Make element appear before/after previous text? - css

Given this:
<h1>This is a test <small>It is</small></h1>
Is there any CSS I could apply to the <small> that would have it appear BEFORE, and ON THE PREVIOUS LINE, before "This is..."? float:left; display:block; doesn't get it before the content.

In a relatively simple case like this, you can use positioning. Declare the heading as relatively positioned, set a suitable top padding on it, and make the small element “absolutely” positioned (i.e., positioned relative to its positioned ancestor, the heading). Example:
h1 { position: relative; padding-top: 1em; }
h1 small { position: absolute; top: 0; left: 0; height: 1.3em; }
Note that when setting the padding, em denotes the font size of the h1 element, whereas when declaring the height of the inner element, the small element, em denotes its font size, which is smaller. Hence 1em vs. 1.3em, even though the padding is meant to give room for the small element. You probably want to set font sizes on h1 and small (say, h1 { font-size: 150% } small { font-size: 80% }) to get more predictable rendering, and then experiment with the padding and height values to get the appearance you like. This tuning will also depend on the font.

Here it is:
HTML:
<h1 id="thisid">This is a test <small>It is</small></h1>
CSS:
#thisid:before {
content:"This is the content on the line above \A ";
white-space: pre;
}
The :before pseudo element will make the stuff go before. Whereas the \A will make a space break.
Here is the fiddle: http://jsfiddle.net/pikk/ZL54q/

Related

font-size vs line-height vs actual height

