Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Control width of flex items arranged vertically in a flex container

I'm trying to achieve the effect where the boxes labeled "HALF", take up only 50% of the width (aka they share the first row evenly).

The base requirement is that they remain in a single container. Is this possible to achieve using flexbox?

I've tried playing around with flex-grow, flex-shrink, and flex-basis but I'm afraid I'm not understanding how to make it work, or if it's even possible, given the single container requirement.

Consider this fiddle: http://jsfiddle.net/GyXxT/270/

div {
  border: 1px solid;
}

.container {
  width: 400px;
  display: flex;
  flex-direction: column;
}
.child {
  
  height: 200px;
}
.child.half {
  flex: 1 1 10em;
  color: green;
}

.child:not(.half) {

  flex-shrink: 2;
  flex-basis: 50%;
  color: purple; 
}
<div class="container">
  <div class="child half">
    HALF
  </div>
  
  <div class="child half">
    HALF
  </div>
  
   <div class="child">
    FULL
  </div>
   <div class="child">
    FULL
  </div>
  <div class="child">
    FULL
  </div>
   <div class="child">
    FULL
  </div>
</div>
like image 239
parliament Avatar asked Dec 19 '16 17:12

parliament


People also ask

How do you adjust flex width?

You have to add a wrapper around the right column, and then only specify flex-basis on the . menu element. Now when the menu is hidden, the right column expands the full amount. Great, that works as expected!

Which properties can control the size of Flex items?

The flex-shrink property. The flex-shrink property specifies the flex shrink factor, which determines how much the flex item will shrink relative to the rest of the flex items in the flex container when negative free space is distributed.

Which flexbox property aligns items vertically?

align-items and justify-content are the important properties to absolutely center text horizontally and vertically. Horizontally centering is managed by the justify-content property and vertical centering by align-items. Not only can align-items be used to center text it vertically centers any child element.


2 Answers

Instead of flex-direction: column, you can try a wrapping flexbox using flex-wrap: wrap; and you can set:

  1. flex-basis: 50% for the half width divs

  2. flex-basis: 100% for the full width divs

See that I have thrown in box-sizing: border-box to adjust for the widths when using flex-basis.

See demo below:

div {
  border: 1px solid;
  box-sizing: border-box;
}
.container {
  width: 400px;
  display: flex;
  flex-wrap: wrap;
}
.child {
  height: 200px;
}
.child.half {
  flex-basis: 50%;
  color: green;
}
.child:not(.half) {
  flex-basis: 100%;
  color: purple;
}
<div class="container">
  <div class="child half">
    HALF
  </div>

  <div class="child half">
    HALF
  </div>

  <div class="child">
    FULL
  </div>
  <div class="child">
    FULL
  </div>
  <div class="child">
    FULL
  </div>
  <div class="child">
    FULL
  </div>
</div>
like image 176
kukkuz Avatar answered Sep 23 '22 01:09

kukkuz


The flex sizing properties -- flex-grow, flex-shrink, flex-basis and flex -- work only along the main axis of the flex container.

Since your container is flex-direction: column, the main axis is vertical, and these properties are controlling height, not width.

For sizing flex items horizontally in a column-direction container you'll need the width property.

(Here's a more detailed explanation: What are the differences between flex-basis and width?)

To achieve your layout with a single container, see another answer to this question.

If you want to stay in column-direction, you'll need to wrap the .half elements in their own container.

.container {
  display: flex;
  flex-direction: column;
  width: 400px;
}
.container > div:first-child {
  display: flex;
}
.child.half {
  flex: 1 1 10em;
  color: green;
  width: 50%;
}
.child {
  height: 200px;
  width: 100%;
  border: 1px solid;
}
* {
  box-sizing: border-box;
}
<div class="container">
  <div><!-- nested flex container for half elements -->
    <div class="child half">HALF</div>
    <div class="child half">HALF</div>
  </div>
  <div class="child">FULL</div>
  <div class="child">FULL</div>
  <div class="child">FULL</div>
  <div class="child">FULL</div>
</div>
like image 25
Michael Benjamin Avatar answered Sep 23 '22 01:09

Michael Benjamin