Vertically-aligned inline-block element not perfectly centered within container - html

I'm trying to use vertical-align: middle to vertically center an inline-block element within some text.
p {
background: red;
line-height: 20px;
display: block;
}
span {
height: 18px;
width: 18px;
display: inline-block;
background: lightblue;
vertical-align: middle;
}
<p>
<span></span>
<-- Not perfectly aligned
</p>
Notice that the element isn't perfectly centered... why is this? Is this a browser off-by-one issue? It repros on WebKit browsers (Chrome, Safari).

vertical-align: middle; was never meant to center the element. Here is a more trivial example to better see:
p {
background:
linear-gradient(yellow,yellow) center/100% 1px no-repeat, /* the center */
red;
line-height: 80px;
font-size:80px;
display: block;
}
span {
height: 18px;
width: 18px;
display: inline-block;
background: lightblue;
vertical-align: middle;
}
<p>
<span></span>
<-- Not aligned
</p>
Aligns the middle of the element with the baseline plus half the x-height of the parent ref
Related question for more details:
How to understand the difference between vertical-align: -0.125em and vertical-align: middle?
Vertical align not working on inline-block
Vertical-align aligns everything else except self
https://stackoverflow.com/a/54190413/8620333

Your code has comments and text is not in span.
Try this:
<p>
<span>Not perfectly aligned</span>
</p>
p {
background: red;
}
span {
display: inline-block;
background: lightblue;
vertical-align: top;
}

Related

Make text wrap when it meets sibling span

Basically, I have two span elements: one pulled left, the second pulled right.
The one on the left is bigger, the one on the right is supposed to just show a number.
What I am trying to achieve is - while resizing the window, make the left span line break when it meets the right span and center the right span vertically when it happens (since the container div will probably gain some additional height). Any ideas?
Here is the code: http://www.jsfiddle.net/1db4trxo/5/
.pricing {
width: 100%;
background: #333;
color: #fff;
overflow: hidden;
}
.left {
float: left;
margin-left: 5px;
}
.right {
float: right;
margin-right: 5px;
color: #f6c42b;
}
<div class="pricing">
<span class="left"> Wow, there's kinda lot of text here </span>
<span class="right"> Just a price </span>
</div>
Flexbox can do this, and you don't need floats. In fact, floats are ignored in a flex container.
Revised Fiddle
.pricing {
display: flex; /* establish flex container */
justify-content: space-between; /* align children at opposite ends */
background: #333;
color: #fff;
}
.left {
margin-left: 5px;
}
.right {
white-space: nowrap; /* prevent text from wrapping */
align-self: center; /* center element vertically */
margin-right: 5px;
color: #f6c42b;
}
<div class="pricing">
<span class="left"> Wow, there's kinda lot of text here </span>
<span class="right"> Just a price </span>
</div>
You can do it with CSS table with browser support of IE8+.
Set the container as display: table; two columns inside as display: table-cell; vertical-align: middle; and text-align: right; white-space: nowrap; on the right column.
Open the jsFiddle, resize the result panel and see.
.pricing {
display: table;
width: 100%;
background: #333;
color: #fff;
}
.left, .right {
display: table-cell;
vertical-align: middle;
padding: 0 5px;
}
.right {
color: #f6c42b;
text-align: right;
white-space: nowrap;
}
<div class="pricing">
<span class="left"> Wow, there's kinda lot of text here </span>
<span class="right"> Just a price </span>
</div>
You should set a width of both inner divs
like this
.left
{
width: 75%;
}
.right
{
width: 25%;
}
it's work for me.

Vertically aligned item using line-height is slightly off middle

In this style of using line-height and inline-block, why is the green item a few pixels below the middle? Shouldn't there be exactly 15px above and below?
.container{
height: 45px;
line-height: 45px;
background-color: red;
display: inline-block
}
.item{
height: 15px;
width: 15px;
background-color: green;
vertical-align: middle;
display: inline-block
}
<div class="container">
<div class="item">
</div>
</div>
I know there are other ways of vertically aligning items (including JS, absolute positions, and many more). I'm not trying to solve the general "how to vertically align a div".
The culprit here is not so much the line-height, but rather the vertical-align: middle. It tries to align your box with the text that may hypothetically be inside the parent box. Where the inner box ends up depends on the font-size of that text. You can push the box further down by increasing the font-size of its parent:
.container{
height: 45px;
width: 100%;
line-height: 45px;
font-size: 45px;
background-color: red;
display: inline-block
}
.item{
height: 15px;
width: 40px;
background-color: green;
vertical-align: middle;
display: inline-block;
}
<div class="container">
job
<div class="item">
</div>
</div>
As you can see, the text is closer to the bottom of its container than to the top (the "j" overflows the container while the "b" does not).
In the same way, you can move the box closer to the center by decreasing the font-size. Since you asked in comments, here's how you get it optimally centered with this method: Set font-size to 0 on the container.
.container{
height: 45px;
width: 100%;
line-height: 45px;
font-size: 0px;
background-color: red;
display: inline-block
}
.item{
height: 15px;
width: 40px;
background-color: green;
vertical-align: middle;
display: inline-block;
}
<div class="container">
job
<div class="item">
</div>
</div>
Changes in your style may help you
.container {
background-color: #ff0000;
display: table-cell;
height: 45px;
vertical-align: middle;
}
.item {
background-color: #008000;
display: table-cell;
height: 15px;
vertical-align: middle;
width: 15px;
}
Please use dividable size to make this work. Also remove vertical align attribue
https://jsfiddle.net/guc6uxc7/
.container{
height: 42px;
line-height: 42px;
background-color: red;
display: inline-block
}
.item{
height: 12px;
width: 12px;
background-color: green;
display: inline-block;
}