This question's answer says that the font-size defines the height of a box so that all letters (with ascenders and descenders) can fit.
But why has a span with 40px font-size and line-height an actual size of 45px? If I understand the linked question correctly then "X" should be smaller than 40px but the overall height should be exactly 40px. I thought that maybe it is making some extra room above/below the ascenders/descenders but the image shows that the ascenders/descenders take all the space so there can't be much extra room:
When I wrap a div (green) around the span then the div has a height of 40px. Why does the div use the font-size of its child for its height but the child itself doesn't?:
Now when I set the span's line-height to 15px (less than the font-size) then the div's height changes to 26px. How is this value calculated? Has this something to do with the baseline?:
When I set the span's line-height to 65px (more than the font-size) then the div's height is the height of the line-height. I would have expected the div's height to be something like (65px - 45px) + 45px.:
So how do font-size and line-height affect the actual heights of elements? I read some questions that referenced the spec but I couldn't make much out of it. Are there any easy to understand rules?
JSFiddle
First, I recommend reading my answer in Inline elements and line-height. To summarize, there are various heights related to inline boxes:
Height of the inline box, given by line-height
Height of the line box, which in simple cases is also given by line-height, but not here.
Height of the content area of the inline box, which is implementation dependent. This is the area painted by the red background.
The other height in your case is the height of the parent div. This is determined by §10.6.3. In this case, since the box establishes an inline formatting context with one line,
The element's height is the distance from its top content edge to [...] the bottom edge of the last line box
So the height of the parent block is given by the height of the line box.
What happens here is that the height of the line box is not the line-height of your inline box. And that's because the line-height of the parent block is also taken into account:
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."
If you set parent's line-height to 0, and child's vertical-align to e.g top, then the height of the parent will exactly be the line-height of the child.
.outer {
margin-top: 50px;
background-color: green;
width: 150px;
font-family: "Times New Roman";
line-height: 0;
}
.letter-span-1 {
background-color: red;
line-height: 40px;
font-size: 40px;
vertical-align: top;
}
.letter-span-2 {
background-color: red;
line-height: 15px;
font-size: 40px;
vertical-align: top;
}
.letter-span-3 {
background-color: red;
line-height: 65px;
font-size: 40px;
vertical-align: top;
}
<span class="letter-span-1">XxÀg</span>
<div class="outer">
<span class="letter-span-1">XxÀg</span>
</div>
The parent block is 40px tall.
<div class="outer">
<span class="letter-span-2">XxAg</span>
</div>
The parent block is 15px tall.
<div class="outer">
<span class="letter-span-3">XxÀg</span>
</div>
The parent block is 65px tall.
If you don't set a line-height to the parent, it will be normal.
Tells user agents to set the used value to a "reasonable" value based
on the font of the element[...]. We recommend a used value for
'normal' between 1.0 to 1.2.
That means that there will be a minimum height for the parent which will be its font-size (which you don't specify, and the default is implementation-dependent) multiplied by that factor (implementation-dependent).
You should also consider the vertical-align of the span. By default it's baseline, and that may create a gap below. The image in web-tiki's answer is especially useful:
That's because vertical-align determines how the span will be aligned with the strut, and with baseline the alignment can depend on font-size and end up increasing the height of the line box. The line box height is the distance between the top of the uppermost and the bottom of the lowermost boxes in the line.
If you don't want the height of the parent div to be increased by that, you need some other vertical-align, like top, middle, or bottom. Then the font-size of the span shouldn't affect the height of the div.
To summarize, the height of the div depends on
Its line-height
... which by default depends on div's font-size
Span's line-height
... which by default depends on span's font-size
Possibly span's font-size, depending on span's vertical-align
And obviously height, min-height, max-height, etc.
Introduction
Good question,
I learn most of these things through personal experience.
In this case, the DIV height is set to auto. It will detect the height of its own contents, and evaluate its new height from there.
Clearly, the DIV only takes into account the line height of the . This is likely due to the diverse number of fonts. Line-height gives us the adaptability we need for various font types.
In Short
font-size
Font size only changes the actual font itself, and not the div elements around it
line-height
Line-height is the height of the actual line and will change the div elements around it
Wait a second...
If we have something like this:
div {
background: green;
margin-top: 50px;
}
.test-one {
font-size: 20px
}
.test-two {
font-size: 40px
}
<div>
<span class="test-one"> test one </span>
</div>
<div>
<span class="test-two"> test one </span>
</div>
Clearly the size of the DIV (height: auto;) changes according to font-size. That's because the line-height will automatically adjust accordingly if it is not set manually.
One Exception
Upon further inspection, I noticed that DIVs don't always match the line-height. This occurs if the line-height is very small, and the font exceeds it by some distance.
The example you gave -
.outer {
margin-top: 50px;
background-color: green;
width: 150px;
font-family: "Times New Roman"
}
.letter-span-1 {
background-color: red;
line-height: 40px;
font-size: 40px;
}
.letter-span-2 {
background-color: red;
line-height: 15px;
font-size: 40px;
}
.letter-span-3 {
background-color: red;
line-height: 65px;
font-size: 40px;
}
<span class="letter-span-1">XxÀg</span>
<div class="outer">
<span class="letter-span-1">XxÀg</span>
</div>
<div class="outer">
<span class="letter-span-2">XxÀg</span>
</div>
<div class="outer">
<span class="letter-span-3">XxÀg</span>
</div>
If you look closely,
letter-span-1 and letter-span-3 both result in the DIV equaling the line-height.
However, letter-span-2 does not.
-------------- Line-height - Actual-height
letter-span-1: 40px - 40px
letter-span-2: 15px - 25px
letter-span-3: 65px - 65px
Notice that letter-span-2 is the smallest. It is so small, it will actually limit the height of the div. You can test this by altering the font size.
The "Why?"
Why have these two different settings, and not just change height normally?
I honestly am not sure, but I speculate that it was because fonts aren't standard. If the computer misreads a particular font, it may incorrectly evaluate the line-height.
Not to mention the numerous "CSS Tricks" you can do with line-height. It is great for adding space for open designs.
Conclusion
Line-height defines div height, unless line-height is very small, in which case the font-size will define the size.

Div within a div css styling - use padding to center inner div inside the outer?

So I have 2 divs, 1 within another. #outer the outermost div and #frame the div w/in #outer.
With regards to #outer, I've applied a background picture that is to take up the entire browser space.
frame is where the text will go - text will constantly change with different string lengths. However, I only want #frame to occupy the center portion of #outer, so that text does not leak outside (this is because the background picture in #outer has a chalkboard-like figure - I want it to look as though the text is being written onto that chalkboard without text running outside the lines).
I'm supposed to use padding for this right? As in set the padding attribute on #frame right? Or should I adjust the frame's width? How do I center this sucker?! Float? Pad? I'm lost...
HTML:
<div id='outer'>
<div id='frame'>
</div>
</div>
CSS:
#outer {
height: 612px;
background: url('http://i151.photobucket.com/albums/s147/yungottii/abveaspi_background_final.png') no-repeat 0 0 scroll;
background-size: 100%;
}
#frame {
text-align: center;
height: 612px;
padding: 50px;
overflow: auto;
font-family: Didot, "Didot LT STD", "Hoefler Text", Garamond, "Times New Roman", serif;
font-size: 60px;
color: black;
}
I've been messing with padding and border and margin for the past hour trying to get a grasp on the box model in general. Any quick pointers that anyone can help me accomplish this?
PS It may be difficult to see, cuz this probably isn't fully compatible with your browser settings yet, but you can go to:
http://www.abveaspirations.com
to see what the above code is currently spitting out. As you may be able to see, the especially long strings/text leak outside of the glass. BTW I'm using textualizer plugin, not sure if that changes anything...
This is a little more complicated of an answer than it could be.. This can pretty much be done with padding, but I feel that this way is the most smooth and solid result for what you are doing, and it also works extremely well for a responsive site, so it won't break as you scale your screen size up and down.
Here's the demo of this in action so you can follow along with what I'm saying, and look at the full code at the same time:
http://jsfiddle.net/9FtFh/1/
Ok so first of all, just to set up your outer div, I basically just set position: relative; on it, everything else is fine. This is just because I'm setting the frame to be position: absolute; and I want it to position relatively to this outer div.
After that, lets look at the changes to the frame...
position: absolute;
top: 10%;
bottom: 20%;
left: 15%;
right: 15%;
These styles serve the purpose of stretching the bounds of the div out to certain points. Notice that there is no set height or width on the frame element anymore, those must be taken out. Basically, these styles say that the top of the div will be 10% from the top of the outer div. The bottom will be 20% from the bottom of the outer div.. and so on. I used percentages instead of pixels, as this will make sure the positioning adapts to whatever width the screen is.
Notice that I set a dotted border on the frame so that you can see where the box is being sized and positioned at all times.
I didn't worry about vertical centering of the text content because I'm fairly certain that your plugin for the text effect handles that. Just let me know if I was wrong on that count, and I can expand on that.
Now, there's another challenge in the fact that once the screen gets to a certain smaller size, the image begins to have a smaller height than the outer container. This probably isn't something you want, so I added a media query:
#media only screen
and (max-width: 1060px) {
#outer {
height: 0;
padding-top: 47.85%;
}
}
What this does is it applies styles only after the screen gets to be a certain width. I choose the max-width based on the point where the image starts to shrink past the edges of the container.
As for the styles that get applied, this is a little trick for maintaining the aspect ratio of a container on re-size. I set the height to 0, and then re-create the height using padding-top. The number that I used (47.85%) is an approximate ratio of the height of the image relative to the width. (The image is about 47.85% as high as it is wide.) This will now begin to scale the whole container down with the screen, to match the image. Because your frame is positioned absolutely, it will stay around for the ride, and maintain it's percentage based position.
One thing I did not do that you might be interested in is setting another media query once the image width starts to get so wide that the bottom gets cut off. At this point you could set the frame bottom to be 0% so that it matches that. (you may also need to periodically update the top property, as the screen gets wider and wider. This is only because you have a set height cutting off the image, making the percentages irrelevant.)
In that example I linked to, try re-sizing that bottom frame's width larger and smaller, and watch how the dotted lines stay right where they should be, and the content inside adjusts. Also notice how the container stays the set height up until the image gets too small, and then everything begins to scale down.
There's only one glaring issue that I can see left, and that is that because all of your text content gets positioned absolutely letter by letter, re-sizing the screen will cause elements to spill out, until a new slide comes in, and the letters are re-positioned based on the new width. That's just something to keep in mind going forwards.
Option 1 http://jsfiddle.net/bdbpY/
#outer {
background-size: 100% 100%;
}
And it works. The only issue is that it will change the height/width of your image to something other than you may want.
Option 2 http://jsfiddle.net/bdbpY/1/
Another option which probably will work better is this
#frame {
height: 100px;
overflow: hidden;
}
This works how you want.
If you're going for adjustable widths instead of a fixed px, you can than try stuff like
#frame {
max-height: 50%;
overflow: hidden;
}
Option 3 http://jsfiddle.net/qLNFz/
This is probably the best choice , and easiest.
All I did was this
#frame {
height: 29%;
padding: 10px 20px;
}
HTML
<div id='outer'>
<div id='frame'><span class="sp">Sample Sample Sample Sample Sample Sample Sample Sample Sample Sample Sample Sample Sample Sample Sample </span>
</div>
</div>
CSS
* {
margin:0px;
padding:0px;
}
#outer {
background: url('http://i151.photobucket.com/albums/s147/yungottii/abveaspi_background_final.png') no-repeat 0 0 scroll;
background-size: 100% 100%;
width:1000px;
margin:0px;
}
#frame {
margin:20px auto;
text-align: center;
width:600px;
height:400px;
padding: 50px;
overflow: hidden;
font-family: Didot, "Didot LT STD", "Hoefler Text", Garamond, "Times New Roman", serif;
font-size: 60px;
color: black;
border:1px solid black;
}
.sp {
overflow:hidden;
}
Demo
I have used overflow:hidden; for long text to accommodate in the frame. So your board will be like this http://jsfiddle.net/3pNSx/70/

