Line-height affecting spacing above first line and after last line - css

I've a text in side heading with multiple lines. Want the spacing the two lines to increase, so I set a line-height. When I do this, not only does it increase space between the two lines, it also increases spacing above the first line (and maybe below the second). How can I increase spacing between the two lines only, without increasing above and below.
I know it's a behavior of Line-height. but just curious if there is any good solution for this.
This is just en example to what I'm asking.
Jsfiddle: http://jsfiddle.net/jitendravyas/V3eWV/

You can use negative margins for this, although there is something to keep in mind:
line-height is a funny thing. According to CSS2.1 it doesn't specify the line-height but the minimum height of line-blocks:
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.).
A line box is defined in 9.4.2 Inline formatting contexts:
In an inline formatting context, boxes are laid out horizontally, one after the other, beginning at the top of a containing block. Horizontal margins, borders, and padding are respected between these boxes. The boxes may be aligned vertically in different ways: their bottoms or tops may be aligned, or the baselines of text within them may be aligned. The rectangular area that contains the boxes that form a line is called a line box.
This doesn't change in CSS3 very much, at least if you don't change the line-stacking. However, there is no property which targets your problem directly: you can't change the line-height of the ::first-line, it will always get applied.
That said, use negative margins for the time being. Even better, wrap your elements in a generic container. By using :first-child and :last-child you can add as many elements as you like.
Example
<div>
<h1>I've a text in side heading with multiple lines. Want the spacing the two lines to increase, so I set a line-height. When I do this, not only does it increase space between the two lines, it also increases spacing above the first line.</h1>
<h1>I've a text in side heading with multiple lines. Want the spacing the two lines to increase, so I set a line-height. When I do this, not only does it increase space between the two lines, it also increases spacing above the first line.</h1>
</div>
body {padding:30px;background:yellow;border:1px solid red;margin:0}
div{background:red;margin:0;padding:0;border:1px solid green;}
h1{line-height:2em;}
div > h1:first-child{
margin-top:-.25em;
}
div > h1:last-child{
margin-bottom:-.25em;
}

Related

If line boxes not allowed to overlap why can we get vertically overlapping text?

Excerpts from the CSS specification (emphasized by me):
9.4.2 Inline formatting contexts
A line box is always tall enough for all of the boxes it
contains.. When several inline-level boxes cannot fit horizontally
within a single line box, they are distributed among two or more
vertically-stacked line boxes.. Line boxes are stacked with no
vertical separation (except as specified elsewhere) and they never
overlap. (ref)
'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. (ref)
Keeping it in mind, that line boxes don't allow for bleeding their content away and at once don't overlap with each other, how is it still possible we can get lines of text vertically overlapping? This result may become achievable when a container's line-height is set in ems whereas an inline descendant's font-size computed value is of a comparable number (an example is at the end of this Mozilla doc).
Following the spec I would rather expect to see vertically cropped text in this case, but not overlapped.

CSS rule like inline-block to match exactly the space the text takes

If I do
<div style="display: inline-block;">Some text</div>
The div dimension fits closely the rectangle the text fits in, but not exactly:
More precisely, it fits perfectly horizontally, but not vertically. And the height will be the same wether the text is "A", "..." or "ppp", while the space used by the text changes. Is there a css property that would behave like inline block, but treat the text as a more floating element and have the smallest height that can contain the current text? Like (photoshoped):
No, there isn't.
To make that happen, and since every font has its own inner white space and renders different on different browsers, you need to measure a particular font's size and "cut" of the rest.
One way could be cloning the element and draw it on a canvas and the count colored pixels from top/bottom to get its exact height.
Further reading about fonts: http://www.freetype.org/freetype2/docs/glyphs/

CSS: Element with Lazy Width

Let's say that I want to make a <p> element that has a fixed height and a width that only grows if the height is not sufficient to display all of the text. By default, <p> is a block level element. This means it has a greedy width and lazy height. I want the opposite, lazy dynamic width and fixed/greedy height. An inline-block element tries to display the text in one line if possible, which is not something I want. I want a pure CSS solution just because. Is it possible?
This is not possible.
9.4.2 Inline formatting contexts
In an inline formatting context, boxes are laid out horizontally
[...]. The rectangular area that contains the boxes that form a line
is called a line box.
The width of a line box is determined by a containing block and the
presence of floats. [...]
In general, the left edge of a line box touches the left edge of its
containing block and the right edge touches the right edge of its
containing block. However, floating boxes may come between the
containing block edge and the line box edge. Thus, although line boxes
in the same inline formatting context generally have the same width
(that of the containing block), they may vary in width if available
horizontal space is reduced due to floats. [...]
Line boxes are created as needed to hold inline-level content within
an inline formatting context. [...]
Therefore, the width of the line boxes will only be affected by the width of the containing block and the presence of floats. And then, there will be as many line boxes as necessary.

multiple line-heights without extra css class

Is there a way to have multiple line heights in an unordered list? See the example below, the normal li's have a line height of 25px, but as soon as the sentence gets too long it will split in the same line height as defined before.
http://i46.tinypic.com/w1pdhi.jpg
I would like to have a line height of 16px once the sentence gets too long, without having to give an extra CSS class to the li.
Thanks in advance!
give the same normal line-height to every list-item and apply a margin-bottom to them to create room between each other
Jsbin example
You cannot make the line height depend dynamically on the rendering of a li element on one line vs. several lines. You could to mark the multiline li elements with a class, but being multiline should normally depend dynamically on the available width, instead of being specified statically.
On the other hand, I think that what you are really looking for is a way of setting the vertical spacing between list items. For this, you would simply set vertical margins or padding on them, using a line-height setting that is suitable for the multiline items.

How to prevent line-height from adding a margin in the top?

Whenever i use a large line-height like 1.6em it always adds a margin in the very top of the text which i don't want.
Example: http://jsfiddle.net/EstpJ/1/
i want the text to be sharply lined with the borders and not have any kind of top or bottom margin.
How to fix that?
That's exactly what line-height is, it's a manual way to set the height of a line of text for the purposes of wrapping text and such. The actual visible size is determined by the font-size and to a lesser extend by the font-family. The average line-height for normal text/font is around 1.2em. Anything larger than that will cause visible letterboxing, which is exactly what you are describing. Using a smaller value will cause successive lines to overlap each other.
The only way to fix your exact example is introduce more markup to determine line numbers so that you can style the first/last line differently.
You could maybe slightly alter your markup (I prefer wrapping <p> tags around lines of text) and use a negative top margin?
As Matthew said, this is what lineheight does.
You could try to set the line height on an inner div (inside the one with borders), and counteract the top and bottom effect by also setting a negative top and bottom margin. But it's likely that the negative margin won't work in all browsers.

Resources