0

Consider this HTML

<div class="container">
  <div class="element">
    <div class="top">
      <div>A</div>
      <div>B</div>
    </div>
    <hr/>
    <div class="bottom">
      <div>C</div>
    </div>
  </div>
  <div class="element">
    <div class="top">
      <div>A</div>
    </div>
    <hr/>
    <div class="bottom">
      <div>B</div>
      <div>C</div>
    </div>
  </div>
    <div class="element">
    <div class="top">
      <div>A</div>
    </div>
    <hr/>
    <div class="bottom">
      <div>B</div>
    </div>
  </div>
</div>

I want to line the elements up horizontally using flexbox, such that the horizontal rules align. It seems that align-items: baseline would do the right thing – if I could make sure the element divs have their baseline at the horizontal bar.

See this codepen link for something to play around with.

How can I control the baseline of such a block element?

Joachim Breitner
  • 25,395
  • 6
  • 78
  • 139
  • I think it's not possible to control which element IS the baseline. I guess you'll have to separate this in 3 : over line content / line / under line content. – Sebastien Sep 21 '15 at 08:45
  • There is already this separation within the `.element`. Or are you saying that I have to first list all `top`, then all `hr`, and then all `bottom` blocks? That will hardly work well with a multi-line flexbox layout. – Joachim Breitner Sep 21 '15 at 08:47
  • Yes, just wrote a demo, let me post it. – Sebastien Sep 21 '15 at 08:53

2 Answers2

2

You could use multiple stacked flexboxes to achieve this, however HTML gets more complex, but it looks like the only way to pretend you set the baseline yourself.

Demo : https://jsfiddle.net/Paf_Sebastien/tLk1jajo/

The content over the line is in one flexbox with :

.overline {
    align-items: flex-end;
}

The content under the line in another with :

.underline {
    align-items: flex-start;
}
Sebastien
  • 1,014
  • 9
  • 29
  • I’d like to have a closer look, but from my university network, jsfiddle.net seems to regularly timeout. I’ll have a look later! – Joachim Breitner Sep 21 '15 at 09:02
  • Thanks for the codepen link. Unfortunately, this does not quite cut it: If you make it `flex-wrap: wrap;` (which I need in my use case) and it has to wrap lines, things go horribly wrong. – Joachim Breitner Sep 21 '15 at 09:09
  • Indeed... Don't have other ideas except : if you set fixed width in your use case as you do in the demo, you may use `inline-block` instead (but I guess flexbox is chosen on purpose). – Sebastien Sep 21 '15 at 09:14
0

I want to line the elements up horizontally using flexbox, such that the horizontal rules align. It seems that align-items: baseline would do the right thing

align-items: baseline is not going to help you here, because you want to align different elements with respect to another element (the hr as opposed to aligning same elements based on the text baseline).

If you can work with fixed heights of your .elements, then without changing your markup, you could do a nested flex and equalize your .top and .bottom, like this:

.top, .bottom { 
    height: 49%; 
    display: flex; flex-direction: column;
    align-items: center;
}
.top > div, .bottom > div { flex: 0 0 auto; }

And then, to align the .top one to the bottom (i.e. close to the hr), you would do a margin-top: auto, like this:

.top > div { margin-top: auto; }

This will also play along nicely with your flex-wrap: wrap. Try changing the width of the fiddle pane, or window size in the examples below.

Complete Example Snippet:

* { box-sizing: border-box; padding: 0; margin: 0; }
.container {
    height: 320px; border: 1px solid #ddd;
    display: flex; flex-wrap: wrap;
    align-items: center;
}
.element {
    flex: 1 1 auto;
    height: 120px; width: 200px;
    padding: 0.5em;
}
.top, .bottom { 
    height: 49%; 
    display: flex; flex-direction: column;
    align-items: center;
}
.top > div, .bottom > div { flex: 0 0 auto; }
.top > div { margin-top: auto; }
<div class="container">
  <div class="element">
    <div class="top">
      <div>A</div>
      <div>B</div>
    </div>
    <hr/>
    <div class="bottom">
      <div>C</div>
    </div>
  </div>
  <div class="element">
    <div class="top">
      <div>A</div>
    </div>
    <hr/>
    <div class="bottom">
      <div>B</div>
      <div>C</div>
    </div>
  </div>
    <div class="element">
    <div class="top">
      <div>A</div>
    </div>
    <hr/>
    <div class="bottom">
      <div>B</div>
    </div>
  </div>
</div>

Fiddle: http://jsfiddle.net/abhitalks/vym76nyn/

Codepen: http://codepen.io/anon/pen/ZbOyzE

.

Abhitalks
  • 27,721
  • 5
  • 58
  • 81