Why are text buttons pushed down?
So play a little here. By default, text and inline elements are vertically aligned along the baseline. The baseline is the value determined by the line-height element of the element, although the element without line-height will determine the "reasonable" value [1] - in the case of an empty element, it will be 0. However, when you add text, then the element receives line-height and moves down this amount. [2]
A simple solution is to force inputs with the same alignment, text or not, using vertical-align: top .
Why is there a space between the buttons?
The inline elements (and inline-block , such as your inputs) naturally align side by side, however they behave like text [3] . Just as if you put a line break between two letters in your HTML, a line break between inline elements will add one space between them.
Hypothetically, if you entered all your inputs on one line (without spaces), this would solve your problem:
<input type="button" value="these" /><input type="button" value="are" /><input type="button" value="touching" /> <br><br> <input type="button" value="these" /> <input type="button" value="are" /> <input type="button" value="not" />
Although I do not suggest this method - it is just for demonstration purposes.
So what is the solution?
Well, you have several options. Choose the one that you think will work best for you.
Solution 1: Wrap the inputs in the container and apply font-size: 0 . Whitespace will still be present, but font-size: 0 ensures that they are not visible.
input { background-color: #e7e7e7; border: solid; border-width: 1px; text-align: center; height: 50px; width: 50px; padding: 0px; margin: 0px; vertical-align: top; font-size: 12px; } .container { font-size: 0; }
<div class="container"> <input type="button" value="foo"> <input type="button" value=""> <input type="button" value=""> <br/> <input type="button" value=""> <input type="button" value=""> <input type="button" value=""> <br/> <input type="button" value=""> <input type="button" value=""> <input type="button" value=""> </div>
Solution 2: Bypass the triviality of inline elements and use display: block with a float .
input { background-color: #e7e7e7; border: solid; border-width: 1px; text-align: center; height: 50px; width: 50px; padding: 0px; margin: 0px; font-size: 12px; float: left; display: block; } .row {display: block;} .row::after { display: block; content: ''; clear: both; }
<div class="row"> <input type="button" value="foo"> <input type="button" value=""> <input type="button" value=""> </div> <div class="row"> <input type="button" value=""> <input type="button" value=""> <input type="button" value=""> </div> <div class="row"> <input type="button" value=""> <input type="button" value=""> <input type="button" value=""> </div>
Solution 3: Use a more modern approach like flexbox .
input { background-color: #e7e7e7; border: solid; border-width: 1px; text-align: center; height: 50px; width: 50px; padding: 0px; margin: 0px; vertical-align: top; font-size: 12px; } .container { display: flex; flex-wrap: wrap; width: 150px; }
<div class="container"> <input type="button" value="foo"> <input type="button" value=""> <input type="button" value=""> <input type="button" value=""> <input type="button" value=""> <input type="button" value=""> <input type="button" value=""> <input type="button" value=""> <input type="button" value=""> </div>
Sources
1: " normal: Tells user agents to set the calculated value to a" reasonable "value"
2: "For embedded unused items, the field used for alignment is a field whose height is" row height ".
3: "Line-level items generate line-level boxes, which are blocks that participate in the formatting context of the format."