On a sexier and perhaps better blog, this post title would be a euphemism.
Instead, this post is a bit of a follow up to an earlier post, so this second entry might as well mark the beginning of a series.
Itās time for Youāre doing it wrong!, the yearly column where I criticize peopleās blogās CSS even though Iām not an authority on that subject!
Letās talk about lines.
There arenāt that many HTML tags, and markdown only supports the small subset that are relevant to writers, so it makes sense to make use of them.
Hereās how you make a horizontal rule in markdown: * * *
. This becomes the following HTML:
Which typically comes across as a horizontal line, depending on the CSS, and typically is meant to mark a new section. On this blog, in a browser, at this time of writing, it looks like two thin lines on top of one another. The CSS I used for that looks like this:
hr {
padding: 0;
border: none;
border-top: medium double #333;
}
Edit: Actually, Iāve already changed it. The horizontal rules outside of the post body are still that, but the ones within post bodies are now stars as described below.
CSS is really flexible. You can even style an hr as an image. The blog post that Iām constantly googling for is this one by Marek Prokop which gives a great introduction to the different ways you can style hrs. Heres another, from which I more or less cribbed their last example.
Considering how good hrs are, I donāt understand why bloggers like Shawn Blanc and Stephen Hackett (whom I generally like), donāt use them.
They get the appeal of a nice separating line but instead of using an hr, which is easy to make with markdown, which I think they both use, they do this:
<div align="center">* * *</div>
or:
<p style="text-align:center">* * *</p>
Both commit the cardinal sin of embedding CSS in the middle of an HTML tag. Youāre not supposed to do that! Even if you donāt want to use an hr, the correct move would be to separate content and presentation by assigning a class and then selecting that class with the CSS, like so:
The HTML:
<div class="separator">* * *</div>
The CSS:
.separator {
align: center;
}
I assume they do it this way with the hope that it will be more portable. These days, people often read blog posts in their RSS reader or read later app, far out of reach of their blogās CSS. In these contexts, the post is subject to the reader appās CSS, and a div with a class will be treated as unstyled text, but a div with inline CSS might still be styled.
Sometimes.
If Iām reading a post outside of a browser, itās probably in Reeder or Instapaper (links unnecessary, right?). In Reeder, the rat tactic works and the stars are centered and more or less convey what the authors want them to. In Instapaper, the CSS is totally overridden and itās just a couple of asterisks. Same for Safari Reader, Readability, probably others.
Had they used an hr, each individual reader would style it as they see fit, but they would understand what it is and work to convey your meaning.
Besides, itās not that semantic is it?
Blancās p tag is most egregious in this regard, because p means paragraph, which this is not. It may have been chosen because the blogās CSS properties for paragraphs also applied to separators, but that does not make this a paragraph.
styling the hr with an image
Hereās the rub: as flexible as CSS is, I have no idea how to style an hr so that it looks the way these guys seem to want it to look without embedding a small image at every hr, which introduces its own set of problems.
- According to Prokop, an image hr has visual bugs in IE and Opera, so he resorts to a bit of a hack, namely wrapping the hr in a div with some additional rules, which is a bit of a nonstarter for markdown users ā we need something that automatically expands from
* * *
and looks right.
- Iāve tried this in the past and it looked kind of lo-res and not great on a retina display
I think these problems are surmountable by:
- just ignoring those browsers
- researching hi-res images and how to do it right (on my to do list)
So what would that look like?
The HTML:
The CSS:
hr {
height: 13px;
background: url(hr.png) no-repeat scroll center;
border: 0;
}
The image could be anything but hereās one I just whipped up in pixelmator with a transparent background to play nice with various sites. Keep in mind: the height property corresponds to the imageās height, so if you use a different image, adjust accordingly.
Edit: styling the hr with pseudo-elements
Edit 2: I love writing posts like this because I end up learning a lot. I especially love realizing how little I understood it at the beginning. Iāve removed the image-based-stars and replaced them with something different, something better.
Now no images are required at all! I realized while loading the dishes that I had cited an example earlier that used the :after
pseudo-element to insert a glyph into an hr, so why couldnāt we do the same with Hackett and Blancās beloved asterisks? We can! It looks like this:
The HTML:
The CSS:
hr {
padding: 0;
margin: 0;
border: none;
text-align: center;
color: black;
}
hr:after {
content: "* * *";
position: relative;
top: -0.5em;
}
This is a thinly-modified take on Harry Robertās Glyph style from that earlier link (example eight).
Isnāt that great! You can use a standard markdown (or HTML or anything) hr to make some centered asterisks show up automatically.
Of course I wanted to experiment and try inserting some other characters in there. This is my first experience with the :after
CSS rule and unsurprisingly itās a can of worms. I attempted to replace content: "* * *";
with content: "āæ";
, pasting the unicode black florette character directly into the CSS, and there were bonkers errors. The sass compiler just freaked out and killed the whole stylesheet. So, looking at this terriffic HTML entity reference, I went for the familiar-looking code decimal correspondent, ✿
, wearing those comfy ampersand-semicolon mittens (etsy, get on that). That totally didnāt work either so I ignored the third column and went googling. I came upon this great stack overflow answer which set me straight.
Now my CSS looks like this (and I promise to walk away and stop changing it for a day or two):
hr {
padding: 0;
margin: 0;
border: none;
text-align: center;
color: black;
}
hr:after {
content: "\273F\a0 \273F\a0 \273F";
position: relative;
top: -0.5em;
}
If youāre like me youāre like the fuck is that.
Thatās the third column I ignored, hex code! \273F
corresponds to that black florette and \a0
corresponds to a space. Isnāt that terrifically fussy?? You must pull out the hex number and add a leading \
as an escape to avoid errors.
Regarding using CSS to insert content into an hr, Chris Coyier writes:
Note that in some of these examples, generated content is used (:before/:after). This isnāt supposed to work, as far as I know, because <hr>s are no-content style elements (they have no closing tag). But as you can see, it does. If you are concerned about uber-long-term design fidelity, stay away from those.
To which I say: kewl bruh whatever tho.
Hereās an hr with this style:
This opens you up to use actual stars (or any other unicode character) instead of asterisks! I call that an upgrade. And if you turn CSS off or Instapaper it, it degrades nicely to a plain old horizontal rule, which isnāt really so bad. Itās good enough for John Gruber anyway. His horizontal rule looks like three pale centered dots.
His CSS:
hr {
height: 1px;
margin: 2em 1em 4em 0;
text-align: center;
border-color: #777;
border-width: 0;
border-style: dotted;
}
I donāt really understand how that becomes three pale dots but then I donāt really understand CSS.
Edit 3: I was wrong about instapaper
Completely wrong! I made some bad assumptions and now Iām really confused.
In the first draft of this post, I had this scattered throughout my paragraphs anywhere you see āhrā or āhrsā above:
<code><hr /></code>
Which is what my markdown processor, Kramdown, generates when I write this:
It wraps it in the code tags and replaces the angle brackets with their HTML entities, with the goal to make sure itās not recognized as a horizontal rule, but as anonymous, quoted code. Despite these precautions, Instapaper rendered those as horizontal rules, awkwardly breaking up paragraphs instead of displaying the codeās text inline.
That behavior may make sense in some contexts, but not really in this one. So I went through and removed the brackets, despite it looking kind of goofy without them. But this post was ostensibly about writing blog posts with things like Instapaper in mind, and I wanted it to be readable in there.
Whatās even more baffling is that hrs that werenāt inline with paragraphs wouldnāt display at all. Just regular plain old hrs. Not on Daring Fireball and not on here. For a parser that is so aggressive as to forcibly render hrs that donāt want to be, itās bizarre that it ignores the ones with their hand raised.
So, I dunno. Iām pleased that I managed to find a CSS replacement for Blanc and Hackettās vibe, but now Iām not sure if they were doing it wrong at all. At least theirs show up.