9

I'm having some trouble with a flexbox layout. What I'm trying to achieve is how the image below is positioned. However, using margin and padding I can move the elements to the correct place without something drastic happening.

I am probably approaching this incorrectly. If someone could give me some advice and an explanation on how to do this correctly that would be great.

Wireframe

enter image description here

How it is right now

enter image description here

HTML

<div style="background: grey;">
    <div class="parent-container" style="flex-direction: column; align-items: center; margin: 10px;">
        <div class="aelia-text child33">
            The first of it's kind, to<br/>
            create a better customer<br/>
            journey with reduced<br/>
            collection waiting time and<br/>
            a special moment that makes<br/>
            even the most jet-lagged<br/>
            shopper smile.
        </div>
        <div class="child33">
            <div class="img-wrapper" ng-style="{'background-image':'url(/assets/Aelia_Robot_highres006.jpg)'}"></div>
        </div>
        <div class="child33">
            <div class="img-wrapper" ng-style="{'background-image':'url(/assets/AELIA_IMAGE.jpg)'}"></div>
        </div>
    </div>
</div>

CSS

.aelia-text {
    background: white;
    color: black;
    font-size: 1.5vw;
    font-family: portland-medium-font; 
    -ms-flex-pack: center; 
    justify-content: center;
    -ms-flex-align: center;
    align-items: center;
    display: -ms-flexbox;
    display: flex;
}

.child33 {
    position: relative;
    -ms-flex-positive: 1;
    flex-grow: 1;
    height: 50%;
    width: 33.3%;
    max-width: calc(100% * (1/3));
    margin: 0;
    position: relative;
    -ms-flex-flow: nowrap row;
    -o-flex-flow: nowrap row;
    flex-flow: nowrap row;
    border: 0;
    outline: 0;
}

.parent-container {
    display: -ms-flexbox;
    display: flex;
    font-size: 0;
    margin: 0;
    padding: 0;
    border: 0;
    -ms-flex-wrap: wrap;
    flex-wrap: wrap;
    height: 92vh;
    width: 100vw;
}

.img-wrapper {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background-size: cover;
}
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Troy
  • 211
  • 1
  • 2
  • 15

2 Answers2

22

Your flex container (.parent-container) has three children (flex items).

Each child has a class child33.

The flex container is set to flex-direction: column and flex-wrap: wrap, meaning the items will align vertically and wrap when necessary, forming new columns.

.parent-container {
    display: -ms-flexbox;
    display: flex;
    font-size: 0;
    margin: 0;
    padding: 0;
    border: 0;
    -ms-flex-wrap: wrap;
    flex-wrap: wrap;
    height: 92vh;
    width: 100vw;
}

<div class="parent-container" style="flex-direction: column; align-items: center; ...">

So in your image you have a two-column layout: two items in the first column, and the third item wraps to form the second.

The reason both columns are spread out is that an initial setting of a flex container is align-content: stretch. This means that multiple lines in the cross axis will be distributed evenly across the length of the container.

You already have align-items: center in your code. But this only works on single line flex containers. When there are multiple lines in the cross-axis, you need to use align-content.

So, override the default setting by adding align-content: center to your container.

body { margin: 0; }

.parent-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    flex-wrap: wrap;
    height: 92vh;
    width: 100vw;
    align-content: center;  /* NEW */
}

.aelia-text {
    display: flex;
    justify-content: center;
    align-items: center;
    background: white;
    color: black;
    font-size: 1.5vw;
    font-family: portland-medium-font;
}

.child33 {
    flex-grow: 1;
    height: 50%;
    width: 33.3%;
    max-width: calc(100% * (1/3));
    margin: 0;
    position: relative;
}

.img-wrapper {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    /* added image for demo; original code had relative URI */
    background-image: url(http://i.imgur.com/60PVLis.png);
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
}
<div style="background: grey;">
    <div class="parent-container">
        <div class="aelia-text child33">
            The first of it's kind, to
            <br/> create a better customer
            <br/> journey with reduced
            <br/> collection waiting time and
            <br/> a special moment that makes
            <br/> even the most jet-lagged
            <br/> shopper smile.
        </div>
        <div class="child33">
            <div class="img-wrapper"></div>
        </div>
        <div class="child33">
            <div class="img-wrapper"></div>
        </div>
    </div>
</div>

jsFiddle

From the spec:

6. Flex Lines

In a multi-line flex container (even one with only a single line), the cross size of each line is the minimum size necessary to contain the flex items on the line (after alignment due to align-self), and the lines are aligned within the flex container with the align-content property. In a single-line flex container, the cross size of the line is the cross size of the flex container, and align-content has no effect. The main size of a line is always the same as the main size of the flex container’s content box.

8.4. Packing Flex Lines: the align-content property

The align-content property aligns a flex container’s lines within the flex container when there is extra space in the cross-axis, similar to how justify-content aligns individual items within the main-axis. Note, this property has no effect on a single-line flex container.

(emphasis added)

Community
  • 1
  • 1
Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 1
    Appreciate the Fiddle and explanation on why it wasn't working as I didn't realise this before. As you stated adding align-content: center; did indeed work as intended and fix my issue. I know you're not meant to say thanks on SO :D but ya know... – Troy Jul 11 '16 at 10:03
  • @Michael_B You're a lifesaver! – inafalcao Aug 16 '17 at 20:39
-2

If I understand correctly, you want to center both columns in the middle. Since .parent-container has flex-direction: column; in your inline style, you would need justify-content: center;.

If you look in the section 'Basics & Terminologiy' in CSS-Tricks, you'll see that justify-content plays with the main axis of the flexbox and align-items plays with the cross axis. So when your flexbox direction is in columns and you want to horizontally center you columns, you need to align them in the main axis or with the justify-content attribute.

But if you want to make your flexbox cross-browser you would need the following:

-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;