Vertically center text in a box without knowing how many lines

This is driving me crazy I just don't understand why this piece of simple css to vertically center an element in a div doesn't work as expected.
this is the html:
<div class="header-a-wrapper" style="
line-height: 48px;
height: 48px;
background: red;
display: block;
text-align: center;
">
<a href="/user/5659186348163072" class="right" style="
background: blue;
line-height: normal;
display: inline-block;
vertical-align: middle;
float: none;
height: 20px;
">medical salamander</a>
</div>
the inner element does not get centered vertically but I really think it should
here is an html with the two elements:
http://alephz.com/test.html
and this is the CRAZY part. here is a jsfiddle with the same html and over there it works! tested on the same chrome/win7!
http://jsfiddle.net/pkrsdqkb/
Very weird, but if you want to solve it, you add to 'a':
position: relative;
top: 50%;
transform: translateY(-50%);
Remove
vertical-align: middle;
float: none;
One option to play nicely with vertical-align: middle is to use display: table and display: table-cell.
The wrapper gets display: table and width: 100%
Wrap the links in a div which will act as a "table cell" with display: table-cell
vertical-align: middle will now work as you expect it to.
Compatibility: display: table is good for IE 8 + and modern browsers everywhere.
Example:
.header-a-wrapper {
background: red;
display: table;
text-align: center;
height: 100px;
width: 100%;
}
.vertical {
display: table-cell;
vertical-align: middle;
}
.right {
background: blue;
display: block;
margin: 2px 0;
}
<div class="header-a-wrapper">
<div class="vertical">
medical salamander
medical salamander
</div>
</div>
Old answer
There is a lot of redundant CSS.
The vertical center is applied through: line-height: 48px.
Leave that on the wrapper and remove all the positioning CSS properties on a.right.
Example:
.header-a-wrapper {
line-height: 48px;
background: red;
display: block;
text-align: center;
}
.right {
background: blue;
}
<div class="header-a-wrapper">
medical salamander
</div>

Vertically align middle for all elements in div

I am coding the header of my webpage.
But I found that the elements(sometimes image, sometimes textfield) inside my div did not align vertically.
I tried to use vertical-align: middle and line-height but fail to do the job.
http://jsfiddle.net/v68jpypz/1/
#free-wifi {
line-height: 28px;
display: inline-block;
margin-right: 50px;
vertical-align: middle;
}
vertical-align: middle only works when the element is marked as a table-cell, so do it like this:
#free-wifi {
display: table-cell;
margin-right: 50px;
vertical-align: middle;
}
See it work here: http://jsfiddle.net/xv6mthv5/1/
http://jsfiddle.net/v68jpypz/7/
.right {
float: right;
display:table;
}
#social-network {
line-height: 1.5em;
display: table-cell;
vertical-align:middle;
}
You can do the same for the left div.

Aligning divs to the top

I'm trying to create a really basic layout with two divs. The idea is to have one div to the left and the other to the right in the same line. However they don't have the same height.
Why is the smaller div aligned to the bottom instead of to the top? Is not that the expected behavior within the page flow?
<body>
<div>
<div class="left debug-green"></div>
<div class="right debug-red"></div>
</div>
</body>
body {
font-size: 0;
}
.left {
width: 50%;
height: 30px;
display: inline-block;
}
.right {
width: 50%;
height: 20px;
display: inline-block;
}
.debug-red {
background-color: rgb(255, 0, 0);
}
.debug-green {
background-color: rgb(0, 255, 0);
}
This is a js fiddle sample:
http://jsfiddle.net/3nAsx/
add to the right div
vertical-align: top;
Most browsers render inline-block element with default vertical-alignment value and that value is: baseline
vertical-align values:
vertical-align: baseline /* keyword values */
vertical-align: sub
vertical-align: super
vertical-align: text-top
vertical-align: text-bottom
vertical-align: middle
vertical-align: top
vertical-align: bottom
vertical-align: 10em /* <length> values */
vertical-align: 4px
vertical-align: 20% /* <percentage> values */
vertical-align: inherit
You can replace the display:inline-block; declarations with float:left;. Since you're specifying the dimensions anyway, you don't need inline-block property. Here's how it looks like after I made the change.
Code
.left {
width: 50%;
height: 30px;
float:left;
}
.right {
width: 50%;
height: 20px;
float:left;
}
vertical-align: top;
Is good option.
But if you just want one div on left and other on right.
Give float: left to left div and float : right to right div
This way is good short coding
<div class="wrap">
<div class="left debug-green"></div>
<div class="right debug-red"></div>
</div>
.wrap div{
width: 50%;
height: 30px;
display: inline-block;
background-color: green;
float:left;
vertical-align:top;
}
.right {
height: 20px !important;
background-color:red !important;
}