Joachim Breitner
Joachim Breitner

Reputation: 25762

Set baseline of flexbox elements

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?

Upvotes: 0

Views: 3774

Answers (2)

Abhitalks
Abhitalks

Reputation: 28397

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

.

Upvotes: 0

Sebastien
Sebastien

Reputation: 1102

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;
}

Upvotes: 2

Related Questions