I have a simple HTML vertical menu, with such a structure:
<div id="menu">
<div class="item">
...
</div>
</div>
I've set the .item div to be rendered as text elements, so they're ordered next to each other:
#menu div.item {
margin: 0px;
padding: 0px;
display: inline;
}
This kinda works:
However, I want to apply a :hover effect on each link, such as vertical black borders will come from sides and connect with the bottom dashed border:
So I did the following:
#menu div.item a{
padding: 5px;
border-width: 0px 1px 0px 1px;
border-color: transparent;
border-style: dashed;
}
#menu div.item a:hover{
border-color: black;
background: #B3D2FF;
}
But the link seems to be bigger than it's parent element. I didn't think this was possible:
What's wrong? Why doesn't the parent DIV stretch to be able to contain whatever's inside?
(not) Working fiddle.
Rest of the CSS:
#menu {
text-align: center;
margin: 0px;
padding:0px;
background-color: #CEE2FF;
border-bottom: 1px dashed #1868FF;
}
Add the following css:
#menu div.item a {
display: inline-block;
}
Before this code, the a tags are not being displayed as blocks and the container doesn't want to be friends with them.
The padding 5px you used on the a tag will be partially applied but only left-right in respect to other sibling inline elements.
You're trying to set padding to inline elements, which is visually not the desired. The padding on inline elements will refer to the textual line, but not in respect to the containing block-level parent.
Remember that padding can be set to block-level elements such as
<div>, <h1>, <p> etc...
One fix is to use some simple math and set line-height to your a
The other is to set your inline anchors as display-block elements,
doing that way your elements will act contextually as inline elements while being allowed to take block-level elements properties.
https://developer.mozilla.org/en-US/docs/Web/CSS/display
http://www.w3.org/TR/CSS2/propidx.html
Also setting just like that an inline any element to be inline-block is not the best choice and is not fully compatible with older browsers.
display-inline for span, a, b, i, s, q, u will work in all browsers,
but generally speaking span is the perfect one to be used in that case cause even if an inline element by properties is similar to div.
https://developer.mozilla.org/en-US/docs/HTML/Block-level_elements
https://developer.mozilla.org/en-US/docs/HTML/Inline_elements
From CSS 2.1 section 10.6.1 Inline, non-replaced elements
The vertical padding, border and margin of an inline, non-replaced box
start at the top and bottom of the content area, and has nothing to do
with the 'line-height'. But only the 'line-height' is used when
calculating the height of the line box.
The height of the block div is the height of the stack of line boxes, which in this case is the height of the one and only line box. Which means that if you want to contain the <a> with padding, you need to set the line-height of the <a> element.
Add to your CSS
#menu div.item a{
line-height:30px;
vertical-align:top;
}
Like this: http://jsfiddle.net/Z63gs/4/
You can try putting overflow:hidden; on your #menu item. http://jsfiddle.net/Z63gs/1/
This will just hide the extra fluff. I think your padding is making the <a> elements larger than you would like.
Elliot's answer is much cleaner than this.
Related
a:link,
a:visited {
background-color: #f44336;
color: white;
padding: 14px 25px;
text-align: center;
text-decoration: none;
display: inline-block;
}
a:hover,
a:active {
background-color: red;
}
This is a link
In the above code if I set "display" to "inline" the link gets pushed towards upside. Why is it so?
First of all, your question is not a duplicate of Why is this inline-block element pushed downward? and the answer here (unlike that question) has nothing to do with vertical alignment. Nor will studying "Section 8 Box Model" of the CSS 2.2 spec enlighten you.
To understand what's happening here you need to understand about heights. The height of block containers and the height of line boxes, and how they interact.
Block containers, which includes among others display:block and display:inline-block elements have a height that's either the sum of the height of its block level box children, if it has any, or the sum of the line-heights of its stack of line boxes otherwise.
In the case of your example, the <body> element, which is a display:block block container has only inline-level children, regardless of whether the <a> element is display:inline or display:inline-block so its height is the height of the sum of the line boxes. Furthermore, unless the viewport is very narrow, we can simplify things further by assuming that all the text in the <a> element will fit on one line, and so the height of the <body> element is the height of the one and only line box that it contains. We have this:
You'll note that I haven't depicted the boundaries of the <a> element above. That's because its placement depends on whether it is display:inline or display:inline-block.
We now need to look at how line-heights are calculated from the content. For display:inline elements we have this in the section 10.6.1 Inline, non-replaced elements of the spec.
The height of the content area should be based on the font, but this
specification does not specify how. A UA may, e.g., use the em-box or
the maximum ascender and descender of the font.
and
The vertical padding, border and margin of an inline, non-replaced box
start at the top and bottom of the content area, and has nothing to do
with the 'line-height'. But only the 'line-height' is used when
calculating the height of the line box.
Put those together, and what it means is that the height of the line box in this circumstance is the height of the text, and that the padding you have: padding: 14px 25px; doesn't affect the height of the line box at all, when the <a> element is display:inline. If it doesn't affect the height of the line box, then it doesn't affect the height of the <body> element either. But the background of the text and its padding still get painted. So we have this:
display:inline-block is different. Here the 10.6.6 Complicated cases spec says:
For 'inline-block' elements, the margin box is used when calculating
the height of the line box.
So the line box contains the whole of the inline-block element, not just the content, but the padding, borders and margins as well. In this case we have
And we can see if we put them alongside one another, that the text is lower for display:inline-block, than for display:inline.
Block-level elements are vertically aligned depending on the upper side of the box.
Inline-level elements are vertically aligned in respect to the text baseline. That is why for block-level elements your top padding is taken into account, but not for inline-level elements.
I would recommend reading about the box model in the spec.
a:link,
a:visited {
background-color: #f44336;
color: white;
padding: 14px 25px;
text-align: center;
text-decoration: none;
display: inline-block;
}
a:hover,
a:active {
background-color: red;
}
This is a link
In a nutshell:
An inline element has no line break before or after it, and it tolerates HTML elements next to it.
A block element has some whitespace above and below it and does not tolerate any HTML elements next to it.
An inline-block element is placed as an inline element (on the same line as adjacent content), but it behaves as a block element.
Please go through this article for more insights.
You should preferably use display: inline-block in this case.
a:link,
a:visited {
background-color: #f44336;
color: white;
padding: 14px 25px;
text-align: center;
text-decoration: none;
display: inline-block;
}
a:hover,
a:active {
background-color: red;
}
This is a link
Quote from Head first html:
You can add padding to the top and bottom of inline element, but the padding doesn’t affect the spacing of the other inline elements around it, so the padding will overlap other inline elements
a) As far as I understand the above quote, adding padding to the top and bottom of inline element doesn’t ( ever ) have any effects on surrounding elements and thus on the look of the page?!
b) But what exactly is meant by “padding will overlap other inline elements”? Does it perhaps suggest that in certain circumstances padding ( top and bottom of an inline element ) will have effect on the look of the page?!
thanx
Use inline-block instead. Add these properties to all the elements on which you want to add padding. For example:
a:link {
display: inline-block;
display: -moz-inline-box;
-moz-box-orient: vertical;
vertical-align: top;
zoom: 1;
*display: inline;
}
If I understand correctly, and from an example I just made:
a) the text is an inline element, so me adding a span with top and bottom padding is not pushing the other lines down
b) as you can see, since I've added a color to the span, the color will overlap the other lines.
I hope this is both right, and answers your question :D
Try this:
<style type="text/css">
div { background: blue; height: 4em; padding: 1em }
span { background: red; padding: .5em; }
</style>
<div>
<span>one</span>
<br/>
<span>two</span>
</div>
The padding will affect the element itself. For example, any text within the element will be more padded from other DOM elements.
This is the HTML:
<div>
<p>
We bring you the latest in entertainment & information services, right on your phone. From the latest of Bollywood to the futuristic applications, get it all here!
View All
</p>
</div>
And this is the CSS....
div{width: 350px;}
a{
padding: 30px;
background: red;
margin: 20px;
border-radius: 12px;
background: red;
color: #fff;
font: bold 12px Arial, Helvetica, sans-serif;
text-decoration: none;
}
I know this could be solved by using display: inline-block; in .a. But I would like to know why this is overlapping the text? Should it not to go beyond the text?
DEMO1
DEMO2 now a is within a block level of p.
And also have a look at this DEMO. Img is also an inline element. And why this is not overlapping, this should also be overlapping, right?
<a> tag is inline level but while <img> tag is both inline and block level specially inline-block. So <a> tag is overlapping because of inline level which is corresponding to the text but <img> tag won't overlap because it is behaving inline-block. And you may know the difference between them.
Reference: Is <img> element block level or inline level?
An inline element could not be set its width and height and even doesn't work correctly the margin behaviour what actually should do. The margin is applied only to left or right side. Actually this is why, inline element here <a> tag would not set its width and height and remain in same line and seems to be overlapped when applied padding values.
The following picture makes you clear to understand about inline vs inline-block
View Live Demo
It's overlapping because the default behavior for an <a> tag is to fit with the text. If you want it to behave like a block, then set display: block.
The initial value for the display property on a link is display: inline. This means that it will try to fit in with the text and will accept horizontal margins, and padding on all sides, which is exactly why your link overlaps the text. In order for it to accept vertical margins (so it doesn't overlap), you need to set it to display:block or inline-block if you want it to align with the text still.
Padding doesn't work well with inline elements.
Ref:Inline Elements and Padding
This actually is explained in the W3C spec, although it was a bit tricky to find.
Horizontal margins, borders, and padding are respected between these boxes.
This tacitly implies that vertical margins/borders/padding are not respected. It goes on to say:
The height of a line box is determined by the rules given in the section on line height calculations
If you move the <a> into the contents of the box
We bring you the latest in entertainment View All
You can see this effect: http://jsfiddle.net/rHCNb/7/ -- the horizontal padding is respected, but not the vertical. The fact that it covers the other text has to do with z-indexing.
Add the below property in a.
position:relative;
float:left;
Working DEMO
TIPS:
Write background-color instead of the shorthand background when you
are not associating any other property.
If you write display:block then the block width will be equal to the parent
width, so always write width with display.
a{
padding: 30px;
background-color: red;
margin: 20px;
border-radius: 12px;
color: #fff;
font: bold 12px Arial, Helvetica, sans-serif;
text-decoration: none;
display: block;
width: 50px;
}
DEMO
Why isn't the image centered in the li? The dimensions of it is 25x25px.
#information-list li {
height: 50px;
line-height: 50px;
padding: 0 10px;
border-bottom: 1px solid #c1c0bf;
}
#information-list li img {
vertical-align: middle;
margin-right: 10px;
}
<ul id="information-list" class="flat-list">
<li>
<img src="images/test.png" />
<strong>Foo</strong>
</li>
...
Try this instead:
#information-list li {
height: 50px;
line-height: 50px;
padding: 0 10px 0 20px;
border-bottom: 1px solid #c1c0bf;
background:transparent url(images/test.png) no-repeat left center;
}
<ul id="information-list" class="flat-list">
<li>
<strong>Foo</strong>
</li>
...
It is vertically centered for me (tested your css/markup in Chrome/Firefox/IE)
Do you have a valid doctype?
You can read about vertical-align, and how it works here.
As commented by animuson, here is how you should use inline elements and vertical-align.
Essentially, you need to vertically align both inline elements, and you did it on one only.
You should also try to keep line-height properties on blocks that contain text.
Here's a JSFiddle example - I also included some proof that it is in fact centered
CSS
#information-list li {
padding: 0 10px;
border-bottom: 1px solid #c1c0bf;
}
#information-list li img,
#information-list li span{
vertical-align:middle;
}
#information-list li span{
font-weight: bold;
line-height: 50px;
}
HTML
<ul id="information-list" class="flat-list">
<li>
<img src="images/test.png" />
<span>Foo</span>
</li>
...
Here's a screenshot
W3C will give us a bit of insight.
www.w3.org - line-height:
On a block container element whose content is composed of inline-level elements, 'line-height' specifies the minimal height of line boxes within the element.
The minimum height consists of a minimum height above the baseline and a minimum depth below it, exactly as if each line box starts with a zero-width inline box with the element's font and line height properties. We call that imaginary box a "strut." (The name is inspired by TeX.).
The height and depth of the font above and below the baseline are assumed to be metrics that are contained in the font. (For more details, see CSS level 3.)
On a non-replaced inline element, 'line-height' specifies the height that is used in the calculation of the line box height.
www.w3.org - vertical-align:
This property affects the vertical positioning inside a line box of the boxes generated by an inline-level element.
Note. Values of this property have different meanings in the context of tables. Please consult the section on table height algorithms for details.
The following values only have meaning with respect to a parent inline element, or to the strut of a parent block container element.
In the following definitions, 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.
The default blocks
The HTML you provided consists of 4 blocks which have these display properties by default.
<ul> - treated as a block
<li> - treated as list-item
<img> - is treated as an inline-block (placed as inline, but formatted as a block)
<strong> - treated as inline
Try to remember them. Though they have little impact on this particular scenario, it is good to know the defaults and what they do and what they are for.
See also
9.2.2.1 Anonymous inline boxes
Any text that is directly contained inside a block container element (not inside an inline element) must be treated as an anonymous inline element.
Quote from Head first html:
You can add padding to the top and bottom of inline element, but the padding doesn’t affect the spacing of the other inline elements around it, so the padding will overlap other inline elements
a) As far as I understand the above quote, adding padding to the top and bottom of inline element doesn’t ( ever ) have any effects on surrounding elements and thus on the look of the page?!
b) But what exactly is meant by “padding will overlap other inline elements”? Does it perhaps suggest that in certain circumstances padding ( top and bottom of an inline element ) will have effect on the look of the page?!
thanx
Use inline-block instead. Add these properties to all the elements on which you want to add padding. For example:
a:link {
display: inline-block;
display: -moz-inline-box;
-moz-box-orient: vertical;
vertical-align: top;
zoom: 1;
*display: inline;
}
If I understand correctly, and from an example I just made:
a) the text is an inline element, so me adding a span with top and bottom padding is not pushing the other lines down
b) as you can see, since I've added a color to the span, the color will overlap the other lines.
I hope this is both right, and answers your question :D
Try this:
<style type="text/css">
div { background: blue; height: 4em; padding: 1em }
span { background: red; padding: .5em; }
</style>
<div>
<span>one</span>
<br/>
<span>two</span>
</div>
The padding will affect the element itself. For example, any text within the element will be more padded from other DOM elements.