Michael
Michael

Reputation: 9402

How to prevent strange element misalignments

I'm trying to lay out some elements in a line such that they all have the same top and bottom vertically.

If I create a button and text input with the same specified size, the button actually has a slight margin at the top and bottom which make it appear smaller than the text input. When I inspect the element in Chrome developer tools, it doesn't show this extra space as part of the actual element!

<button style="height:160px">
    test
    </button>
<input style="height:160px" />

Fiddle

Why is this happening and how do I get rid of the extra space around the button?

Now if I remove the text from the button, suddenly the second element get pushed way down! I see the same thing if I put a space (e.g. &nbsp;) in the input.

<button style="height:160px">
    </button>
<input style="height:160px" />

Fiddle

Again, what's going on here and how do I fix it?

Upvotes: 1

Views: 91

Answers (3)

sol
sol

Reputation: 22939

The other answers explain box-sizing, and how to align the elements with vertical-align.

Another approach to the alignment is to wrap the elements in a flex container. You can also set the height on the container instead of both the elements.

Example:

div * {
  box-sizing: border-box;
}

div {
  display: flex;
  height: 160px;
}
<div>
  <button></button>
  <input>
</div>
<br>
<div>
  <button>Content</button>
  <input>
</div>

Upvotes: 0

Ollin Boer Bohan
Ollin Boer Bohan

Reputation: 2401

First Question:

There isn't any extra space around the button, but there is extra space inside the input tag, in the form of padding, which causes its effective height to exceed 160px.

If you want the total height of the input to be 160px, including padding, set box-sizing: border-box on the input (arguably, this should be the default behavior).

Second Question:

To align the button without any text inside it, set vertical-align: bottom; (or top, or middle) on the button.

For explanation: the default vertical-align value of baseline will try to align the baseline of text inside the element with the text in the parent element, but if there isn't any text inside the element, will instead try to align the bottom margin edge, which means that the bottom of the button ends up around the middle of the input.

Code with Both Fixes:

<button style="height:160px; vertical-align: bottom;">
</button>
<input style="height:160px; box-sizing: border-box;"/>

Upvotes: 2

j08691
j08691

Reputation: 207901

The box model and box-sizing property are the reason for the slight size difference on your first example. It's the way browser's calculate the width and height based on margins, padding, etc.

Set the box-sizing property to border-box and they line up just fine

input {
  box-sizing: border-box;
}
<button style="height:160px">
    test
    </button>
<input style="height:160px" />

As for your second example, it's the vertical align property that comes into play. It affects inline elements and the default is baseline. Set it to something like top or middle and they align as you would expect. Throw in the same box-sizing as the previous example and they become the same height:

input {
  vertical-align: top;
  box-sizing: border-box;
}
<button style="height:160px">
    </button>
<input style="height:160px" />

Upvotes: 3

Related Questions