Make empty div of one line height

Is it possible to create a rule that will make the following HTML:
<div style="width: 100%"></div>
of one line height using just CSS, or do I need to put as the content?
Some possibilities:
Set height (or min-height) to the line-height's used value.
The initial value of line-height is normal, whose used value is implementation-dependent, but the spec suggests a number between 1.0 and 1.2
In my case (FF27 for winXP with font-family: "times new roman") that value is 1.25, so you could use height: 1.25em. However, that value might be different with other fonts or implementations.
Then, it's better to manually set line-height to some value, like line-height: 1.25em.
div {
border: 1px solid red;
min-height: 1.25em;
line-height: 1.25;
}
<div></div>
Note that if you want to set those styles to the elements only when it has no content, you can use the :empty pseudo-class:
div:empty {
border: 1px solid red;
height: 1.25em;
line-height: 1.25;
}
<div></div>
Inserting some content to the element.
For example, you can add a normal space and set white-space to pre-wrap (or pre) to prevent the space from collapsing:
div {
border: 1px solid red;
white-space: pre-wrap;
}
<div> </div>
Alternatively, you can use a zero-width space (​)
div { border: 1px solid red; }
<div>​</div><!-- There is a zero-width space inside -->
As you say, would also work. However, it is a non-breaking space, so its purpose is preventing automatic line breaks. Then, using it would be semantically incorrect IMO.
And as #BoltClock says, those whitespaces could be inserted with CSS pseudo-elements, but note that might not work on very old browsers.
Just another solution:
.your-selector:empty::after {
content: ".";
visibility: hidden;
}
That depends on your definition of a single-line height, since there isn't a CSS unit that corresponds to the computed line height of an element.
If you know the exact line-height value for this element, then you can just explicitly set height to the same value. But, given your question, this is likely not the case.
There is a unit that corresponds to font size, em, which you can use if the height of one line is equal to the computed font size:
<div style="width: 100%; height: 1em"></div>
Otherwise you will have to put in some sort of filler content. You can either throw in an and be done with it:
<div style="width: 100%"> </div>
Or go a little overkill by writing a CSS rule with a pseudo-element, but you must be able to target this element somehow:
div::before { content: '\00a0'; }
If the element may or may not have content but you want it to have a minimum height,
use min-height where you would have used height instead, or
select div:empty::before instead if you choose to use a pseudo-element so the filler doesn't get inserted if there is content.
The solution with visibility: hidden; is clever. It is simpler to set the content to Unicode character feff, which is the byte order mark. This has no width but has height; it behaves the same on every browser all the way back to IE6.
.your-selector:empty::before {
content: '\feff';
}
I have found that WebKit (at least on Mac OS) applies slightly different (1px) line height to bold text than normal text for some fonts. To enforce uniformity (in this case, we would need to apply even to non-empty selectors):
.your-selector::before {
content: '\feff';
font-weight: 900;
}
The problem I had was with jQuery Terminal that needed to have empty line same size of normal lines. Other solution was problematic because when using fixed line-height there was gaps between lines also there was bug in Firefox that I've reported about layout with font-size + line-height.
By best solution so far is this:
div::before {
content: '\0200B';
float: left;
display: block;
}
and no line-height/min-height in the code and it works perfectly. Also when not using line-height it have good looking style selection without gaps.
What height do you want to keep? Will that be in relation with your font-size? That can be in em, pt, px or %.
This is just an example where 1.5em is arbitrary value:
<div style="width: 100%; height: 5px" ></div>
If you don't have anything to write in this div, use some height value.

