4 ms·
Matthew Butterick, of typography and Racket fame, used a neat and/or slightly insane CSS hack for hanging punctuation in his online booklets, leading me to a ro
by ttepasse 3y ago
Matthew Butterick, of typography and Racket fame, used a neat and/or slightly insane CSS hack for hanging punctuation in his online booklets, leading me to a round of web-inspectoring some years back:
He programmed his site builder to insert two elements at the site of the punctuation:
<dquo-open-push></dquo-open-push> <dquo-open-pull> “That’s</dquo-open-pull>
and styles them with this CSS:
dquo-open-push { margin-right: 0.5em }
dquo-open-pull { margin-left: -0.5em }
E.g. the first elements pushes the following element further back, but the second element pulls itself back in that negative margin. The resulting effect is that in normal flow both the positive and negative margin of these cancel each other out, leading to quasi normal inline flow:
text text text text PUSH↔PULL text text
But if there is a line break between the elements the the push element pushes invisible into the right margin and the pull element pulls itself in the left margin, leading to hanging punctuation:
text text text text text text PUSH→
←PULL text text text text text text
So the trick with negative margin not only works at the beginning of block elements but inside the inline flow without leading to a negative experience - e.g. it also works with unpredictable line lengths.
An example is on this page: https://practicaltypography.com/are-two-spaces-better-than-one.html#the-role-of-research https://practicaltypography.com/are-two-spaces-better-than-o...
I really like the going of the extra mile, although now with `hanging-punctuation` it is unnecessary.
Note: Butterick programmed his own site builder - Pollen - and designs his own fonts - that makes such customisability more achievable, I assume. Not the biggest fan of using custom elements instead of span but modern HTML and web components makes this syntax valid.
- lwhi 3y agoCall me old fashioned, but contaminating the markup like this—for something that's aesthetic—is a no no.
- Retr0id 3y agoWhy is it a no no? My personal rule of thumb is that as long as Reader Mode can render it fine (which implies coherent semantics), then the markup can do whatever it likes.
- globular-toast 3y agoBecause users should be able to make their own stylesheets and having a bunch of stuff in there that isn't relevant is annoying.
- deleted 3y ago[deleted]
- immibis 3y agoHas anyone ever done this?
- Retr0id 3y agoYes, it's a whole thing, e.g. https://userstyles.world/ https://userstyles.world/ But, I don't think those `dquo-open-*` tags would get in the way at all.
- OJFord 3y agoYes, the users of Stylish, Stylus, usercss.com, TamperMonkey, GreaseMonkey, ... It's definitely not a 'regular user' thing, but I'm fairly sure it's more common than things like 'r/unixporn', or theming Linux to look like Windows XP or macOS, that are themselves quite large niches.
- velcrovan 3y agoImagine there was a hobby that was as marginal to ham radio operators as ham radio is to the rest of the population. That is about how relevant user stylesheets are.
- globular-toast 3y agoI think simple changes like changing fonts etc would be more popular if people knew they could. But it's not made easy nor is it generally effective on badly designed websites (most of them).
- nlitened 3y agoWhen I hear “old fashioned”, I imagine <table> layouts, transparent pixel gifs, and <marquee>.
- lwhi 3y agoTo me, old fashioned means sticking to semantic principles and separation of concerns. (P.S. get off my lawn)
- reddalo 3y agoI can only imagine what you think of TailwindCSS so...
- lwhi 3y agoCounterintuitively, I'm okay with it .. but just because it solves problems I see as more important than purity in the codebase. Large FE projects often have multiple developers, which come and go .. and have differing levels of ability. Tailwind provides a framework that's easy to jump into, provides consistency and is widely known. -- However, that doesn't mean I can't think this particular technique isn't a good idea.
- madeofpalk 3y agoWhat markup? If it's generated, does it matter?
- lakpan 3y agoAre we looking at the same page? Where’s the contamination? It’s pure CSS applied to a basic `blockquote` element. There are no spans and no divs.
- svat 3y agoThis is pretty much the typical way things are done in TeX: having glue or penalties that “cancel out” in the usual case but do the right thing when line breaks are involved. Unlike CSS that has lots of special cases and keeps adding more, TeX has a very simple algorithm for breaking paragraphs into lines, but the box-glue-penalty model is general enough that a lot of things can be achieved with it. (I like the way these are explained in the paper by Knuth and Plass; see e.g. https://tex.stackexchange.com/a/469908 https://tex.stackexchange.com/a/469908 and https://tex.stackexchange.com/a/423578 https://tex.stackexchange.com/a/423578 .)
- notpushkin 3y agoI think I've seen it on quite a few sites. It would be nicer if you could do a ::before and maybe also specify pull width to be the width of a quotation mark: dquo-pull::before { margin-right: -made-up-string-width(“); } dquo-pull { margin-left: calc(-1 * -made-up-string-width(“)); } She said: <dquo-pull>“That’s</dquo-pull> (I think you can do something like that with container query units [1], but I haven't managed to do it just yet.) UPD: container query wouldn't work here because if you set `container-type: inline-size` on dquo-pull, it will get inline size set to zero, as if it had no content [2]. [1]: https://developer.mozilla.org/en-US/docs/Web/CSS/length#container_query_length_units https://developer.mozilla.org/en-US/docs/Web/CSS/length#cont... [2]: https://drafts.csswg.org/css-contain-3/#containment-inline-size https://drafts.csswg.org/css-contain-3/#containment-inline-s... > although now with `hanging-punctuation` it is unnecessary `hanging-punctuation` only works at the start of the block element though. Maybe that'll change in the future though!
- ttepasse 3y agoIf I remember correctly, pseudo-elements act as they are children of their "parent" element, e.g. <dquo-pull><::before></::before>... </dquo-pull> In that case the ::before element doesn't linebreak independently from its "parent" element and so those two elements are always together, even at a break before the start of a new line.
- notpushkin 3y agoYou could set `display: contents` on the outer element – this will put ::before in the parent flow instead. But then the quote mark becomes a text node and you can't pull that back without another wrapper element: And then she said: <char-hang><span>“</span></char-hang>Hello, handsome! What a day, huh? which will be rendered like this: "And then she said: " <!-- push: --> <char-hang::before /> <!-- pull: --> <span>“</span> "Hello, handsome! What a day, huh?" Without adding another element, you can use a hack though: make the quote mark transparent and use text-shadow to “move” it back instead: https://jsfiddle.net/utjxnv1r/3/ https://jsfiddle.net/utjxnv1r/3/ And if we allow JS, we can just create a custom element and avoid those hacks altogether (also you don't have to calculate / eyeball the offset you need anymore): https://jsfiddle.net/c72uLtma/ https://jsfiddle.net/c72uLtma/
- giraffe_lady 3y agoPollen is really impressive, for programmers it's probably the most accessible way to get professional quality typesetting for web and small documents. I use it for my resume, contracts, flyers, anything intended to printed out. It's missing some tools you'd need for full printed & bound books but it can cover pretty much everything else. Learning curve is acceptable if you know css well and lisp somewhat. Might be a struggle if not but still more flexible for a beginner than luatex I think.
- gwern 3y agoThat sounds cute but potentially expensive: a span for every single double-quote in the page! I know Butterick's pages are short and don't usually feature lots of quotations or bibliographies like mine, but still.