Skip to content Skip to sidebar Skip to footer

How To Position Text On A Baseline?

PLAYGROUND HERE HTML:
Hello g World
Hello g World
CSS: div { background-color: rgba(255, 0, 0, 0.3); /

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>
enter image description here
  • 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>

enter image description here

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;
}

JSBIN

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;
}

JSBIN

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;
}

JSBIN

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?"