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 approaches to it that have been developed are:
<pre>
tags.
The official, ultimate solution is MathML. As of this writing, it should be a mature product, but it has suffered setbacks, and is supported by only one major browser, Firefox. 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. (Of course, there are already programs that automated the generation of MathML code.)
This is an investigation of solutions for formatting 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 avoiding them.
Most of these marks have Unicode composing character equivalents.
If you must have fancy characters such as h-bar, you might consider using the Unicode character ħ for it.
Previously, this web page has preferred using ISO-8859-15 characters and the HTML 4 standard character entities. Since 2010 however, all major web browsers on desktop computers support the Unicode encoding standard (and all browsers on smartphones do).
One alternative to using Unicode is
SGML
character entities. These are names for characters in HTML code.
They are always placed
between an ampersand (&
) and a semicolon (;
).
One conceivable reason for using these nowadays would be that you somehow are pressed for time to look up the Unicode character. Or somehow you are working in some archaic environment that doesn’t support Unicode.
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:
◊ ♠ ♣ ♥ ♦
Some old 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.
The Unicode encoding specifies hundreds of math and technical symbols, The only question is, do fonts on the viewer’s system contain graphical representations for these characters? For example, there is the beautiful Unicode character range 8704–8959.
It is crucial to specify the character encoding at the beginning of the HTML file. The exact syntax for doing this has changed over time, and depends on the specific version of HTML (or XHTML) that you are using.
In HTML 4 and previous, the most portable approach was to place this tag:
in the <head>
block. In the more modern standards
XHTML and HTML 5, Unicode is the default encoding. But in XHTML 1.1 the
encoding was specified by the first line of the file, introducing it as
an XML document:
Perhaps the most attractive option is the HTML 5 standard, in which the
encoding is specified by this line directly after the <head>
tag:
There are many means of putting Unicode characters directly into a text document. This way, you can see a representation of the letter directly in the text.
It is also possible to 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).
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 was very quirky, and seems to be simply missing features that one would want.
Finally, the CSS3 standard provides a set of positioning features, well enough described to display mathematics.
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.
Fractions written with the horizontal divider are in any medium difficult to fit in-line with text, so are usually displayed separately. In the examples below, however, I both display them separately and put some text around them to indicate the position of the baseline, to see if the technique used could be applied for in-line expressions.
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).
Here we use CSS
inline-table
for browsers that have it, and
inline
for browsers that don’t
Aa0qp |
b2 |
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.
While this approach is attractive in that it doesn’t use tables, the absolute positioning unfortunately rules out automatic allocation of space for the fraction’s contents: to leave proper vertical space, it must be tailored to fit the contents.
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 in-line 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 (now supported by
most browsers) for the display
property of the outermost element.
The code is very clean, and centers everything nicely.
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 legibility 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. Tables may sometimes be necessary in more complex expressions.
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 behavior:
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 |
Tables can be used 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 I couldn’t control the 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.
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 browsers don’t agree as to the handling of vertical
placement of inline tables…
∑ i |
It is possible to perform elaborate decoration of characters with modern SVG vector graphics. This is especially nice for stretching a glyph, as in
abc |
There are several good candidates for wide accents. Besides the ASCII caron ^ and tilde ~ and the iso-8859-1 macron ¯ there are ⎴ ⎵ ⏜ ⏝ ⏞ ⏟ ⏠ ⏡
abc |
One down-side is that, for mathematics, positioning and shaping is very font-specific.
HTML tables are ideal for placing matrix elements, but the traditional brackets around matrices are a problem.
It’s not beautiful, but a fair 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 | | |
Unicode defines some extensible character pieces that can be used, provided fonts are available that support them. Pieces are provided for square brackets, parentheses, and curly brackets. There are also parts for The application with HTML/CSS is tricky though. The approach taken here is to position the character pieces with CSS within a single long table cell. For this to look good, there must be no vertical spacing between the pieces.
⎡ ⎢ ⎢ ⎣ |
a | b | c | ⎤ ⎥ ⎥ ⎦ |
d | e | f | ||
g | h | i |
CSS box borders may be employed to make very pretty brackets, but they are displayed only in browsers that support CSS.
|
Likewise, a matrix norm:
|
but braces and parentheses are beyond this approach.
The SVG standard now common in modern browsers, and could probably be employed in more than one way to make brackets as well as other enclosing symbols. Some hurdles include: simply stretching a glyph tends to distort the glyph, and that it is difficult within the web page to know the physical height of the thing being bracketed. One advantage is that in this approach, the bracket characters appear in the HTML code.
|
Table frames have been dropped from the HTML 5 standard, perhaps with the idea that frames are in most cases a matter of presentation rather than content. Of course, it’s easy to imagine tables where important information is conveyed by borders and lines. Ah well, principles are hard to stick to. I personally liked frames because they work in text-only browsers.
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.
I take the principle of separation of presentation and content to be an important principle and a practical necessity. Yet here we're faced with a dilemma.
With the demise of table frames and rules, the only way to draw a horizontal
line is with an <hr>
element, and there is no option
whatever for drawing a vertical line.
On the other hand, MathML was explicitly designed to encode the meaning of mathematical expressions, rather than the typesetting. (In this sense, it is superior even to LaTeX, which never made this distinction.) But the grand solution of MathML is not ready for general use at this time.
So math needs to look reasonably right, but at the same time, the code should reflect the meaning. Is there any expedient that would satisfy both requirements?
I think it can be done, at least on an ad-hoc basis.
HTML class
attributes can be defined to describe the meaning of
the content of the tag to which they're applied. For instance,
a <div class="fract">
tag containing two further
tags <div class="numer">
and <div class="denom">
can serve both to
indicate CSS formatting and to make the meaning of the content very clear.
Furthermore, if consistently applied, the code could be automatically
converted to a standardized markup language such as MathML whenever it
becomes appropriate to do so.
So rather than on relying on a global standard for specifying the meaning of math expressions, one may consider specifying meaning locally.
FF | O | Sf | D | K | C | lk | lx | |
---|---|---|---|---|---|---|---|---|
SGML | P | P | P | P | P | P | G | B |
Unicode | P | P | P | P | P | P | G | B |
Fraction with table, hyphens | G | G | G | G | G | U | G | G |
Fraction with inline-table | P | P | B(c) | P | B(c) | P | G | B |
Fraction hybrid | P | P | P | P | P | P | B | R |
Fraction with inline-block | P | P | P | P | P | P | B | B |
Superscript subscript | P | P | G | G | P | P | R | R |
Sum with inline-block | P | P | G | G | G | P | B | B |
Integral with CSS | G | P | G | G | G | G | U(u) | R |
Integral with table | G | P | G | B(c) | G | P | R | U(t) |
Complex expression concatenated | G | G | B(c) | B(c) | B(c) | B(c) | B(u) | B(u) |
Complex expression with tables | G | G | G | G | G | U* | R(u) | B(ut) |
Matrix with vert. bar | G | G | G | G | G | G | G | G |
Matrix with CSS border | P | P | P | P | P | P | B | B |
Matrix with frame | P | P | P | P | P | P | R | B |
Matrix norm with frame | P | P | P | P | P | P | G | B |
Matrix with frame and CSS | P | P | P | P | P | P | R* | B |
Equation numbers | P | P | P | P | P | P | P | U(t) |
|
|
Browser | v | P | notes |
---|---|---|---|
FF | 2.0 | L | Some matrix borders gray.
I don’t understand the logic… Maybe fixed in 3.0. No support for CSS inline-block . Fixed in 3.0.
|
Opera | 9.6 | L |
Incorrect drawing of table rules 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). Greek entities are greatly improved -- perhaps due to improvements in the terminal emulator? |
lynx | 2.8rel4 | L |
Wrong handling of Greek entities No table rules. Tables generally poor. |
Konqueror | 4.1+ | L | SGML problems finally resolved. |
Chrome | 47+ | L | Doesn’t seem to support inline-table properly in complex expression. |
Support for CSS has greatly improved since 2010. Only vertical positioning remains an issue among browsers — but without much finer control than CSS can provide, that is, without font- and glyph-specific behavior, such positioning will remain crude.
So far, table frames and rules are supported by IE, Mozilla Firefox, 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 at some point.)
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.
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.
Opera doesn’t render at all lines with fractional CSS widths. This is wrong behavior. 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.
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 transliterate 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.
Outside text-only browsers, SVG are very commonly supported nowadays. SVG could be used to stretch letters such as parentheses, brackets and vertical bars, as well as perhaps integral signs.
As to the issue of presentation vs. content: in the case of merely scaling or stretching a letter, the letter remains as the content of the SVG markup. That is, if the SVG were entirely disabled, the character would still be there. The meaning of the SVG markup can be indicated by SVG tag attributes, just as with CSS.