How To Position Text On A Baseline?
Solution 1:
After searching ...and searching I came up with this very awesome tutorial at adobe's place about how to align text to baseline of an element.
USING PSEUDO-ELEMENT
I would suggest this one but take a look at all the story bellow (Road from .strut element to a single pseudo-element):
div {
width: 400px;
height: 100px;
}
.first {
font-size: 24px;
background-color: #9BBCE3;
}
.first::after {
content: "";
height: 100%;
display: inline-block;
}
<div><divclass="first">Hello g World / With font-size: 24px</div></div>
USING AN EXTRA .STRUT ELEMENT
- SCENARIOS AND RULES
Rule 1 (Larger Fonts): We want the height of the div to be fixed. For example 20px. So, the font-size
must be equal or less to the .height
value so as to work.In general,
~ THE FONT-SIZE MUST BE EQUAL OR LESS THAN THE FIXED HEIGHT.THEN IT WORKS FOR ALL SIZES WITH LESS VALUES
Scenario 1: Suppose that we have larger fonts than the 20px
of this case.
See it in action:http://jsfiddle.net/csdtesting/pvw5xhku/
div.forall {
width: 700px;
height: 48px;
border: thin black solid;
background-color: #9BBCE3;
margin-top: 20px;
}
.inText {
font-size: 48px;
line-height: 48px;
}
.inText3 {
font-size: 22px;
line-height: 22px;
}
.strut {
height: 48px;
display: inline-block;
}
<divclass="forall"><divclass="inText">Hello g World /With font-size 46px
<divclass="strut"></div></div></div><divclass="forall"><divclass="inText2">Hello g World /With font-size 32px
<divclass="strut"></div></div></div><divclass="forall"><divclass="inText3">Hello g World /With font-size 32px
<divclass="strut"></div></div></div>
- EXPLANATION
All the magic about this implementation is about the .strut element
.This is the one with display:inline-block;
property!
I wondered ...what is that again ?!
The baseline of the strut is placed at its bottom margin edge, which is determined solely by the height of the strut in this case. And if the letter span’s line-height is smaller than the strut’s height, the letter’s baseline will move to match! Unbelievable!
- MAIN IMPLEMENTATION
See it in action:http://jsfiddle.net/csdtesting/bm2yz3ec/
div.forall {
width: 300px;
height: 20px;
border: thin black solid;
background-color: #9BBCE3;
margin: 10px;
}
.inText {
font-size: 20px;
line-height: 20px;
}
.intext2 {
font-size: 9px;
line-height: 9px;
}
.strut {
height: 20px;
display: inline-block;
}
<divclass="forall"><divclass="inText">Hello g World /With font-size 20px
<divclass="strut"></div></div></div><divclass="forall"><div>Hello g World / Without font-size
<divclass="strut"></div></div></div><divclass="forall"><divclass="intext2">Hello g World / with font-size:9px
<divclass="strut"></div></div></div>
Solution 2:
Yes, to some extent: you can manipulate the position of text using a combination of line-height
and a choice of other properties, including setting margins and padding, or using position: relative
and top
. There are other techniques if you only have one line that needs positioning (e.g. if you're creating a drop cap); I will cover positioning techniques that work on one and multiple lines.
There is the rather large caveat to this that type rendering varies between OSes and browsers, and it is going to be difficult to control your text precisely, particularly if you want pixel-perfect control.
By default, browsers position text roughly in the middle of the line, as defined by the line height. There is not a defined baseline for text that is invariant between browsers, so positioning varies between browsers.
The idea when setting up vertical rhythm is to have all your text falling at certain intervals. To do this, you need to control font size (which most people do anyway), line height, and anything that will add vertical space to your design: borders, padding, and margin. You select your "rhythm unit"--in your case, 20px--and then set your text to align with it. Your line height should be equal to your rhythm unit (i.e. 20px); for large font sizes, use multiple of the rhythm unit (e.g. 40px, 60px) to ensure the text stays in rhythm. The combination of borders, padding, and margin should add up to your rhythm unit to keep everything in line.
I've made the following JS Fiddle to illustrate the next piece of code.
As mentioned earlier, text gets vertically centered(-ish) by the browser, so it doesn't sit nicely on a grid; the text baseline moves around when using different font sizes. Here are a couple of ways to deal with that.
Here's our sample HTML:
<article><section><h2>Title!</h2><divclass="first">Hello g World<br />Lorem ipsum...</div><divclass="second">Hello g World<br />Lorem ipsum...</div><divclass="first">Hello g World<br />Lorem ipsum...</div></section></article>
We'll give it the following basic css:
article {
margin: 0;
padding: 0;
line-height: 20px; /* 20px is our "unit of rhythm" */
}
div {
margin: 20px;
}
h2 {
font-size: 24px;
line-height: 40px; /* double our rhythm unit */
}
.first {
font-size: 16px;
}
.second {
font-size: 30px;
line-height: 40px; /* double our rhythm unit */
}
Using position: relative
and top
:
Visually align text by positioning it relatively to the background grid.
Give the section
element the class rel
and add the following CSS:
.rel, .rel.first, .rel.second {
position: relative;
}
.rel.first {
top: 4px;
}
.rel.second {
top: 9px;
}
JS Fiddle - half way down the page
This pushes the text down from its natural position. Unfortunately, this alignment has to be done by eye and yep, it does vary from browser to browser. Pages are usually internally consistent--i.e. text lines up with the grid, even if it is uniformly a couple of pixels higher in some browsers.
Using padding
and/or margin
The sum of the top and bottom padding must equal our unit of rhythm. Again, alignment has to be done by eye and may differ between browsers.
.ptop.first {
padding-top: 24px;
padding-bottom: 16px;
margin: 020px; /* get rid of the massive gap! */
}
.ptop.second {
padding-top: 30px;
padding-bottom: 10px;
margin: 020px; /* get rid of the massive gap! */
}
JS Fiddle - scroll to the bottom
You can also use margins, but care must be taken with collapsing margins to ensure the rhythm stays intact.
That is a whistlestop guide to a couple of methods for establishing vertical rhythm. I've skimmed over the details, so I would advise you to read up about this online -- there is a great article about vertical rhythm at 24ways, and another good one at A List Apart. There are also some vertical rhythm generators to stop you doing too much pixel-fiddling yourself.
Solution 3:
try adding line-height
attribute as well:
div {
background-color: rgba(255, 0, 0, 0.3); /* For visualization only */margin-top: 50px; /* For visualization only */height: 20px; /* This is fixed! */line-height: 20px;
}
UPDATE
Setting height
and line-height
to the same value aligns text vertically by center:
JSBIN
If you only use 16px
and 30px
that might be enough for you. If you need this to work with all values, I would suggest you use another layout, something like this:
<divclass="container"><spanclass="align-bottom">Hello g world</span></div>
Solution 4:
I don't think there's a CSS property for this, and I don't think you can determine it programmatically.
However, you can adjust the div
's height with JavaScript, assuming the section of the font above the baseline is approx. 80%:
var d = document.getElementsByTagName('div');
for(var i = 0 ; i < d.length ; i++) {
d[i].style.height= d[i].offsetHeight*0.8+'px';
}
Remove the hard-coded div
style height first.
Fiddle: http://jsfiddle.net/38eLft8q/1/
Solution 5:
A little tricky and maybe not bulletproof, but so far:
HTML
<divclass="first"title="Hello g World"></div><divclass="second"title="Hello g World"></div>
CSS
div {
background-color: rgba(255, 0, 0, 0.3);
margin-top: 50px;
height: 20px; /* This is fixed! */position: relative;
}
div:before {
content: attr(title);
position: absolute;
bottom: -0.24em;
}
.first {
font-size: 10px;
}
.second {
font-size: 16px;
}
thanks for the challenge :)
UPDATES:
For no changes in the question structure we'll keep div's text:
<divclass="first">Hello g World</div><divclass="second">Hello g World</div>
and a little javascript will create the titles
var divs = document.getElementsByTagName("div");
for (var i = 0; i < divs.length; i++) {
var txt = divs[i].innerHTML;
divs[i].setAttribute('title', txt);
}
finaly some css changes
div {
background-color: rgba(255, 0, 0, 0.3);
margin-top: 50px;
height: 20px; /* This is fixed! */text-indent: -9999px;
position: relative;
}
div:before {
content: attr(title);
text-indent: 9999px;
position: absolute;
bottom: -0.24em;
}
If we can change the structure that will be
HTML
<divclass="first"><span>Hello g World</span></div><divclass="second"><span>Hello g World</span></div>
CSS
div {
background-color: rgba(255, 0, 0, 0.3);
margin-top: 50px;
height: 20px; /* This is fixed! */position: relative;
}
divspan {
position: absolute;
bottom: -0.24em;
}
NOTE:
- Not checked with different fonts, but i think it's only to calculate the bottom part.
Post a Comment for "How To Position Text On A Baseline?"