html5 vertical spacing issue with <img> - css

I am trying to create a layout where the vertical spacing between divs is pixel perfect. So far I've ruled out almost all the big grid systems (960.gs, Blueprint), because they have no solution at all for the vertical spacings. With them, the only way to set vertical spacing between divs is to use body { line-height } attribute and manipulate the div spacing using that. I wouldn't call that a solution, as it ruins your template, depends on font-family, and doesn't let you use different spacings for different divs.
The only grid system I found which has proper support for vertical spacing is Golden Grid, which doesn't use body { line-height }, but has it's own .clear { height: 5px } for vertical spacing.
My problem is that no matter how I try, I couldn't make spacing work in HTML5. I am talking about vertically arranged images without gap between them. In XHTML transitional mode, everything works perfecly, the images align perfectly, but when in HTML5 mode, they have a vertical gap between them. The gap is 2px in Chrome and 2-3 px in Firefox, alternating between lines. I think it's the case with every grid system when used in HTML5 mode. I don't know what's the best way to write this code in plain HTML5, so I just tried grid systems. The vertical gap is present in 960.gs, Blueprint too.
A solution I found out might be to set body { line-height: 0 } and define line-height in every single typographic tag. But I don't understand why such a bad hack would be required for such a simple case: vertically arranged images. Why are browsers different in HTML5 mode than in XHTML Transitional mode?
Here, I have the same page, nothing changed, just the doctype. The XHTML one is pixel perfect in every browser, the HTML5 one has the gap and is different from browser to browser.
What is the best way to make the HTML5 example work like the XHTML transitional one?
UPDATE: thirtydot answered the problem, if I include img { display: block; } the HTML5 version behaves exactly the same as the XHTML Transitional. Thank you thirtydot!
But before closing this thread, can someone explain to me why is it that:
Why do all browsers behave differently in HTML5 mode and all have different vertical gaps between img elements, when not specified as display: block. Have a look in a browser comparing site for the html5 link above, it will be different from browser to browser. They have gaps between 2 to 4 px.
Why does XHTML Transitional not need this hack
Why does XHTML Strict produce a vertical gap too
Is it safe to use img { display: block; } in a reset.css sheet?

Why do all browsers behave differently in HTML5 mode and all have different vertical gaps between img elements, when not specified as display: block?
First of all, browsers do not have a "HTML5 mode". What they have are three modes "Quirks", "Limited Quirks" (aka Almost Standards) and "Standards" mode. There is only one difference between "Limited Quirks" and "Standards" modes and that relates to the way in which a line-height and baseline is established for the line box of which the <img> sits. In "Limited Quirks" mode, if there is no rendered text content on the line, then no baseline is established and the <img> sits on the bottom of the line box.
In "Standards" mode, the line box always contains the space for the descenders of characters like g, p and y below the baseline, even if there are no real characters in that line box.The gap you see is the distance between the baseline and the bottom of the line box which is the space for those descenders. For a thorough description, see http://msdn.microsoft.com/en-us/library/ff405794%28v=vs.85%29
The remedy, then, is either to stop <img> being treated as an inline element { display:block; } or to override the vertical alignment of the <img> { vertical-align:bottom; }. Either will work.
Why does XHTML Transitional not need this hack
Using the XHTML Transitional doctype places the browser into "Limited Quirks" mode. Had you used XHTML Strict, or a full HTML4 Strict doctype, you would have seen the same gaps as you see with the HTML5 doctype as each of these places the browser in "Standards" mode.
Why does XHTML Strict produce a vertical gap too
See above.
Is it safe to use img { display: block; } in a reset.css sheet?
Of course, but there will probably be times when you'll want <img> to be treated as an inline element. In those cases, you'll need to add CSS in the appropriate places to achieve that.

I feel like this can't be the answer you're looking for. It's too short:
Add to the CSS of your HTML5 page: img { display: block }.
Testing in Firefox and Chrome, doing that gets pixel perfect identical rendering between your two pages.

The vertical-align: baseline is causing the gap at the bottom of your images.
In Strict doctypes, images are inline elements and behave like text. Aligning inline elements at the baseline causes them to leave room for text descenders even if there is not any text.
Adding img { vertical-align: bottom } to your reset stylesheet will fix the problem.

