Space around text in header elements - html

I have been inspecting a header element using firebug, and have noticed that the header container does not hug its contained text, even though I have no padding set.
<h2>test</h2>
http://jsfiddle.net/BTwk6/
The top and bottom spacing is greater than that on the left and right, the result of this is that my h2 does not sit squarely in its containing box.
Is this normal? Is there anyway to have the h2 box hug its text?
Thanks

Yes, it is normal, and things are supposed to be that way. If you e.g. set a border on a heading element, you will see that characters in the heading text will normally not touch the border.
There are two reasons to this. First, the height of a font is a design concept and does not (normally) correspond to the height of any letter; there is empty space above even capital letters as well as below the baseline of text. Descenders like that of “j” or “g” may, in some designs, reach the bottom of the font, and diacritic marks like that of “Ê” may reach the top, or even go beyond it.
Second, there is normally some leading above and below a line, typically a total of 15–20% of the font height. The default depends on the font (and on the browser). In practice, this is meant improve readability and to prevent characters from touching characters on the previous or next line.
The leading is indirectly set by setting line-height, since line-height sets the total height that is the sum of font height (font size) and leading. By setting line-height: 1, you set leading to zero; this is called “setting solid” in typography, and it can be suitable for isolated lines, like a one-line heading. But there is still spacing caused by the first reason mentioned, the spacing that has been “built in” into the font. You can even set line-height to a smaller value, like 0.85, making the leading negative. Beware that this may cause vertical truncation of characters if the font used differs from the one you suggest on your page.

Try adjusting the line-height property as well, by default different fonts have different spaces above and below them. You may not be able to entirely fix this. For example, the word
Tempura
Is a whole lot taller than the word
mum
But the word 'mum' will still have to have the same height above and below the line as 'Tempura'.

by default a h2 element has a margin of 19px top an bottom. Try to reset it

Try to reset margin and padding :
h2{margin:0;padding:0}
replace 0 with your own values ...
mimiz

Related

Fit text exactly without spacing

In CSS/HTML, using a simple text within a div with no margin/padding with a given font-size (assume 36px) and a given line-height of 36px will not fit exactly, there's always some spacing at the top of the line. Reducing the line-height for 20% (i.e. in this case 29.8) seems the result in the desired effect.
Why is this, is there any browser thing I am missing? I'd assume having a line-height equal to font-size should actually NOT add any spacing around a line at all?
Update: The effect I am actually getting is called "half-leading". Howevever, I assumed that when setting the line-height equal to the font-size, no leading may occur at all as the browsers' calculated half leading should result in 0px.
Update 2: Just found this in the CSS-Spec: http://www.w3.org/TR/CSS2/visudet.html#line-height
However, I am still confused considering how to avoid having added ascender/descender at all?
Responding to your update #2:
Since ascender/descender height is calculated for each font, there are fonts that don't have ascenders/descenders, like all caps monospace. It would need to be a font that doesn't include any characters with a/d; just applying text-transform: capitalize wouldn't work.
A roundabout solution, but as you've stated it is a "feature not a bug".

How to deal with line-height while coding a pixel perfect design

