I seem to be observing some confusing behavior with flexbox, specifically when attempting to use align-self: baseline
. The basic issue is that it simply doesn’t work; the following snippet demonstrates the problem:
.flex-form {
display: flex;
}
.flex-form label {
align-self: baseline;
}
input[type=text] {
border: 1px solid black;
font-size: 16px;
margin: 0 10px;
padding: 5px;
}
button {
background-color: white;
border: 1px solid black;
margin: 0;
}
<form class="flex-form">
<label>Label: </label>
<input type="text" placeholder=" " />
<button type="submit">Submit</button>
</form>
Here’s a screenshot of what the output looks like:
As you can see, the label’s baseline is not aligned with the other form elements, despite having align-self: baseline
set. If I use align-items: baseline
on the parent container, however, I get a different result:
.flex-form {
display: flex;
align-items: baseline;
}
input[type=text] {
border: 1px solid black;
font-size: 16px;
margin: 0 10px;
padding: 5px;
}
button {
align-self: stretch;
background-color: white;
border: 1px solid black;
margin: 0;
}
<form class="flex-form">
<label>Label: </label>
<input type="text" placeholder=" " />
<button type="submit">Submit</button>
</form>
Is this correct behavior according to the spec, or is it a bug? If so, why? Is there a workaround? For reference, I’ve tested on Chrome 54, Safari 9.1.2, and Firefox 50 on macOS 10.11.6, and they all seem to exhibit the same results.
If you want baseline alignment for all items, apply align-self: baseline
to each or, more simply, set align-items: baseline
on the container.
An initial setting of a flex container is align-items: stretch
.
This means that all flex items will expand the full cross-axis length of the container.
That's what's happening in your layout. EXCEPT, you've overridden align-items: stretch
on one flex item (label
), by applying align-self: baseline
.
While the other flex items stretch, the label has a baseline
instruction – but no point of reference.
From the spec:
8.3. Cross-axis Alignment: the
align-items
andalign-self
properties
baseline
If the flex item’s inline axis is the same as the cross axis, this value is identical to
flex-start
.Otherwise, it participates in baseline alignment: all participating flex items on the line are aligned such that their baselines align, and the item with the largest distance between its baseline and its cross-start margin edge is placed flush against the cross-start edge of the line.
Okay, let's break this down:
The first line doesn't apply. In this case, the flex item's inline axis is the same as the main axis (horizontal), not the cross axis (vertical), so baseline
doesn't resolve to flex-start
.
"...all participating flex items on the line are aligned such that their baselines align..." Well, there's only one item with baseline alignment. There is no other baseline for reference. Apparently, the browser falls back to flex-start
in such a scenario (but I haven't seen an official reference for this behavior).
The rest of the spec language is not relevant to this question, but is covered in detail in this related post: What's the difference between flex-start and baseline?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With