This document can be viewed properly only in modern browsers with good support for CSS2 and the full HTML character set.
Mathematical formatting is hard.
There hasn’t been very good support for math on the Web. Some of the solutions are:
<pre> tags.
The official, ultimate solution is MathML. As of this writing, it is just starting to be supported to some degree by two of the major browsers. MathML is not a lightweight solution though. It is easy to generate automatically, but hard to type by hand (as opposed to LATEX). If you want just a single formula in a web page, the difficulties of using MathML might not seem worth the effort of learning it.
This is an investigation of solutions for formating math in standard HTML, enhanced by the widely-supported formatting language CSS. I have striven for
In contrast to the graphics approaches, this has the added benefits that the text
A practical principle of contemporary web design is “separate presentation from content”. It means to put the information in one place, and describe how to present it in another. This is opposed to, for example, explicitly setting the font of each word of text explicitly in the HTML code.
The most common means of describing presentation is the style language CSS. With it, you can specify the presentation of a certain kind of HTML entity in a separate document, or at the top of the page of HTML code.
For our purposes, this rendition of “separate presentation from content” is useful: Use standard characters and HTML to produce content, use CSS to beautify it.
It is convenient to define a CSS class selector .math. With
this, any text contained in an element of class math can be
specially formatted. For single-letter symbols, it’s convenient to use
the selector i.mi, which will cause the symbol to be rendered
in italics in older, non-CSS browsers, but leave the HTML tag
<i> free to indicate generic italics.
For example, x, y, z are single math symbols in text, and
is a math formula set off for display.
Using CSS positioning, decorated characters, such as
can be constructed, but won’t look good in most browsers. They are also font-dependent. I recommend that you avoid them.
Mathematics, being a very flexible language, can do without most of these fancy symbols, but quantum mechanics, without h-bar, is even more uncertain.
It’s best to stick to ISO-8859-15 characters, and the HTML 4 standard character entities. A character in bold face is representable on most browsers, too. If you really must have fancy characters such as h-bar, you might consider using Unicode. Unicode is fairly universal on computer systems since 2004 or so, but is often poorly implemented on older computer systems.
Most modern browsers support characters in the ISO-8859-15 character set. To ensure that the browser knows the character encoding of the page, place the line
in the head section of the HTML document.
Besides European characters (à, å, ç, etc) there are a few math symbols: ·, ×, ÷, ¬, ±. and financial symbols: ¥, £. Note: do not rely on any of the “superscript” or “fraction” symbols from ISO-8859-1, nor the “broken vertical bar” or “currency”; they are replaced in ISO-8859-15.
The only advantage of using these is that you see the characters directly in your HTML code. All these characters are also SGML character entities: see below.
The real strength of character encodings is the ability to display text in one or more languages.
A much better and ultimately more portable solution is to use
SGML
character entities. These are names for characters in HTML code.
They are always placed
between an ampersand (&) and a semicolon (;).
The
HTML 4 standard
includes most of the Greek alphabet:
α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ ς τ υ φ χ ψ ω Α Β Γ Δ Ε Ζ Η Θ Ι Κ Λ Μ Ν Ξ Ο Π Ρ Σ Τ Υ Φ Χ Ψ Ω ϑ ϒ ϖ
a fairly rich selection of math symbols:
∀ ∴ ∃ ¬ ∋ ∅ ∈ ∉ ∧ ∨ ∩ ∪ ∂ ∇ ∏ ∑ ∫ √ − ∗ × ÷ ⋅ ± ⊕ ⊗ ∝ ∞ ∼ ≅ ≈ ≠ ≡ ≤ ≥ ⊂ ⊃ ⊄ ⊆ ⊇ ∠ ⊥
arrows:
← ↑ → ↓ ↔ ↵ ⇐ ⇒ ⇓ ⇔
fancier brackets:
⌈ ⌉ ⌊ ⌋ 〈 〉
a few fancy script letters:
ℵ ℘ ℑ ℜ µ
and these:
◊ ♠ ♣ ♥ ♦
Most browsers will display a textual version of the entity if they can’t display a glyph for it, so that the text is still readable.
Note: Up through version 6, Microsoft Internet Explorer (MSIE) has been one of the least compliant browsers with regard to SGML Math Entities. Even entities corresponding to glyphs in character encodings that it displays correctly, it failed to display.
With MSIE 7.0 beta, things look much better. Only 5 entities are not displayed correctly (MS has been notified of these.)
In browsers that support the UTF-8 encoding, you can use the many beautiful
characters in the Unicode range 8704 - 8959. You’ll need to specify the
character encoding in the <head> block of your page:
Then specify the character you want using a hexadecimal numerical character
reference. For example, the Unicode numerical character
reference ∬ is a nice double integral sign.
There is also a h-bar defined in Unicode (u+0127).
Besides a browser that supports UTF-8, the user’s system has to have Unicode fonts available that contain the required glyphs.
HTML tables can be used to do much of the positioning required by math, but the code required to do this can be very cumbersome, so that the bulk of the code is about arranging the formula as a table, rather than about the formula and its parts. (Moreover, some browsers don’t even support tables).
In CSS2 came a technology that we had hoped would allow us to do very flexible positioning with simple HTML. It doesn’t always work that way. CSS positioning is very quirky, and seems to be simply missing features that one would want. However, as of this writing, most graphical browsers have fair support for it.
The main CSS1 positioning properties are
vertical-align
text-align
CSS2 adds
position
top bottom left right
It probably isn’t a good idea to mix the CSS1 properties with the position property within the same element.
The main trick with CSS2 positioning is this: absolute positioning is
relative to its innermost positioned ancestor element (or the body element,
if no nearer one exists). So one normally creates an element with
position: relative, then within that element, other elements
with position: absolute. These inner elements can be placed
rather precisely, in principle.
A weakness in this scheme is that, although one can position precisely, there is no well-defined way to center positioned elements relative to one another, unless their sizes are known beforehand. So for example, one can use it to place an element above and below another element, but then there is no way to say to center the elements horizontally. One might think that, by simply not specifying the horizontal position of an absolutely-positioned elements, the positioning would somehow be governed by the CSS1 text-align property. Well, some browsers implement this, and others don’t.
The absence of standard fractions in HTML is a tragedy. Fractions are used
by so many people, from auto mechanics to cooks, but there’s no nice way to
write “A over B” in HTML. Even more
tragic: there was a frac tag for this purpose in the HTML 3.0
standard, but it was dropped in HTML 3.2.
The most portable fraction is made using a table with three rows, the middle one being the dividing line made of hyphens:
| Aa0qp |
| --------- |
| b2 |
This is readable even in text browsers, so long as they support tables. But sometimes the hyphens don’t connect and you get a dotted line, and also, it’s hard to guess how many hyphens to use (they have slightly different lengths in different fonts).
One neat way to make a fraction is to use CSS box border properties with a table; unfortunately most browsers, particularly text browsers, don’t support border properties. Also, it’s another trick to align the whole fraction vertically:
| Aa0qp |
| b2 |
HTML 4 has the frame and rules attributes, which
in principle should make a line that displays in non-CSS browsers.
Unfortunately, many browsers don’t support them.
| Aa0qp |
| b2 |
rules quite
nicely.)
This hybrid uses just div and span with line breaks,
with a divider element that contains dashes for non-CSS browsers but
uses border instead for CSS browsers.
This is all fine for separate display of fractions, but to display them inline properly is much harder. None will work without revision.
One would think the coolest would be to use CSS positioning to make a fraction. There are several difficulties: The first is: if all the elements are absolutely positioned, they lose their natural widths. One could set the width of the containing element explicitly, or pick the widest of the numerator and denominator, and make that one non-positioned, or possibly include a string of non-breaking spaces to force the width. A related problem is the horizontal centering of the items. But all of these measures are messy, artificial, and concern more a weakness in CSS than the typesetting problem.
If the numerator and denominator are block elements (or are separated by line breaks), there are HTML ways to center them horizontally, but then putting them inline becomes a problem. If they aren’t block elements, they can be positioned vertically with CSS, but I don’t know how to arrange for horizontal centering.
In an example below, I pick the numerator to be statically positioned to give the fraction a width. It’s picky (depends on whether the numerator or denominator is the longer) but it seems the least intrusive of the methods.
This example uses the inline-block value for the
display property of the outermost element. The code is very
clean, and centers everything nicely. Firefox doesn’t
currently support it though.
HTML has always had built-in support for superscripts and subscripts, so most browsers support them to some degree.
This is a place where a little CSS can make all the difference, aesthetically. The trick is the right balance of font size and vertical offset. For legibilty on a computer screen, the minimum font size is about 7 points (7 points). In printed math texts, much smaller fonts are sometimes used. On the other hand, most browsers make it easy for the user to increase the font size…maybe this is a non-issue.
To put the superscript and subscript directly over one another, there are
a couple of approaches. You can try CSS positioning,
but there are various technical questions. A position of
absolute allows you to place an element where you like
relative to the containing (relatively-positioned) element, but leaves
no space on the line for the contents. A position of
relative leaves space on the line where the element
was. So if you know which of the sub- or superscript is longer
horizontally, you can position that one relatively (to leave space for
it), and position the other absolutely:
Another approach is to use tables.
A very nice integral can be assembled using the SGML entity
∫ and some CSS.
There are three popular typesetting forms for integrals and sums, differing in the placement of limits relative to the integral or sum symbol. In display form, limits are centered over and under the symbol. In inline form, limits are placed as super- and subscripts to the symbol. In compact form, limits are placed to the right of the symbol, and given enough vertical spacing so that they may flow around an integrand.
Here is a compact form using sup and sub, with
CSS to permit the flowing behaviour:
This displays well in text browsers, so long as they have a way of
displaying <sup> and <sub>.
Here tables align an integral to achieve traditional typographic “compact” form, wherein the upper and lower limits flow around an integrand.
| ∫ | 1 | |
| f( x ) dx | ||
| 0 | ||
One can use tables to align everything. A text baseline can be maintained within a line of cells. Indeed, for very complex formulas displayed out of text, this may be the best solution. However, the problem of aligning that baseline with the text baseline surrounding the table seems unsurmountable, so this technique is usually unusable for inline math. In displayed math too: once you start aligning with a table baseline, everything has to go into the table. Furthermore, to typeset a complex formula using tables can require very cumbersome HTML. Then again, very complicated formulas aligned by tables can be rendered impressively well in a text browser.
|
xn |
The pure CSS solution is to separately vertically align the summation symbol and limits: the main problem here is the horizontal centering of the limits on the symbol. I know of no resolution. (Is it possible with CSS to achieve horizontal centering of inline items of indeterminate width without making use of a block item?)
A hybrid approach is perhaps best: use a table to align the limits to the
symbol horizontally, then use CSS to adjust the position of the symbol
relative to the baseline (which is less critical than keeping the baseline
straight). The display property of the table is
then set to inline so that it doesn’t break the line it’s in.
(This works for browsers that handle this CSS property correctly; that
includes most modern browsers.)
(Why a table again, rather than a div? because couldn’t control width of the div. Why not?)
| ∞ ∑ n=0 |
Here’s an element using the CSS 2.1 inline-block value of
display.
This way, a positioned expression can be placed in a line, without forcing
a line break in browsers that don’t know CSS.
Opera and Konqueror support this; Firefox does not,
but may soon.
IE7 supports it
buggily.
Maybe the way of the future:
Complex expressions can be formed by simply concatenating such constructions,
but then the integrands won’t share the same baseline.
Expressions that are made using HTML tables will normally appear on a new
line because a table is a “block” element: to stop this behavior, use CSS
to set its display property to inline.
Unfortunately, the broswers don’t agree as to the handling of vertical
placement of inline tables…
| ∑ i |
HTML tables are ideal for placing matrix elements, but the traditional brackets around matrices are a problem.
It’s not beautiful, but a fairly good work-around is to use the vertical bar character, if you’re not concerned with the distinction between the usual enclosing square brackets and simple horizontal lines. This matrix is readable in any browser that supports tables:
| | | a | b | | |
| | | | | ||
| | | -b | a | | |
You can use CSS box borders to make very pretty brackets, but they are displayed only in browsers that support CSS.
|
HTML 4 tables have a frame attribute, which can be set to
vsides to produce vertical bars, so in principle this could
be a way to make brackets that are beautiful in CSS browsers and readable
in non-CSS browsers. Many browsers don’t support this, though.
|
|
|
|
Here is a hybrid, using table frames to make vertical lines, and CSS to make brackety-looking things in the better browsers.
|
How about a norm?
|
|
|
|
There is more than one way to write a square root in mathematics. One can always resort to a fractional superscript using HTML. If one really wants a traditional radical, this is also possible in HTML, using CSS, but it has limitations.
In case the browser doesn’t have CSS, the overbar that binds the arguments of the root is lost. For this reason, it is safer to parenthesize the arguments.
But the worst problem comes from the fonts themselves. There seems to be no agreement as to how the radical sign will connect with a horizontal line. (You would think that it would simply extend to the height of the font, but no. In some fonts, it extends beyond the font height, but in others, it doesn’t reach the font height. But I think I have seen glitches of this kind in printed text, as well.)
Equation numbers are pretty easy to achieve by wrapping an expression in
the middle cell of a table of width 100%, and putting the equation
number in the rightmost cell with text-align set to
right. (To make the right-alignment function in Links, you
have to use the deprecated align attribute of
<td>.
|
10.1 |
text-align, text-indent,
vertical-align, display,
white-space, list-style, border,
direction
hr element. Especially, standardize
what the size attribute means, and at least mention how
CSS controls it.
frame and rules
attributes. It needs to be made clear how CSS interacts
with the rendering of frames and rules.
| FF/M7 | IE7 | O | Sf | iC | K | A | lk | lx | |
|---|---|---|---|---|---|---|---|---|---|
| SGML | P | G | P | P | B | B | G | B | B |
| Unicode | P | P | P | P | P | P | B | B | |
| Fraction with table, dash | G | U | G | G | U | U | G | G | R |
| Fraction with rules | P | U | B | B | G | U | U | P | B |
| Fraction with CSS | P | P | P | P | P | P | G | B | B |
| Fraction with CSS positioning | G | G | G | G | G | G | B | B | B |
| Superscript subscript | P | G | P | G | G | P | B | R | R |
| Sum with inline-block | B | B | P | G | B | P | B | B | B |
| Integral with CSS | G | G* | P | G | U | G | B(cs) | U(u) | R |
| Integral with table | G | G | P | G | G | G | U(c) | R | U(t) |
| Complex expression concatenated | G | G | G | B(c) | B(c) | B(c) | U(s) | B(u) | B(u) |
| Complex expression with tables | G | G | G | G | U(s) | U(c) | U* | R(u) | B(ut) |
| Matrix with vert. bar | G | G | G | G | G | G | G | G | G |
| Matrix with CSS border | P | P | P | P | G | P | P | B | B |
| Matrix with frame | P | U | P | B | U | B | U | B | |
| Matrix norm with frame | P | U | P | P | U | P | G | B | |
| Matrix with frame and CSS | P | U | P | P | U | P | R* | B | |
| Equation numbers | P | P | P | P | G | P | B | P | U(t) |
|
|
| Browser | v | P | notes |
|---|---|---|---|
| FF | 2.0 | L | Some matrix borders gray. I don’t understand the logic… |
| FF | 1.5 | L | Matrix borders blotchy. Fixed in 1.5.04 |
| NS | 7 | W | hr in fraction is gray |
| IE | 6 | W | hr in fraction is gray,
thin solid black border of matrix table is several pix wide.
Better to use 1pt rather than thin.
|
| IE | 7 | W | hr in fraction is gray.
|
| Opera | 9.0 | L |
Math SGML chars take too much horiz. room.
(6.1 vastly improved; fixed in 8.51) Wrong positioning of table elements whose “block” attribute has been turned off in CSS. (fixed in 9.0) |
| Elinks | 0.10.4 | L |
Very impressive implementation of table frames and rules.
Issue with choice of frame logic (see below). Wrong handling of Greek entities |
| lynx | 2.8rel1 | L | Wrong handling of Greek entities |
| Amaya | 9.51 |
Sup/subscripts — CSS positioning way out of whack.
maybe interprets completely wrongly Complex expression w/table: integral sign way too high? Fails to center tables correctly even when they have margin: auto are in a div
with text-align: center.Ver. 9 actually got worse than previous versions in the equation numbering category. | |
| Konqueror | 3.5+ | L |
Improved SGML, but most math symbols are still missing.
(Bug was reported years ago—they blame it on Qt.) |
So far, table frames and rules are supported by
IE, Mozilla/Firefox/Netscape, Opera, Safari, and Elinks.
Konqueror tries, but doesn’t get it right. Both Opera and Safari draw
rules where they should not. (Opera started doing this recently.)
Frame logic in Mozilla, MSIE, and Elinks is different. Both MSIE and Elinks
treat frame and rules as an enhancement to
an existing border attribute, while Mozilla treats them
as an override to border. So MSIE and Elinks show nothing
if border is absent, but frame are specified.
But even at that, MSIE puts rules on either side of each thing, rather
than between them, and Mozilla and Elinks do. Oh, dear. And
frame="lhs" puts a line at the left of each column, not just to
the left of the table.
Opera doesn’t render at all lines with fractional CSS widths. This is wrong behaviour. But many of the browsers have glitches in this regard. I think that implementing anti-aliasing to represent the fractional part of a line width is the solution.
Regarding integrals with CSS, and positioning in general:
it is disappointing but unsurprising that, among the major browser the
one most challenged by CSS position is IE7. It simply does the wrong
thing with the bottom property. This renders this property
useless for cross-browser typesetting. A work-around is to always use
the top property.
The control of table frames and rules, and of horizontal rule, using CSS is also muddled. The Mozilla browsers take the border properties as definitions of how to render frames and rules. Konqueror gives no (obvious) control of frame and rule presentation, and considers them to be independent of CSS borders.
Netscape seems to have dropped support for all operating systems other than Windows. Nobody really cares. So I drop support for them.
Links fails to display Unicode correctly even on a terminal that supports Unicode. For example, in a terminal that can display the h-bar Unicode character, Links displays a capital H. Curiously, Lynx will display correctly Unicode test, but if a Unicode character appears in a web page, it is also incorrectly rendered.
While most graphical browsers provide good support for most SGML entities on the screen, many fail to print them properly.
In most cases, display is better than printing. Mozilla doesn’t print all these characters correctly, at least on Linux. Lynx and links should have no problem, but they tranliterate Greek SGML characters to Latin! It’s an easy fix, and their maintainers have been contacted.
This is particularly pronounced in Linux/unix, where there has never been a unified printing interface. Firefox for Linux fails to print most SGML symbol characters, while Opera 9 is only missing a dozen or so.
There is a different printing interface for Mozilla called xprint that uses X Windows rather than PostScript to print. I couldn’t get it to work, but it is said to fix the problem.
Printing on Windows is better: Opera 7 prints SGML entities quite beautifully.
See also