CSS flexbox giving unexpected output

Viewed 55

I have below markup for testing flexbox:

<html>
    <head>
        <style>
            .parent{
                display: flex;
                flex-direction: column;
            }
           .parent>div>button{
               display: flex;
           }
           .parent>div:nth-child(2){
               display: flex;
           }
        </style>
    </head>
    <body>
        <div class="parent">
            <div class="div1"><button>butt1</button><button>butt7</button></div>
            <div class="div2"><button>butt2</button><button>butt3</button><button>butt4</button>
                <button>butt5</button><button>butt6</button></div>
        </div>
    </body>
</html>

Its output is given below:

enter image description here

What I don't understand is that even if we haven't given any flex-direction: column to the div1 i.e., we haven't written:

.parent>div>button{
   display: flex;
   flex-direction: column;
  }

even then butt1 and butt7 are aligned in column. Why they are not aligned in row?? Is it the case that child div inherits the value of flex-direction of parent? I have read that default value of flex-direction is row. So, with that logic as well, they should have been aligned row-wise, not column-wise.

Please help me to find the reason of above behaviour.

Thank You.

3 Answers

The problem is in this:

.parent>div>button{
  display: flex;
}

You overwritten default style of button, which is display: inline-block. display: flex works for children not for element itself, so your buttons behave like normal div (display: block). If you want to use flex in your way even if it's inappropriate change it to display: inline-flex.

More precise information directly from specification:

flex - This value causes an element to generate a flex container box that is block-level when placed in flow layout.

inline-flex - This value causes an element to generate a flex container box that is inline-level when placed in flow layout.

@IMPROVEMENT

You have a lot of code that is not needed.

You can achieve same result by:

.parent > div {
  display: flex;
}
<div class="parent">
    <div>
        <button>butt1</button>
        <button>butt7</button>
    </div>
    <div>
        <button>butt2</button>
        <button>butt3</button>
        <button>butt4</button>
        <button>butt5</button>
        <button>butt6</button>
    </div>
</div>

If you want to apply a flex to the div1 do it like this:

.parent>.div1{
    display: flex;
}

See here, I've added a background color for you to see what's going on:

.parent {
  background: red;
  display: flex;
  flex-direction: column;
}

.parent>.div1 {
  background: blue;
  margin: 10px;
  display: flex;
}

.parent>div:nth-child(2) {
  background: green;
  margin: 10px;
  display: flex;
}
<div class="parent">
  <div class="div1">
    <button>butt1</button><button>butt7</button>
  </div>
  <div class="div2">
    <button>butt2</button><button>butt3</button><button>butt4</button>
    <button>butt5</button><button>butt6</button>
  </div>
</div>

this line of CSS is the issue:


.parent>div>button{
  display: flex;
}
      

You are telling css CSS using > that rules will be applied to elements which are direct children of the .parent -> div -> button element.

.parent {
  display: flex;
  flex-direction: column;
}


.parent>div:nth-child(2) {
  display: flex;
}
<div class="parent">
  <div class="div1"><button>butt1</button><button>butt7</button></div>
  <div class="div2"><button>butt2</button><button>butt3</button><button>butt4</button>
    <button>butt5</button><button>butt6</button></div>
</div>

Related