&::before Pseudo element not aligning properly - CSS(3) Box Model - LESS

I'm trying to add an image with the &::before pseudo element and place it on top of it's parent element by adjusting the padding/margin. I have not be able to place the img "on top" of it's parent element. It resides within the box of the parent. I have tried setting both elements to display:block. I have attempted to use relative/absolute positioning. I have adjusted margins/padding without a solution.
HTML:
<div class="foo">
<div class="title">title</div>
<div class="body">text</div>
</div>
LESS/CSS:
.foo {
display:block;
padding: 1em;
&:before {
background-image: url("bar.svg");
padding: .25in;
background-repeat: no-repeat;
background-position: top left;
background-position: top outside;
background-color: white;
content: "";
display: block;
max-width: (#column + .45in);
margin-left: -.15in;
margin-top:-.5in;
}
}
I would expect adjusting the value of the margins on the pseudo element would produce the expected result. However this is not the case. Is there a limitation I'm unaware of?
Thanks for your time and your help.
First, I assume by "on top" you mean displayed "before" the .foo element. I assume that based on what it appears you are trying to do with your code. Normally, I would interpret "on top" as a higher z-index and overlapping an element, but I don't think that is what you are asking.
Second, unless I am unfamiliar with something (definitely possible), there is no outside keyword for background-position; therefore, that would seem to be an error (though I would not expect it to cause the issue you face).
Third, I would think that your basic premise should be working. This fiddle demonstrates a shifting of the :before element to be "before" its .foo parent. It could be your mixed use of em units and in units is causing some issues. That would not be a good way to insure you get the positioning you want. I would keep your units in em.
Pseudo-elements are displayed inline by default. Also, they are placed within the content area of an element.
To make it appear 'on top' of that element, set the display to block.
Lastly, pseudo-elements should be initialized using the content property.
.foo::before {
content: url(./bar.svg);
display: block;
}

CSS: Why does reducing the font size of an adjacent inline element increase the overall leading?

I have an element that contains two span tags that each contain some text. The container element sets a font size, then the font size on the second span tag is set to a lower size. When the second span is reduced in font size, the space between the line and the next block element is increased. This occurs in both WebKit and Gecko.
The p container element has { margin-bottom: 0; padding-bottom: 10px; } and its following sibling has { margin-top: -5px; }
The following image illustrates the situation and contains a snapshot of the relevant part of the document structure in FireBug.
Why is the spacing beneath the p tag increasing after reducing the font size of the second span tag?
My guess is that you have a (relatively) large line-height being inherited by that decimal span (perhaps 32px?), and when you reduce the font size down to 18px, you get a situation where the baseline of the decimal glyphs match up with the nondecimal glyphs, but the line must still take up the full specified line-height. Thus, extra space is added below the baseline.
Add a line-height rule and I bet this goes away:
.box .value > .decimal { line-height: 18px; }

Resources