Customizing the CSS for #WriteFreely is a pain in the butt

You like the style of my blog? It only took me all afternoon. I may have some work catch-up to do this weekend.

So one of the reasons I broke up with WordPress, other than it was heckaspensive to host a domain, and it was over featured, and I wanted to self-host, etc., etc. – was because I couldn't futz with the stylesheet for this blog without paying even more money. That's dumb.

I mean all I wanted was monospaced text for snips of code, is that too much to ask for?

#WriteFreely on the other hand, lets you muck with your #CSS directly. However, it's not quite as simple as it would seem. For one, the last time I futzed with Cascading Style Sheets, #webrings were still a thing and everyone still used #ICQ. CSS has come a long way and is a lot more powerful – at the same time a lot more complex.

Out of the box WriteFreely CSS customization

So drill into your Blog's customization menu either from your blog's landing/index page: or from your account's Blogs page: and scroll down until you see Custom CSS. Then, all you have to do is paste in your custom CSS, save and go check it out right?

Not quite. Throw in some basics like an h1 or a a:hover and you'll find it will work in some instances but not others.

What happens is, the custom CSS you paste in there has to compete with the site/WriteFreely's default stylesheet. THAT bad boy is linked over here. No, that's no mistake; and yes, it IS a big glob of CSS with no formatting or whitespace or comments – good luck reading that; that's the form its served up from WriteFreely's statics folder.

The reason that's a big glob is because it's rendered – during WriteFreely install – on the fly from some LESS scripts; LESS is a CSS pseudo language, and there's a LESS node.js tool that compiles them into CSS. So the source of the stylesheets are easier to maintain for the WF/Write.As developers, but makes it a bit thicker for us trying to twiddle with our blog styles.

CSS Specificity Sucks

The problem we bang up against is CSS Specificity – to whit, the more specific, or narrow in scope your style declaration is, the higher precedence it will have. For example, we could use this CSS

h1 {
 color: blue
}

but then have the HTML

<h1 style="color: pink">The heading yo</h1>

and the latter would win (in the CSS engine Battle For Supremacy) because its more specific.

So this is the same WriteFreely default stylesheet from above, but run through the nice CSS Formatter at cleancss.com. Look at all those very specific styles! For example, we could be trying to change the font-size and padding of every h1, but we'd get clobbered by

body#subpage #wrapper h1{
    font-size:2.5em;
    letter-spacing:-2px;
    padding:0 2rem 2rem;
}

.. that is any h1 tag in the HTML that is a descendant of a body tag (with an id=subpage) or any element with id=wrapper.

The helpful link – below the box where you paste your CSS – to the CSS customization page over at Write.As gives you a few hints of what you have to cover, but not much.

UGH. HTML. I still have that Dreamweaver 3 CD around somewhere..

What you have to do is delve into the HTML that WF spits out and see what's there. OR, you can use a tool (like I do) that lets you load the webpage and analyze all the CSS stylings. I use Skybound's Stylizer for Windows, it lets you click on page elements and see what style rules/declarations from where are affecting it, and you can tweak or suppress any declaration, then copy-paste your new styles into your new stylesheet.

There are two main pages we care about in our WF blog: the blog's index page – this is the landing page for that blog; and a “post” page for each WF post entry. Diving into the HTML for the index we see:

BODY#collection
 HEADER    <-- pinned posts, the byline from the Customize page
  H1 <blog title - link to this page>
SECTION#wrapper   <-- the list of individual post titles
 ARTICLE     <-- each one is wrapped in one of these
 H2 <article title>
 TIME <post date>
 DIV 
  <article content>

and on each blog post's individual page or direct URL

BODY#post
 HEADER
  H1 <link back to index page>
 ARTICLE

so you see, if you tweak the style for an element, say <p>, it will get clobbered if there is a more specific ruling for the same attributes for a <p> that shows under a <BODY id=post> or <BODY id=collection> tag.

So – either you make overriding style declarations for everything:

body#post,body#collection p {
    <CSS for p>
   }

but unless you're a CSS guru (I am NOT), WriteFreely's paste-your-CSS widget (which has a nice syntax checker) might complain about those tags already being defined which was a real hassle for me. Or you can use the allowed, but probably-not-the-best-way method, the !important directive.

h3 {
    color: #FFCC00 !important;
}

The !important directive tells the CSS engine yeah, I know a more specific style declaration may take precedence, but I really want THIS attribute in this declaration to take priority.

So the !important directive lets us pull a trump card and force our attribute declarations over the ones in the default stylesheet. But what about where we don't even want an attribute to be specified? Well, the sad news is you have to overwrite each attribute to their “null” or “default” state. For example, the default style for preformatted or pre tags is:

BODY#collection PRE, BODY#post PRE, BODY#subpage PRE
{
	max-width: 100%;
	margin: 0;
	background: #F8F8F8;
	border: 1px solid #CCC;
	padding: 0.375em 0.625em;
	font-size: 0.86em;
	-webkit-border-radius: .25em;
	-moz-border-radius: .25em;
	border-radius: 0.25em;
}

I didn't wan't the rounded border, the padding or any of that stuff, but I had to overwrite all the attributes:

pre {
    
    border: 1px solid #FFCC00 !important;
    padding: 10px !important;
    line-height: 1 !important;
    max-width: 100% !important;
	margin: 0 !important;
	background:#222222 !important;
	font-size: smaller !important;
	-webkit-border-radius: 0 !important;
	-moz-border-radius: 0 !important;
	border-radius: 0 !important;
}

Not a huge deal; it's just an annoyance is all. Depending on what type of attribute, the “null” or “default” value could be 0 (for most dimensions, thickness, pixels, %s) “none” or “auto”.

In any case, here's the final stylesheet for this blog – Not super awesome (and not documented yet) but it covers all of the Markdown styles that WriteFreely supports, that I cover over in my WriteFreely Markdown Cheat Sheet.

If you are a Master In The Way Of Exploding Stylesheet and can point out how I'm pretty stupid and there was a totally easier – or more elegant from a legit CSS cascading sheet way to do this, I would be totally grateful for your wisdom.

References

Changelog

follow –> AT tezoatlipoca AT mas.to, or AT tezoatlipoca AT awadwatt.com to follow this blorg directly on the Fediverse.