Here is a screenshot of the example design I made up:
There is a 10px space between the bottom of the letters and the red line. I'm trying to replicate this with the following code:
font: normal 40px arial;
border-bottom: 3px solid red;
padding-bottom: 10px;
Technically, this code should give me exactly what I want. But it doesn't. Here is a screenshot of it in action in Chrome:
Because of the line height, there's extra space between the text and the border. Here's an inspected screenshot on Chrome:
When I take my time and measure the space under the letters that's being caused by line height, I can see it's a 9px of empty area. So, to get 10px of space between the text and the border I need to change my code to:
padding-bottom: 1px;
A solution to this might be adding a line-height property with amount of the text's exact height in the design file. But then, it'll mess up if the text includes multiple lines.
What is the best approach here to accomplish the pixel perfect design conversion?
In HTML, there is no way to specify the spacing between the text baseline and the border. To understand this, see this picture:
The height of HTML text always includes both the ascender area and the descender area, even in cases when there are no letters with a descender or an ascender. Therefore the real distance between the bottom of the text and the border in your example is not 10px.
To get the correct distance from the bottom of text in pixels, change the text so that it contains a letter with a descender (e.g. Hellp, Worly") and measure the space between the bottoms of descenders and the red line.
Alternatively, if you are trying to recreate a picture and can't change the text, measure the ratio text height / point size of the used font using a drawing application (e.g. Inkscape), then calculate the distance as follows:
css distance = baseline distance - (point size * (1 - ratio))
The basic spacing below and above a character (glyph) is defined by the font designer. For example, in Arial, there is space below and above an ordinary uppercase letter like “H” even when text is set solid (line-height: 1). When line-height is larger than 1, there is additional spacing below and above. Even for line-height smaller than 1 (i.e., with “negative leading”), there can be some spacing. And any padding that you set adds to that.
If you know the exact text that appears in the content (and it will never change) and if you rely on the specific font to be always available (which is very probable, but not certain, for the Arial font), then you can run some experiments and iterate until you find a suitable line-height value. In this specific case, line-height: 0.82 would remove the spacing above common capital letters A–Z (but any diacritic marks on them, as in É or Å, will be cut off) and would reduce the spacing below the baseline (but if letters have descenders as in “j” or “þ”, they will then be partly cut off).
Pixel-perfectness may still be disturbed by font rendering differences (like anti-aliasing or not) across browsers.

Why does Verdana font result in a different space size before text depending on font?

In the following HTML/CSS example
http://jsfiddle.net/Hmwvv/
we can notice a leading space with size proportional to font's size. How can I remove this effect in order to have different sized texts in different div elements aligned ?
There is a small amount of white space around each glyph, this is intentional so that the letters don't overlap. You can see this by selecting one letter.
To solve your problem, introduce a small negative text-indent.
#big {
text-indent: -5px;
}
Demo
The leading space is part of the character rendering, as you can see e.g. by setting `div:first-letter { background: green }. It would violate normal typographic rules to tweak it.
But if you really want to align the leftmost strokes of letter “M” in different sizes in a heading and in the first line of a paragraph after it, then setting margin-left: 0.3em on the paragraph would seem to be the best option. This applies Verdana and those specific characters are used. (If e.g. the first letter of the heading is “J”, the situation is very different.)

line-height affecting even no-text blocks

I noticed that line-height seems to affect blocks. Its strange to me, that i never noticed this disturbing effect before.
The problem is that it will affect blocks, even if they do not contain text at all.
I created a JSFiddle to demonstrate the issue. If you set line-height to 0, the grey area will no longer exceed that of the image inside the container.
Why is this happening and is there a clean way to prevent it?
The line-height value affects rendering even in the absence of text, since “'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.” (CSS 2.1 about line-height.)
But that’s really not the cause here. Images are by default rendered inline, meaning that they act as big (or maybe small) letters, sitting on the baseline of text. The details are complicated, but by setting line-height considerably smaller than font size, you put baselines closer to each other and the space vanishes.
Another way to remove the disturbing effect is to set display: block on the img element. Then the element will be formatted in a different way.
Yet another way is to set vertical-align: bottom on the img element.

Is margin property of an element ignored until its value is equal or greater than

1)
a) Even if inside CSS file we don’t specify a margin property for a particular block ( like <p> ), browser still displays it as if this block has a linebreak before and after it. Is that space ( let’s call that “default” space a dS ) considered a margin with some default value?
b)
I would assume that if I add ( inside CSS file ) to a <p> element a margin property with a value of 1px, then space below and above <p> should be increased by one pixel? So if dS consists of 15 pixels, then new space should have the height of 16 pixels?
But that doesn’t seem to be the case! Namely, if I assign a value of 11px to margin property, space above and below <p> doesn’t appear to have the height of 26 pixels ( dS + 11px = 15px + 11px = 26px). In fact, the height appears to be the same as when margin property was assigned a value of 1px.
So it would seem that until margin property is assigned a value equal or greater to some predetermined number, the margin property is simply ignored and dS is used instead?
Seems like you're probably observing some variety of a browser's default styles for HTML 4 being applied.
To help with your second question, this article on margin collapsing might be useful.
Excerpt from Article:
Most block elements have a default top
and bottom margin, such as paragraphs
and headings for example, which may
have a top and bottom margin of 1em,
which computes to 16 pixels if that is
the current font size. This is what
creates the gap between two
paragraphs. It is also what causes
margin collapsing to be so important.
[...]
Paragraphs may have 16 pixels top and
bottom margins, while DIVs have 0. As
a result, the gap between the DIV and
paragraph is 16 pixels in each case.
The gap between the two paragraphs is
also 16 pixels, even though there are
two paragraphs, and they may be
expected to have 32 pixels between
them. This is a margin collapse.
[...]
Margin collapsing happens
wherever two (or more) top or bottom
margins are touching. The basic idea
is that when they touch, instead of
getting the sum of the two margins,
the bigger one is used, and the other
is ignored. So in the case of the two
paragraphs, the 16 pixel bottom margin
of the first one touches the 16 pixel
top margin of the second one.
Max(16,16) is 16, so the gap between
them is 16 pixels.
1)
a) Even if inside CSS file we don’t
specify a margin property for a
particular block ( like ), browser
still displays it as if this block has
a linebreak before and after it. Is
that space ( let’s call that “default”
space a dS ) considered a margin with
some default value?
A browser has a so called default stylesheet, which it applies to the elements. The linebreaks are because it's a block style element. That has nothing to do with margins.
I would assume that if I add ( inside
CSS file ) to a element a margin
property with a value of 1px, then
space below and above should be
increased by one pixel? So if dS
consists of 15 pixels, then new space
should have the height of 16 pixels?
No, if you apply a margin on an element, it overwrites the default style. So it would be just 1px;
These are very good questions. Can you please post some sample html with CSS to better describe question #2.
As for question #1, there are per-browser default settings for all elements, and some of this does include margin defaults. Some people like to reset all CSS styles so that they are guaranteed certain expectations across browsers and platforms. See http://meyerweb.com/eric/thoughts/2007/04/12/reset-styles/ for a good example of how to do this.
Not only do different browsers measure height differently based on different interpretations of their box model (see http://www.communitymx.com/content/article.cfm?cid=E0989953B6F20B41), but margins have a tendency to "collapse" into each other when they are adjacent, so there is shared space between the margins of elements (see http://www.howtocreate.co.uk/tutorials/css/margincollapsing).
Hope this helps.
It sounds like you're running into "collapsing margins". If you have two elements with mismatched top/bottom margins, the larger value is used (there are other rules which govern margin collapsing, but that's the basics).
If you apply a 1px margin to your <p> elements, they'll have just one pixel between them, but if you have, say, an <h2> above them, the <h2>'s (presumably larger) margin will be used. If you increase the top margin on your <p>s to be larger than the bottom margin on your <h2>, then the space between them will increase. This is what's giving you the illusion of a "minimum margin".
To decrease the space between an <h2> and a <p>, you'll need to reduce both the <h2>'s bottom margin and the <p>'s top margin.