I know this is very basic CSS. How do I keep the span contained within the div? At the moment, the span extends outside the top and bottom of the div.
div {
width: 200px;
margin: 10px;
background-color: #ff0;
}
span {
margin: 5px;
padding: 5px;
background-color: #fc0;
}
<body>
<div>
<span>span</span>
</div>
</body>
To answer your question, this isn't just an issue with padding or margin, but also with width, display, and the box model.
jsFiddle
span {
display: inline-block;
}
This will honor any padding, margins, or widths you apply to the span.
Inline elements will not consume vertical padding and margin space. You can make the span display: block, but without more detail I don't know if that will achieve your goal.
The vertical padding, border and margin of an inline, non-replaced box (e.g. span) 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. Therefore you see an overlapping here: http://jsfiddle.net/Q9AED/
If you want to use a straightforward solution, you can use line-height rather than display: inline-block: using line-height.
display: inline-block works in Safari >= 2, Opera >= 9, IE >= 8, Firefox > 3. But you can imitate an inline-block in IE < 8: display: inline; zoom: 1.
Related
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.
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.
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.
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.
I'm trying to put some (vertically-stacked) display:block elements within a display:inline-block element. According to the CSS specification, the inline-block element should be a containing block, so it can have display:block elements within it and those should not affect the rest of the layout.
However, the display:block elements inside the display:inline-block elements disrupt the rest of the page; so does having nothing at all within the inline-block, or even a basic element like a paragraph; only simple text avoids disruption of the rest of the page (by disruption I mean shifting other divs down, e.g. in this case the left red block moves down a line and has a blank white space above it). I'm using Firefox 3.0.6.
<html><head><style type="text/css">
#left {
display: inline-block;
background: red;
width: 20%;
height: 100%;
}
#right {
display: inline-block;
background: green;
width: 80%;
height: 100%;
}
</style></head><body>
<div id="left">Left</div><div id="right">Right</div>
</body></html>
The above shows as two panes, left red, right green, as expected. If I change "Right" to
<p>Right</p>
or remove it entirely, or (as I want to do) replace it with a couple of divs, I get the bad formatting.
Is this a Firefox bug, or am I doing something wrong, or are my expectations incorrect? (FWIW, IE 7 mangles them all equally, as if it doesn't understand inline-block; doesn't matter, this is an internal app. and I'm only using Firefox). I may be able to get the layout I want using float/margin, but I'd prefer not to have to do that.
Well display: inline-block can be a bit tricky to get cross-browser. It will require at minimum, a few hacks and, for Firefox 2, potentially an extra element.
CSS
.inlineBlock { display: -moz-inline-stack; display: inline-block; zoom: 1; *display: inline; }
display: -moz-inline-stack is for Firefox 2. All the immediate children will need to have display: block or otherwise be block level elements. Note if you need your inline-block element to shrink wrap I think you can use display: -moz-inline-box instead.
zoom: 1 gives hasLayout to the element (for IE 7 and below). Part 1 of the hack needed for IE7 and below compatibilty.
**display: inline* is a hack second part of the hack needed for IE7 and below compatibility.
I occasionally need to add overflow: hidden for IE compatibility as well.
For your specific situation i think what you need is:
<html><head><style type="text/css">
#left {
display: inline-block;
background: red;
width: 20%;
height: 100%;
vertical-align: top;
}
#right {
display: inline-block;
background: green;
width: 80%;
height: 100%;
vertical-align: top;
}
</style></head><body>
<div id="left">Left</div><div id="right"><p>Right</p><p>Right 2</p></div>
</body></html>
I get the bad formatting.
You are being bitten by margin collapsing, a CSS ‘cleverness’ which is a pain as often as it is a boon. The margin of the <p> collapses outwards to become a top margin on the inline-block; this then behaves as a margin would on an ‘inline’ element would, pushing the vertical-alignment of the text line out.
You can stop it happening by removing the margins from ‘p’ elements and using padding instead. Alternatively place a non-empty element with no top margin at the top of the block and one with no bottom margin at the bottom.
Is this a Firefox bug
I think possibly yes, according to the spec's:
Margins of inline-block elements do not collapse (not even with their in-flow children).
inline-block
This value causes an element to generate an inline-level block container. The inside of an inline-block is formatted as a block box, and the element itself is formatted as an atomic inline-level box.
visual rendering model