Saturday, 30 July 2005

CSS Superscript and Subscript Using Relative Position

You might have noticed in my previous post that the note references in the body of the text were displayed as superscript. Now sup and sub are tags and should be avoided because the presentation should be in the CSS. However, there is no immediate CSS property for superscript and subscript. Here is a solution using the relative value of the position property. Let's take fractions as an example and assume I want to write 3/17. I will use classes fnum and fden for the fraction numerator and denominator respectively.

The first step is to make the text smaller, 70% should be fine. Then we need to offset it vertically. The best way to do this is to use position:relative. For the superscript, it's easy, just push it up from the bottom by 0.5em. For the subscript it is a bit more difficult. Using the top property has no effect so instead we are going to use a negative bottom property to push it down. Here is the resulting code:

.fnum {
  font-size:70%;
  position:relative;
  bottom: 0.5em;
}
.fden {
  font-size:70%;
  position:relative;
  bottom:-0.5em;
}

This works but looks weird for the denominator because, in a fraction, the forward slash (/) character between the numerator and denominator leaves a lot of white space in front of the denominator. The solution for this is to slightly shift the left margin of the denominator: margin-left:-0.2em. Why not use the fact that we are using a relative position and add left:-0.2em instead? This is because the left property shifts the content of the display box but not the box itself and it would leave a gap on the right of the denominator. The margin-left property will shift the whole box and modify the right margin as well. Of course, none of this applies for a standard subscript such as the one used in chemical fomulae like C2H5OH. That's one more reason to use semantic HTML and CSS: you can adjust the display of each individual element depending on their meaning so that they look good in context.

Update

Following the comments below, here's a simpler solution to achieve the same thing courtesy of squidoography.com:

.fnum {
  font-size:70%;
  vertical-align: super;
}
.fden {
  font-size:70%;
  vertical-align: sub;
  margin-left:-0.1em;
}
.atomnum {
  font-size:70%;
  vertical-align: sub;
}

I also agree that in an ideal world we would use MathML to display mathematical formulae but a number of major browsers (this one in particular) don't support MathML so for web documents, we have to do with HTML and CSS.

6 comments:

Anonymous said...

Just a minor quibble here: sup and sub are not presentational tags. Although they alter the presentation they also give extra meaning to their contents.

If what you are writing should actually be in a superscript or subscript then that's exactly what you should do.

For fractions, it might just be best to use MathML than to force CSS into rendering them properly.

Anonymous said...

An annoying and ungainly solution. Playing with vertical-align=super also works. I'm all for using sup tags however since they add meaning besides the look like Mr. Anonymous said.

Anonymous said...

Wonderful, this did do the trick for me!
Thank you.

C├ęcile

Bruno said...

To reply to the comments above, whether sup and sub are presentational tags is debatable but I tend to think that they are because sub-script and super-script themselves, when used in writing, are presentational ways to convey a particular meaning. For instance, the letter x followed by a super-script 2 means "x squared" in a mathematical formula but not necessarily so in other contexts.

You are also right that the ideal solution would be to use MathML. However, MathML is not supported by all browsers so until that is the case, we are stuck with plain HTML and CSS.

Finally, vertical-align=super or vertical-align=sub rather than the relative positioning would indeed be a better solution. The two CSS rules can then be re-written thus:

.fnum {
font-size:70%;
vertical-align: super;
}
.fden {
font-size:70%;
vertical-align: sub;
margin-left:-0.1em;
}

Ann said...

Just wanted to confirm that as of XHTML2, these are still valid content tags for math, chemistry, footnotes, etc. So as much as I otherwise love HTML Dog, he's got this one wrong (really wish there was a contact/comment option on the site).
http://www.w3.org/TR/xhtml2/mod-text.html#edef_text_sup

In general, I've been surprised at what I'm finding in my search. Sure, the default look may need work, but it's interesting how many designers default to class styles instead of tag mods which preserve the content accessibility. Or who don't register there's any to preserve--HTML Dog's oft-quoted authority regardless ;-)

Anonymous said...

I always get confused using with the sup and sub.

web design company