12

Currently my "flex" items look like this (vertically aligned: top)...

 _____________________________________
   1

 _____________________________________
   2

 _____________________________________
   3

 _____________________________________
   4

 _____________________________________



My Goal is to make them look like this (vertically aligned: middle)...

 _____________________________________

   1
 _____________________________________

   2
 _____________________________________

   3
 _____________________________________

   4
 _____________________________________


My requirements:

  • The flex container must stay at 100% in height
  • The flex items must stay 25% in height (equaling 100%, which is its default anyway).
  • The flex items must be vertically centered.
  • This must be responsive and be smart enough to stay in the middle per device (so no line-height/padding)

http://jsfiddle.net/oneeezy/p4XtA/

HTML

<!-- Flex Box -->
<section>

    <!-- Flex Items -->
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>

</section>

CSS

/* Flex Box */
section { padding: 1em; background: black; display: flex; flex-flow: column; height: 100%; justify-content: space-around; }

/* Flex Items */
div { border-top: 1px solid #ccc; background: #f2f2f2; height: 25%; }
div:first-child { border-top: 1px solid transparent; }
div:hover { background: white; }
alex
  • 479,566
  • 201
  • 878
  • 984
Oneezy
  • 4,881
  • 7
  • 44
  • 73

4 Answers4

9

To vertical align content of flexbox child, you will need to apply some other techniques.

I believe there will be content there , wrapped in tag, You can then again use flex and set child in margin:auto; DEMO


CSS updated :

/* Flex Box */
 section {
    padding: 1em;
    background: black;
    display: flex;
    flex-flow: column;
    height: 100%;
    justify-content: space-around;
}
/* Flex Items */
 div {
    border-top: 1px solid #ccc;
    background: #f2f2f2;
    height: 25%;
    display:flex;/* be a flexbox too */
}
div:first-child {
    border-top: 1px solid transparent;
}
div:hover {
    background: white;
}
p { /* or any child of flex box used */
    margin:auto;/* here center/middle align */
}

HTML structure :

<!-- Flex Box -->
<section>
    <!-- Flex Items , Flex Box themselves -->
    <div>
        <p style="width:100%;/* to fill entire width*/">1</p> <!-- Flex Items  -->
    </div>
    <div>
        <p>2</p><!-- Flex Items  -->
    </div>
    <div>
        <p>3</p><!-- Flex Items  -->
    </div>
    <div>
        <p>4</p><!-- Flex Items  -->
    </div>
</section>

Maybe a fallback with display:table , can be usefull : DEMO 2

/* fall back IE8 ie */
html, body, section {
    -moz-box-sizing:border-box;
    box-sizing:border-box;
    height:100%;
    width:100%;
}
section {
    display:table;
}
section > div {
    display:table-cell;
    vertical-align:middle;
}

/* Flex Box */
 section {
    padding: 1em;
    background: black;
    display: flex;
    flex-flow: column;
    height: 100%;
    justify-content: space-around;
}
/* Flex Items */
 section > div {
    border-top: 1px solid #ccc;
    background: #f2f2f2;
    height: 25%;
    display:flex;
}
section > div:first-child {
    border-top: 1px solid transparent;
}
section > div:hover {
    background: white;
}
p {
    margin:auto;
}
Angel Politis
  • 10,955
  • 14
  • 48
  • 66
G-Cyrillus
  • 101,410
  • 14
  • 105
  • 129
  • @MrRioku You are Welcome. flex is very nice, it still needs falbacks. here display:table/table-cell would do for a start in older browser http://jsfiddle.net/p4XtA/5/ – G-Cyrillus May 03 '14 at 10:05
  • yes, i agree. I was actually thinking about attempting to use my grid system to put in place for a fallback but come to think of it tables (though it kills me to say this) would be a perfect fallback solution for the flexbox. Excellent work my friend. – Oneezy May 03 '14 at 10:11
  • seems you can also remove height: 25% from section > div and replace with flex: 1; and that will divide them up evenly. – Oneezy May 03 '14 at 10:25
  • exactly :) this the way :) – G-Cyrillus May 03 '14 at 10:27
8

Perhaps I'm misunderstanding, but can't you just do:

HTML (Slim)

.container
  .item 1
  .item 2
  .item 3
  .item 4

CSS

.container {
  display:flex;
  flex-direction: column;
  height: 100vh;
}
.item {
  flex-grow: 1;
  display:flex; 
  align-items:center;
  border-bottom:2px solid #e8e288;
}

Here's a Codepen

skube
  • 5,867
  • 9
  • 53
  • 77
3

Your problem is not really related to the so-called flex-box, in fact what you want to align is the content of the div (not the div), so just use some trick to align it normarlly. Here is one of the tricks:

div:before {
  content:'';
  height:100%;
  display:inline-block;
  vertical-align:middle;
}

Demo.

King King
  • 61,710
  • 16
  • 105
  • 130
  • Tricky! But still a bit of a hack- I'm not complaining, i think it's brilliant.. but I'd imagine Flex Box would have something to control this sort of thing? – Oneezy May 03 '14 at 09:46
  • 2
    It is not a hack, it is CSS :) For flexox child, just use margin:auto; – G-Cyrillus May 03 '14 at 09:46
  • touche` haha.... but seriously though. The makers of flex don't have something for this? I've been trying to use "the flex methods" for a few days now and have gotten close but no cigar – Oneezy May 03 '14 at 09:49
  • 1
    @MrRioku of course, it can just control the **flex item** but not the **inner content of the flex item**. – King King May 03 '14 at 09:50
1

This is the Flex-way of solving your problem:

HTML

<div style="height:300px;"> <!-- Just to test/change the height of <section> element -->
<!-- Flex Box -->
<section>
    <!-- Flex Items -->
    <div>1</div>
    <div>2</div>
    <div>3</div>
    <div>4</div>

</section>
</div>

CSS

/* Flex Box */
section {
    padding: 1em;
    background: black;
    display: flex;
    flex-flow: column;
    height:100%;
    justify-content: space-around;
}

/* Flex Items */
/* Child selector(>) is used to select <div> elements inside <section> element*/
section > div {
    border-top: 1px solid #ccc;
    background: #f2f2f2;
    height: 25%;

    /* Added code */
    display: flex;       /* Gives inner div flex display */
    align-items: center; /* Centers the div in the cross axis */
    /**************/
}
section > div:first-child {
    border-top: 1px solid transparent;
}
section > div:hover {
    background: white;
}
Barun
  • 4,245
  • 4
  • 23
  • 29