CSS: unexpected vertical position of inline-block elements
The default value for vertical-align
in CSS is baseline
. This means that the baseline of the last text in the first section ("1B") is lined up with the baseline of the last text in the second section ("5") - and also with the baseline of any surrounding text if you had any.
If you add an explicit vertical-align: bottom;
to your .section
CSS then that will use the bottom of the inline-block as the alignment guide, giving the result you want.
See http://www.brunildo.org/test/inline-block.html for a demonstration of how vertical-align
applies to inline blocks
Inline-block elements have different vertical alignment
jsBin demo
Just put your <i>
inside the <a>
. The benefit? your image will be linkable.
<div class="phone-support">
<a href="#">We'll call you <i class="icon"></i> </a>
</div>
Than set a vertical-align:top;
to set your image at the top of the <a>
parent.
.phone-support i.icon {
display : inline-block;
vertical-align: top;
height : 30px;
width : 30px;
background : url(your url here);
margin-left : 10px; /*add some space*/
}
Unexpected margin after inline-block element
In addition to removing the space between inline elements, you need to change the value of the vertical-align
property on the .links
element. It's worth pointing out that the default value is baseline
. When it is set to baseline
on an inline element, there is a reserved space for letters such as f, j, p and q (these letters hang lower (or are taller) than other letters, thus the reserved space).
Updated Example
.links {
display: inline-block;
border: 1px solid black;
width: 100%;
font-size: 0;
white-space: nowrap;
overflow-x: auto;
vertical-align: bottom; /* Added.. */
}
.links a {
box-sizing: border-box; /* Added.. */
}
It's also worth pointing out that the widths of the a
elements didn't add up to 100%
(since the border isn't included in the element's width calculations). In order to remove the scollbar, add box-sizing: border-box
to the anchor elements.
As a side note, since you're setting a width of 100%
on the parent .links
element, it really doesn't need to have a display
of inline-block
. You should make it a block
level element (by omitting display: inline-block
, since it's already a div
and block
level by default). In doing so, you actually don't need to add vertical-align: bottom
anymore, since block
level elements don't respect this property.
Example Here
.links {
border: 1px solid black;
font-size: 0;
white-space: nowrap;
overflow-x: auto;
}
.links a {
box-sizing: border-box;
}
Why is this inline-block element pushed downward?
Basically you have added more clutter in your code which is creating more confusion so first I try to remove clutter which hinders understanding the real issue.
First of all we have to establish that what's the real question?
Its that why "inline-block
" element is pushed downward.
Now we start to understand it and remove the clutter first.
1 -
Why not give all three divs same border width?
Let's give it.
2 - Does floating element has any connection with inline-block element being pushed downward?
No, it has nothing to do with it.
So, we have removed that div altogether. And you are witnessing same behavior of inline-block element being pushed downward.
Here comes the turn of some literature to grasp the idea of line boxes and how they are lined in the same line esp read last paragraph carefully because there lies the answer of your question.
The baseline of an 'inline-block' is the baseline of its last line box in the normal flow, unless it has either no in-flow line boxes or if its 'overflow' property has a computed value other than 'visible', in which case the baseline is the bottom margin edge.
If you are not sure about baseline then here is brief explanation in simple words.
All characters except 'gjpqy' are written on the baseline you can think of baseline as if you draw a simple horizontal line same as underlining right below these "random characters" then it will be the baseline but now if you write any of 'gjpqy' character(s) on the same line then lower part of these characters would fall below the line.
So, we can say that all characters except 'gjpqy' are written completely above the baseline while some part of these characters are written below the baseline.
3 - Why not check where is the baseline of our line?
I have added few characters which show the baseline of our line.
4 - Why not add some characters in our divs too to find their baselines in the div?
Here, some characters added in divs to clarify baseline.
Now when you understand about baseline, read the following simplified version about baseline of inline-blocks.
i) If inline-block in question has its overflow property set to visible (which is by default so no need to set though).
Then its baseline would be the baseline of the containing block of the line.
ii) If inline-block in question has its overflow property set to OTHER THAN visible.
Then its bottom margin would be on the baseline of the line of containing box.
- First point in detail
Now look at this again to clarify your concept that what's happening with green div.
If yet any confusion then here is added more characters close to green div to establish the baseline of the containing block and green div baseline is aligned.
Well, I am now claiming that they have same baseline? RIGHT?
5 - Then why not overlap them and see if they are fit right one on another?
So, I bring third div -left: 35px; to check if they have same baseline now?
Now, we have got our first point proved.
- Second point in detail
Well, after explanation of first point second point is easily digestible and you see that first div which has overflow property set to other than visible (hidden) has its bottom margin on the base line of the line.
Now, you can do couple of experiments to further illustrate it.
- Set first div overflow:visible (or remove it altogether).
- Set second div overflow: other than visible.
- Set both divs overflow: other than visible.
Now bring back your clutter and see if everything is looking to fine to you.
- Bring back your floated div (of course there is need to
increase some width of body)
You see it has no effect. - Bring back same odd margins.
- Set green div to overflow: visible as you set in your question (that misalignment is due to increase of border width from 1px to 5px so if adjust negative left you'll see there is no issue)
- Now remove additional characters I added to aid in
understanding. (and of course remove negative left) - Finally reduce body width because we no longer need wider one.
And now we are back to where we started from.
Hopefully I have answered your question.
h2 interfering with vertical-align of inline divs
You must use display:inline-block;
for make div inline.
This property allows a DOM element to have all the attributes of a block element, but keeping it inline.
Use this: style="display:inline-block; vertical-align:top;"
Try this
Or just try to make your first div float:left
:
Try this
Allow inline-block elements to wrap before stacking
Use display: table-cell;
Instead of display:inline-block
will solve your issue.
.title { display: table-cell; vertical-align: top;}.box { display: table-cell; vertical-align: top;}
<div class="title"> <h1>Hi</h1> <h2>Lots of text I want to wrap</h2></div><div class="box"> Should stay in a block</div>
Related Topics
How to Create a Teardrop in HTML
How to Center Buttons in Twitter Bootstrap 3
Getting Youtube.Com to Load in Iframe
Can't Show Some Websites in Iframe Tag
Should I Use <Ul>S and <Li>S Inside My <Nav>S
HTMLagilitypack Drops Option End Tags
How to Make Image Caption Width to Match Image Width
Streaming a Video from Google Drive Using HTML5 Video Tag
Change Bootstrap Input Focus Blue Glow
Why Would The Height Increase with a Smaller Font Size
How to Disable Text Selection with CSS or JavaScript
HTML5 Audio Not Working on Firefox
PHP Mail() - How to Put an HTML Link in an Email
CSS Divide Width 100% to 3 Column