CSS vertical-align: baseline with tables, forms and divs - html

I'm trying to build a form that contains inputs, textareas and block elements, each with a label. In order to get a flexible grid, I'm using a table. For a matching vertical alignment of the labels and the inputs/textarea I set vertical-align: baseline; which works fine for inputs and textareas. But not for divs (see this jsFiddle). The label for the div is consequently aligned at the bottom of the cell, but I want it on the top, i.e. the baseline should be on the top.
How can I achieve this without changing the contents of the div or having to differ between labels for inputs/textareas and divs? Is there any way to force an invisible baseline to be at the top of a table cell?
Maybe I'm not approaching the problem from the right side, any insight is appreciated.

Use the code below for your problem:
td, label, textarea {
vertical-align: top;
}

Your div must have at least one character (for example a ).
For textareas, "vertical-align: baseline;" only works for Gecko.
As developer.mozilla.org said,
The HTML specification doesn't define where the baseline of a <textarea> is.
I found a workaround for that, but it changes the HTML.
I set vertical-align: text-top to the textarea, and to fix the gap caused by the height of the border-top and the padding top of the textarea, I set it a negative margin-top. And to avoid having the textarea overlapping all elements above it, I put a div around the textarea with a padding-top to counterbalance the gap.
HTML:
<div class="textarea-wrapper"><textarea id="b">nice vertical alignment</textarea></div>
CSS:
.textarea-wrapper {
display: inline-block;
padding-top: 1px; /* - margin-top of textarea */
}
.textarea-wrapper textarea {
vertical-align: text-top;
margin-top: -1px; /* - (border-top-width + padding-top) */
}
I updated your jsFiddle.

Related

Understand inline-element, vertical-align, line-box and line-height