Try this code:
<html>
<head>
<style>
div, span { border:1px dotted; height:100px; width:100px; }
</style>
</head>
<body>
<span>100px</span>
<div>100px</div>
</body>
</html>
When you consider that <img> is an inline element like <span>...I think most of your questions are answered.
Without the width/height attributes, your dependent on each browsers rendering engine to being identical (they're not). So pixel perfect won't work until you tell the browsers how many pixels to use.

Related

CSS Inline margin issue

Hopefully an easy one.
I am concentrating heavily on the CSS side of things in my project, but am having an issue with block vs inline elements, and I don't really want to move on as I know it's fundamental to learning CSS. So the misunderstanding...
I have a span element which is inline.
<span>Please Login With Your Details Below</span>
There is a margin-left of 40px on this span which shows
However if I shrink the viewport small enough it does this
Issue: So on the new line it doesn't keep the margin...
However if I change the span to display:block it does this
which is what I want.
However I read this on https://www.impressivewebs.com/difference-block-inline-css/ regarding inline elements
Will ignore top and bottom margin settings, but will apply left and
right margins, and any padding
So it may be that I have misread it totally, but from what I understand it should have applied the left margin. Can someone explain why it didn't?
Thanks
When the user agent decides that inline content cannot fit the containing block, it will split the inline content into multiple inline boxes in order to accommodate the wrapping required to properly display without overflowing the containing block (if possible).
So in your example, Please Login With Your Details Below would overflow the containing element when you shrink the viewport, and therefore gets broken into two inline boxes:
Please Login With Your Details and Below.
According to the W3C recommendation:
When an inline box is split, margins, borders, and padding have no visual effect where the split occurs (or at any split, when there are several).
They provide this specific example that demonstrates what you are encountering:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML>
<HEAD>
<TITLE>Example of inline flow on several lines</TITLE>
<STYLE type="text/css">
EM {
padding: 2px;
margin: 1em;
border-width: medium;
border-style: dashed;
line-height: 2.4em;
}
</STYLE>
</HEAD>
<BODY>
<P>Several <EM>emphasized words</EM> appear here.</P>
</BODY>
</HTML>
The margin is inserted before "emphasized" and after "words".
The padding is inserted before, above, and below "emphasized" and after, above, and below "words". A dashed border is rendered on three sides in each case.
Your described behaviour is totally fine and correct.
However, the information is correct that left and right margins are applied to the inline element.
The information you did not had is, that actually inline elements left margin only indent the first line.
Think of it as an element meant to be in one single line, where this line can have horizontal margin. Having the text break in multiple line is a nice feature. But from the point of view of the margin property its still one a line.
You can use this property
text-align: justify;
text-align-last: justify;

html and body height confusion

I have this simple code:
<html xmlns="http://www.w3.org/1999/xhtml">
<body bgcolor="#000000">
</body>
</html>
Questions
Why I am getting html height 8px in Chrome and Firefox? HTML height should be auto (0px).
The body height is 0px, so why is the background color (black) filling the whole screen?
Before I answer your questions let me tell you that even browsers have their default CSS style which is applied to every webpage! (To give you more insight let's say these default styles are the reason why normal HTML Buttons appear differently in Chrome, Firefox and IE)
Now for your first question: As per browser's default CSS HTML has padding of 4px! That's why you are getting HTML height 8px.
Now you must be wondering how to get rid of them? So for that we can use Normalize CSS
Now for your second question: you can say BODY is the special case tag which has a exceptional way of rendering it's background! (Or say it's not like a normal DIV tag)
In the absence of a background on the html element, the body background will cover the page. If there is a background on the html element, the body background behaves just like any other element.
You can read more about it here
Hope you found your answers.
You have a line break:
<body bgcolor="#000000">
^---- here
</body>
which gets rendered as a space character, causing you to have an implicit single line of text in your page.
If you look at the page using Chrome devtools, you'll see that the 8px height is coming from the user-agent stylesheet; that is, browsers apply their own default styles.
One common technique to wipe this away and start from a 'clean slate' is to use one of the many css reset libs.
See here for some options.
You are getting margin as 8px, not the height. Each browser has some default settings that's why you are seeing that. Check out the default settings for each browser using the below links:
Firefox
Webkit
IE

CSS Challenge: INPUT going outside of DIV

I'm trying to accomplish something specific around platform constraints I'm under.
I created a somewhat self-explanatory jsfiddle of the problem at http://jsfiddle.net/MrV5M/4/
The specific problem:
On Chrome, the right border of the input box is cut off.
On Safari, the width of the content class cell exceeds the container so it spills over the border.
On IE9, the label doesn't float to the left of the content div
The main reason I care about Safari is because I'm working on a JQuery Mobile/PhoneGap app which is also a web app. I'm only supporting modern browsers, but this is driving me nuts. Normally I'd just use a table for the container, but the text-overflow: ellipsis styles on the content div don't work when inside a table. (Basically, I'm trying to keep the content to a single line and have ellipsis without enforcing a fixed width or calculating a width with Javascript)
Anyone have the l33t CSS skills to make this work? I sure don't... :)
Just add this CSS to your Stylesheet, and get peace of mind on your issue :D
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
You may not like this answer. I made some adjustments in the css which fixes Chrome and IE9 issues. Take a look,
http://jsfiddle.net/MrV5M/11/
There are many ways to do what you are trying to do, but if you insist on using 'flex' stuff which is largely un-supported (even in the majors see here), you'll need to add the vendor prefixes to flex.
e.g... -webkit-flex, -moz-flex
Also, I don't think you need to be setting widths on elements that have the flex property.. not positive though.
So your browser issues:
-IE doesn't support flex at all so you're label won't float unless you use a float.
-The reason your input/content is spilling over the container and getting cut off is not really anything to do with flex.. but the way css works.. setting an element to 100% width means setting it to the width of its parent. But by default, css doesn't count the padding/border-width as part of that width. So you end up getting 100% width plus the L/R padding and border. But, since you are only supporting modern browsers.. box-sizing:border-box; to the rescue. Google it for details, but putting it on your input element should do the trick.

HTML 5, CSS border outline inconsistency

I've looked around but not found a solution to this issue. Using the following CSS
border: double 1px #999;
outline: solid 4px #EAEAEA;
I was able to create a simple double border around a DIV quite easily. In HTML4. Then I switched the Document type to <!DOCTYPE html>, at which point the bottom outline was offset by about 5px. Curiously, only the bottom outline because the other 3 sides of the are still flush with the border.
Am I missing something about border outlines in HTML5? I should stress that it looks perfect in HTML4.
It may be quirks mode box-model issue (if you've used an incomplete Transitional DOCTYPE which doesn't enable "standards mode"). Without proper DOCTYPE you get emulation of IE5 bugs, including an "old" box-model.
The behavior you get with <!DOCTYPE html> is considered correct by the CSS spec.
Ideally you should reduce dimensions of the element by border width to compensate.
Alternatively (if you're using sizes in % for example), switch box-model to the one you expect (works in IE8+):
div {box-sizing: border-box;}
Note that it affects border only. The outline will be outside the box regardless, and it's not going to influence layout. You can reserve room for the outline using equivalent margin.

IE6 website display problem (background or padding issue?)

I'm trying to get a website to display properly in IE6 and IE7. Here is a screenshot of how it looks in IE6.
alt text http://img225.imageshack.us/img225/4779/screenshot20091006at239.png
IE8, Safari, Firefox, etc. all display this site correctly. Could someone give me a hint as to what is causing the distortion in IE6?
If you want to take a look at the page source, the site is: www.devaswami.com
Get the CSS from here.
You're using an auto-layout table for the navbar, and it has colspans. This confuses IE, which is not very good at working out how big tables need to be when there are colspans. It makes the table wider than you need, which makes your cells wider than expected, which makes the ugly yellow background show through and it doesn't line up.
To fix it, set the style table-layout: fixed; width: 970px; on the table element, and add one <col> element for each column, each with a width: ...px style that tells IE exactly how big to make each column. Then it can't make any mistakes (and also larger fixed table layouts render faster).
To fix it better, drop the layout table and use positioned divs for the nav links. You could then also lose the silly image slicing and have a single GIF for the whole header background with the photo and links positioned over the top of that.
(Also it is worth fixing the validation errors both in the HTML and in the CSS. You are using // as a single-line comment in your stylesheet, but there is no such thing in CSS; you will only confuse the parser into dropping rules.)
Ummm at a glance, you have something that is float left and you have a margin left on it?
#foo {
float: left;
margin-left: 20px; //20px in all browsers except IE6 where it will be 40px;
display: inline; //this will fix this issue
}
There's a lot of possibilities and it's hard to just guess based on the screensnap. However, one big step towards making IE 6 and 7 behave better is to declare the doctype at the top of the document:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
That's for HTML 4.01, you'd have to update it to match what you're specifically using if it's not HTML (i.e. XHTML). That alone helps with some of the basic problems, but not all of them. If that doesn't do it, Google "IE6 css hacks" and you'll find lots of potential information that may apply to your context.
Edit: I suggest you fix the errors related to missing/improper end tags:
Error Line 199, Column 194: end tag
for element "a" which is not open
Error Line 200, Column 49: end tag
for element "p" which is not open
Source: http://validator.w3.org/check?uri=http%3A%2F%2Fdevaswami.com%2F&charset=(detect+automatically)&doctype=Inline&group=0
After that's done we can deduce that it's not a markup related issue.
Original answer:
Try applying haslayout to every element and using display:inline on any floated element:
#nav li { display:inline; } /* the selector *must* be floated and have horizontal margins in the direction of the float. */
* { zoom:1; }
For anything that was fixed by the zoom:1, apply a width/height and that will trigger hasLayout.
Though it might be useful if you actually posted some source code.

Resources