Brace(s) yourself
I recently read Why would you do that? on CSS Tricks and it reminded me that I had meant to write this piece a month ago.
So I recently wrote about a fragment of mathematical content and a big part of it was the problem of stretchy braces. After building the "plain" HTML+CSS example at the end (re-using an extremely clever solution from the upcoming MathJax v3), I kept thinking: this should be easier. Luckily, this year I'm dedicating a chunk of my spare time to the MathOnWeb Community Group's new task force focused on CSS, looking for (old and new) ideas that might help simplify equation layout using CSS.
So one thing led to another and I found myself coming back to an old thought of mine.
What's in a name?
Stretchy characters like those braces, what are they really? Like, really really?
Let's look at what they are called. As a matter of fact, they are called various things but the most generic term is possibly bracket. However in the context of equation layout, the more common terminology might be delimiter and fence. In particular, MathML provides an <mfenced>
tag (though for various reasons the equivalent <mrow>
+<mo>
constructions tend to be preferred by most tools).
Now both brackets, fences and delimiters sound awfully similar to a very common concept. Where do you usually put up a fence? Where do you delimit something? At a border. It's a small idea, obviously, but what if we could solve the problem of stretchy constructions using borders?
What if somebody else already has?
Previous Art
Well, you could go visit codepen and simply search for brace and, lo and behold, you find 4 perfectly fine specimens in CSS. Turns out, designers love pretty things, who'd have thunk.
If you dig a little deeper, you'll end up with basically three approaches.
The first one (with several interesting forks) is by Lauren Herda.
See the Pen Single-Element Curly Brace by Lauren Herda (@lrenhrda) on CodePen.
It is really pretty -- look Ma, a single div! (Except that it doesn't quite work on Chrome since an <hr>
gets overflow:hidden
from the user agent style sheet.)
That was fun. Let's do two more: one from Jakob Christoffersen
See the Pen curly braces css by Jakob Christoffersen (@MasterThrasher) on CodePen.
and one from @mexn:
See the Pen CSS Curly Brace by Markus (@mexn) on CodePen.
Both are slighly more complicated than the first one. Instead of the radial gradient for the middle piece, they both use 6 elements with border-radius (though the last one has only two elements with pseudo-elements). If you dive into their forks, you'll find lots of interesting variations, too.
The point is: this problem has in a very real sense actually been solved in CSS and you can do lots of fun variations yourself.
Such as this one
See the Pen stretchy brace by Peter Krautzberger (@pkra) on CodePen.
or this one
See the Pen stretchy brace, single-div by Peter Krautzberger (@pkra) on CodePen.
(Fun fact: using percentages in the border radius leads to some really cute behavior across sizes.)
Objection!
Now you might say it hasn't solved the real problem. Here are a couple of counterarguments:
It has no character! Gasp! It's true that in typical print equation layout engines you'll still have a character there. Well, you could just add a hidden one, no?
It doesn't work well on small sizes! In typical print equation layout, you'll see several sizes of a brace being used for smaller heights (with possibly slight design variations for readability) after which the layout would switch over to a stretchy constructions (made up of several glyphs stitched together). This is a very interesting problem to solve. And you know what? This touches on one of the hottest topics of CSS discussions in the past few years: it is a perfect use case for container queries. Go add a use case and push the web forward for everyone!
But perhaps current CSS is sufficient and someone will find a clever approach to achieve a similar effect. As I mentioned above, percentages in border radius have a neat effect; there is a lot of room to play with once you stop thinking about everything in terms of print traditions.
It's not semantic! Gosh. What exactly does a (stretched) brace represent, semantically speaking? And, should you have decided to imbue it with such rich meaning yourself, are you really unable to expose the relevant information using the web platform's rich accessibility stack? No? Excellent - you should file a bug with ARIA and help push the web forward for everyone!
It can't look like font x! Some fonts have a really tricky curly brace with basically an S shape in each half. I admit my CSS-foo is not good enough to do that. But besides the fact that a better designer might find a solution, I find the trade-off acceptable. And if there's a limitation in CSS, please file a bug with the CSS WG and help push the web forward for everyone!
It can't do delimiter y! There are quite a few brackets, some more complex than others (Mathematical left white tortoise shell bracket anyone?) but few of those are used in stretchy ways and fewer still occur often (for comparison, the STIX-2 fonts support ~30 delimiters). I really don't have a problem with such edge cases remaining difficult for the time being if we can solve a practical problem for 99% of use cases. And if you do, ... you know what to do.
Moar fences!
So let's do two more, the most important ones:
Parentheses,
See the Pen Stretchy parenthesis by Peter Krautzberger (@pkra) on CodePen.
and square brackets
See the Pen Stretchy brackets by Peter Krautzberger (@pkra) on CodePen.
See now, that wasn't so hard?
Coda
I suspect that if we work a bit harder to unstuck ourselves from the traditions of (print) equation layout engines, then we might just find a lot of interesting solutions like this; solutions that help make equation layout on the web as easy as as designing a good page layout with CSS; solutions that work with the grain of the web; solutions that perhaps even lack but help identify (and resolve) shortcomings in the web platform that affect a much wider community; solutions that help move the web forward.
PS: I've started a little collection on codepen. Ping me if you see something that might fit!