For some reason a basic unstyled DIV element has extra height tacked onto the bottom when it contains a VIDEO element (and possibly other elements - I haven't tested with many types).
<div><video src="my_movie.ogv"></video></div>
I have the above line of code in a barebones base HTML file. With Firefox or Safari/Chrome's (if I use an .mp4 file instead of course) DOM inspectors on I see that the computed height of the DIV element is anywhere from 2-5 pixels more than the height of the VIDEO element.
This doesn't seem like expected and intentional behavior. If I put a P element in there instead of a VIDEO element, for example, the DIV doesn't have any of the extra height.
Does anyone know why the browsers are rendering this configuration of DOM elements in this way?
If your markup is as above and there are no special styles applied to it, then the behavior you see is required by the CSS box model; the space is the size of the font's descent, because the bottom of the video is placed by default on the baseline, not at the bottom of the text. In particular, see https://bugzilla.mozilla.org/show_bug.cgi?id=22274#c55 for an explanation in spec terms and https://bugzilla.mozilla.org/show_bug.cgi?id=22274#c37 for how to get rid of the space if you want to. You could also set line-height on the block to 0 to get rid of the space; which approach you take should depend on your other design constraints.
Related
Background
I have a standard three column layout where the first column is floated left, and the third column is floated right. The first column needs a full-height background.
This layout is for a template, so any of the three columns could have the longest content.
I can't change markup source order, so display:table solutions are not possible.
I can't add any DOM nodes.
The layout is centered with a minimum and maximum width, so I can't attach a vertically-repeating background image to the page with the built-in background color.
It needs to look OK in IE7, but IE8+ needs support.
Solution
To achieve the full-height left column, I created a pseudo-element on colLeft. That pseudo-element has fixed-positioning set to the viewport bottom, 100% height, and placed behind the left column. This solution is awesome because:
IE8+ supports pseudo-elements.
The pseudo-element is attached to the left column, so if the template doesn't have a left column, the background naturally isn't there.
By not setting a left or right attribute, the fixed-positioned pseudo-element stays with the left column (good for the centered layout).
Here's an example on CodePen.
(Make sure that the Document Mode is following the Browser Mode when viewing CodePens in IE).
Problem
In IE8 the full-height left column background only extends down to the initial viewport bottom (the fold).
I created another test with a new leftColBg node instead of the pseudo-element. This works as expected in IE8, meaning that the fixed positioning should work.
Here is the best explanation that I can find on IE8 and generated content: Why does a filter gradient on a pseudo element not work in IE8?
I think IE8 is incorrectly positioning the generated content, because it's not an "object" that contains content. Can anybody better explain this IE8 bug? Is there a fix?
The main text of my website's first word has a significant larger font-size than the rest. For some reason or another the container that contains the text cuts the first word off on top. Probably because the line-height of the first word is identical to the rest of the text and thus the container is not able to calculate its own height properly.
Codepen snippet: http://codepen.io/sardasht/pen/maJup (I've included the full contents of my css file to be able to debug properly, so will not embed this here. If this is requested, I'd happily edit my post to include it, but it will be ~300 lines of text)
If I increase the line-height of the first word, the rest of the text which is on the same line gains the same line-height and thus jumps up from the rest of the text below. If I add a margin-top to the container element, the first word is not cut off anymore, but then the bottom line of the text is cut off.
I played with overflow: visible/hidden as well on all parent elements, but to no avail.
The p element has line-height: 1.5em, which will set the height of the text lines inside it. Because of the em unit, the height is determined based on the font size, and it's the font size set for the p element that is used, so the line height won't increase because of the larger font size set on a child element.
I would try using a line-height declaration that isn't set in px, or ems.
p, span { line-height:1 }
I also tried
span { line-height:0.8 }
which seemed to give the very least amount of top "push", but I only viewed it in FF on a Mac.
I've noticed, with fonts, that their heights and widths are rendered differently from browser to browser. And this can be exacerbated with fonts that haven't been given proper leading, kerning, etc. This can cause "odd" line breaks, which causes a 'problem' with set block heights -- especially going from FF, and Chrome to IE. FWIW.
EDIT:
http://jsfiddle.net/mvf6j/
Setting the line-height to 1 (of the child) equates to 100% of the parent's line-height; thus, in your example code 1 = 1.5em. In my fiddle/example, 1 = 1em (even with the child being a 2em font). It's inheritance. It makes the child relative to the parent. And takes the guess work out, if you should want to change the parent's size. All of that ease in sizing/relationships disappears when you set explicit line-heights to the children.
If I individually load in a div with a width of say 500px and display:inline-block, when it reaches the edge of the document the next start on a new line. Is there a non JS way of making the document expand horizontally (ie. with scrollbars) instead.
Sounds like you need to use min-width instead of width
Also you might want to use white-space:nowrap in order to keep text in one line instead of wrapping to another line.
The CSS2.1 spec mandates that overflow other than visible establish a new "block formatting context". This strikes me as odd, that a property whose obvious purpose is to hide overflow without affecting layout, actually does affect layout in a major way.
It seems like overflow values other than visible combine two completely unrelated features: whether a BFC is created and whether the overflow is hidden. It’s not like "overflow:hidden" is completely meaningless without a BFC, because floats historically can overflow their parent element, hiding the overflow without changing the layout seems sensible.
What are the reasons behind this decision, assuming they are known? Have the people who worked on the spec described why this was decided to be the case?
I asked about this on the mailing list on your behalf; the thread can be found here. In summary, this has to do with scrolling content for the most part:
Fundamentally, because if the spec didn't say this, then having floats intersect with something that's scrollable would require the browser to rewrap (around intruding floats) the contents of the scrollable element every time it scrolls. This is technically what
CSS 2.0 required, but it was never implemented, and it would have been a huge problem for speed of scrolling.
-David
Most likely, it refers to scrollable content in a box that may occur outside of the float's parent but would intersect with the float. I don't think this is related to rewrapping content around a float within a scrollable container, as that already happens naturally, plus the float would clip into the container and scroll along with the rest of its content anyway.
Finally this makes sense to me. In fact, I'm going to provide an example here so hopefully it makes sense to you and anyone else who may be wondering. Consider a scenario involving two boxes with the same fixed height and overflow: visible (the default), of which the first contains a float that stretches beyond its parent's height:
<div>
<p>...</p>
</div>
<div>
<p>...</p>
<p>...</p>
</div>
/* Presentational properties omitted */
div {
height: 80px;
}
div:first-child:before {
float: left;
height: 100px;
margin: 10px;
content: 'Float';
}
Notice the similarity to one of the examples given in section 9.5. The second box here is simply shown to have overflowing content for the purposes of this answer.
This is fine since the content will never be scrolled, but when overflow is set to something other than visible, that causes the content to not only be clipped by the bounds of the box, but also to become scrollable. If the second box has overflow: auto, this is what it would look like had a browser implemented the original CSS2 spec:
Because of the float, attempting to scroll the content would cause the browser to have to rewrap it so it doesn't become obscured by the float (and what should happen to the part that scrolls out of the top edge?). It would probably look something like this when scrolled to the bottom:
The catch here is that the browser has to rewrap the content every time it repaints it during scrolling. For browsers that are capable of pixel-based smooth scrolling — which is to say, all of them — I can see why it would be a performance disaster! (And a user experience one, too.)
But that's for when the user can scroll the content, right? This would make sense for overflow: auto and overflow: scroll, but what about overflow: hidden?
Well, a common misconception is that a container with overflow: hidden simply hides content by clipping and cannot be scrolled. This is not completely true:
While scrolling UI is not provided, the content is still scrollable programmatically, and a number of pages perform just such scrolling (e.g. by setting scrollTop on the relevant element).
-Boris
Indeed, this is what it'd look like if the second box was set to overflow: hidden and then scrolled to the bottom with the following JavaScript:
var div = document.getElementsByTagName('div')[1];
div.scrollTop = div.scrollHeight;
Again, notice that the content would have to be rewrapped to avoid being obscured by the float.
Even though this wouldn't be as painful for performance as had scrolling UI been available, my best guess is that they made boxes with any overflow value other than visible generate a new BFC mainly for the sake of consistency.
And so, this change was brought about in CSS2.1, documented here. Now if you apply an overflow value other than visible only to the second box, what a browser does is push the entire box aside to make way for the float, because the box now creates a new block formatting context that encloses its contents, instead of flowing around the float. This particular behavior is specified in the following paragraph:
The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with 'overflow' other than 'visible') must not overlap the margin box of any floats in the same block formatting context as the element itself. If necessary, implementations should clear the said element by placing it below any preceding floats, but may place it adjacent to such floats if there is sufficient space. They may even make the border box of said element narrower than defined by section 10.3.3. CSS2 does not define when a UA may put said element next to the float or by how much said element may become narrower.
Here's what it looks like with overflow: auto for example:
Note that there is no clearance; if the second box had clear: left or clear: both it would be pushed down, not to the side, regardless of whether it established its own BFC.
If you apply overflow: auto to the first box instead, the float is clipped into its containing box with the rest of the content due to its fixed height, which is set to 80px in the example code given above:
If you revert the first box to height: auto (the default value), either by overriding or removing the height: 80px declaration from above, it then stretches to the height of the float:
This happens to be new in CSS2.1 as well, in that an element with height: auto that generates a new block formatting context (i.e. a block formatting context root) will stretch vertically to the height of its floats, and not just enough to contain its in-flow content unlike a regular box. The changes are documented here and here. The change leading to the side-effect of shrinking the box so that it does not intersect the float is documented here.
In both of these cases, no matter what you do to the second box, it will never be affected by the float because it has been restricted by the bounds of its container.
I know this will be a speculative answer, however after reading the specifications a few times here is my view on this:
What section 9.4.1 is talking about is any block element that does not fully contain or does not fill the containment space. For example when you float an element it is no longer filling 100% of the parent, like in-flow elements do. Inline blocks, table cells, and table captions are also elements that you can affect height and width but that are not intrinsically 100% of the parent (yes table>tr>td is one that would fill 100% of it's parent but it is designed to allow for multiple td's so the td doesn't count as it will automatically shrink to accommodate additional td's) this also applies to any overflow other than visible because it breaks the containment of the block element.
So if I am reading this correctly the way it works is the 9.4.1 section is referring to block elements that break the default containment rules of the block elements as specified by section 9.2.1
When using a custom font via #font-face, it does render just as I think it should in Chrome. In Firefox, though, additional padding (top and bottom) is added to the font.
Here is my example page that outlines the problem.
Is there anything I can do about it?
FYI, this also happens in Firefox on Linux (and not in Chromium). I tried to load your font in FontForge and immediately got a warning:
The following table(s) in the font have been ignored by FontForge
Ignoring 'LTSH' linear threshold table
Ignoring 'VDMX' vertical device metrics table
Ignoring 'hdmx' horizontal device metrics table
I think the problem is that the VDMX (Vertical Device Metrics) table is defect:
In order to avoid grid fitting the
entire font to determine the correct
height, the VDMX table has been
defined.
This looks exactly like what happens in Firefox: somewhere the minimum and maximum height is incorrectly calculated. This is also clear when you select the text: the selection box extends to the utmost top and bottom of the line; if the h1 element really had padding, you would see a gap between the top and bottom of the line and the selection box.
Also, validation revealed that almost every glyph is “missing points at extrema”:
Both PostScript and TrueType would
like you to have points at the maxima
and minima (the extrema) of a path.
A quick search showed:
The only other problem I had was a
rather nasty condition called "Missing
Points at Extrema". With a font,
there needs to be a point (or node, as
they are called in Inkscape) at the
extreme left, right, top and bottom of
a glyph. Normally they are there
anyway simply because of the way your
glyph is built, but diagonal lines
with rounded ends often cause problems
[source, including picture (scroll down)]
Just Add:
line-height:1;
to your CSS rules