vertical-align:bottom, means the bottom inline-box matches the bottom of its line-box, so in my case, the inline-box of span2 is the green one, whose line-height is 100px, inherited from its parent. Its line-box is the black one, also has line-height:100px. so they are bottom aligned.
see pic:
I've already learned that:
1.vertical-align works only for inline/inline-block element
2.vertical-align is based on line-height, not the height of its container!
3.in a line-box, its line-height is the line-height of the inline box(in my opinion, its either inline-element or inline-block element) which has the highest line-height. like pic:
Everything works fine on inline-block element, but it seems that there is a problem with inline-element.
explanation:
parent: height:200px, line-height;100px;
div.child:inline-block, vertical-align bottom;
span1: inline, line-height:inherit from parent, which is 100px
span2: inline, line-height:inherit from parent, which is 100px, vertical align: bottom.
To me, the line-box for the code below is like this(you can run the code first):
strange behavior for span2 !!! and it becomes even stranger if I set its vertical-align to text-top or text-bottom
another thing which I found interesting is, if I set display of span to inline block or set the line-height of span to normal (which is 1.16 of its font-size), everything works fine.
can someone explain it? Thanks
div.parent {
width: 300px;
background-color: coral;
/*key-part*/
height: 200px;
line-height: 100px;
}
div.child {
width: 50px;
height: 50px;
background-color: yellow;
/*key-part*/
display: inline-block;
vertical-align: bottom;
line-height: normal;
}
.span1 {
background-color: white;
font-size: 50px;
/*key-part*/
vertical-align: middle;
}
.span2 {
background-color: green;
font-size: 12px;
/*key-part*/
vertical-align: top;
}
<body>
<div class="parent">
<div class="child">inline-block div</div>
<span class="span1">Text1</span>
<span class="span2">Text2</span>
</div>
</body>
Let's try to cover it step by step:
1.vertical-align works only for inline/inline-block element
Vertical-align applies to inline-level elements. That's currently: inline, inline-block, inline-table, inline-flex, inline-grid. Vertical-align is also used, but in a different way, for table cells.
2.vertical-align is based on line-height, not the height of its container!
Except for table cells, correct.
3.in a line-box, its line-height is the line-height of the inline box(in my opinion, its either inline-element or inline-block element) which has the highest line-height.
That's correct for simple cases but not for complex alignment ones. A better approximation goes something like this. Remove all the elements that are vertical-align:top and vertical-align:bottom. Align all the other elements so that their vertical alignment lines are level with one another. Call the box that contains them from the highest top of the aligned elements to the lowest bottom of the aligned elements the proto-line box. The actual height of the line box is then the maximum of the height of the proto-line box and all of the heights of the elements that are aligned top and bottom.
Now the relevant part of the specification for your question is this:
... for inline non-replaced elements, the box used for alignment is the box whose height is the 'line-height' (containing the box's glyphs and the half-leading on each side, see above). For all other elements, the box used for alignment is the margin box.
So for the span2, the green background area is the box's glyphs and above that are each glyph's upper half-leading, a value which is taken from the 100px line-height inherited from the container block element. It's the top of these half-leadings that aligns with the top of the line-box, not the top of the green background area.
On the other hand, the inline-block div aligns to the bottom of the line box, by the bottom of its bottom margin, and not by any half-leading.

large empty space for inline-block div

I am trying to put two divs side by side by using inline-block. For some reason, I am seeing a large empty space at one of the divs.
I have created a pen at http://codepen.io/weima/pen/eKEbD
The problematic div is the one with class .input-area. The empty space is gone if I remove display:inline-block from .input-area css, but then I wont be able to put these two divs side by side.
Is there anyway to solve this without using float?
You could add vertical-align:top to the element in order to fix the alignment issues.
UPDATED EXAMPLE HERE
.input-area {
vertical-align: top;
display: inline-block;
width: 450px;
border: 1px solid green;
}
The default value to the vertical-align property is baseline. If you are curious as to what this does, take a look at this answer.

DIVs wrapping, even with "display: inline-block"

I've got a few divs (multi-column page) with "display: inline-block" set. Shouldn't this prevent them from wrapping? I want them all side by side:
div.LabelColumn
{
display: inline-block;
padding: 10px 0 0 40px;
vertical-align: top;
}
div.DataColumn
{
display: inline-block;
padding: 10px 0 0 5px;
vertical-align: top;
}
To clarify, I want the DIVs side by side – i.e., shown as columns. I want them each to take up as much room as they need. Each of them, using what I want to display, should only take up about 100px, so there is easily enough room to display a few columns side by side. The first column will have a label, the second a bit of data, the third a label, and the fourth a bit of data.
To give a higher level view of the page, I have a div which I am floating left. To its right, I want the multiple columns of data. By the way, this is working in Chrome, but not in IE.
I would like the width to automatically adjust to be as wide as the text in the DIV, if possible.
Remove inline block, use floating, assign width, and padding margin.Here is the demo
Using inline-block does not prevent elements from wrapping. In fact, when applied to div elements it will do the opposite.
use float. for more information: http://css-tricks.com/all-about-floats/
If you want them all side by side, their containing element needs to have enough width to allow so. You can prevent wrapping causing breaks within the elements by applying whitespace: nowrap;, but this may have other effects depending on how you've structured your markup.

Vertical alignment of DIV's using relative positioning and inline-block?

I have a problem aligning DIV's vertically, when the contents within them have different height (although the DIV's themselves have a fixed size).
See HTML example here (with inline CSS)
I want the DIV's to "flow" like text, so I'd like to avoid using position:absolute if possible. I'm using display: inline-block to the DIV's won't collapse.
Add a vertical-align property - it doesn't matter which one, they all do the same thing, since they're the same size. If they're different sizes, use vertical-align: middle:
.collection_box {
vertical-align: middle; /* or top, or bottom, if they're the same size */
}
Float them to the left:
.collection_box {
float: left;
}

How can I make my DIV just the size of the text it encloses

I have this code:
<div id="one">
<div id="two">my text here</div>
</div>
I have styled the div with id=two and put a box around it. The problem is that it doesn't enclose the text but instead expands to the width of the outer DIV. Is there a way I can make it just size to match the text without specifying width?
You can either
#two {
display: inline; /* or 'inline-block' */
}
Or:
#two {
float: left; /* or right */
}
display: inline; stops the div being displayed as a block-level element, causing it to collapse (for want of a better word) to the size of its contents. If you use the alternative display: inline-block then the div retains its ability to have a defined width and height, which may be required for your layout. However it's worth noting that Internet Explorer 6 and 7 only accepts display: inline-block for those elements that are 'naturally inline.'
float has much the same effect; but using float might/will obviously affect the layout of the page, and may need to be cleared by subsequent elements.
display:inline-block;
This way you keep the block behaviour of your div.