Title:  Style-a-blog
Date:   2025-02-16T14:46:36-04:00
---
Originally when writing the blog, I just copied some styles from a [blog][1] and [site][2] that I liked, but now it's time to actually apply a fresh coat of paint.

My goal is nothing flashy, just making the text and layout of the blog really easy to read.

In the same spirit of "build-a-blog", I will start from scratch and write and take notes as I go.

CSS in 2025 is really insane to look at compared to the early-mid 2010s where most of my experience lies.

* [Custom properties (variables)][3]
* [Grid layouts][4]
* [Nesting and child selectors][5]
* [Built in color-scheme light/dark helper][6]

All the nice features are right there and well supported making a preprocessor or polyfilling unnecessary.

A few tools that will make this a bit easier:

A static file server with sane defaults for local dev and static pages: <https://codeberg.org/cfebs/srv>
Basically just a golang `http.FileServer` that uses `Cache-Control: "no-cache, no-store"`

And something to run our build when files change that I call `~/bin/make-watch`

```bash
#!/usr/bin/env bash

dir="$(pwd)"
if [[ -n "$1" ]]; then
	dir="$1"
	shift
fi

last_run_seconds=0
grace_seconds=1
inotifywait -r -m -e modify -e create -e delete "$dir" --format "%e" | while read -r event; do
	if [[ $SECONDS -gt $((last_run_seconds + grace_seconds)) ]]; then
		# reset last_run_seconds if enough time has elapsed
		last_run_seconds=0
	elif [[ $last_run_seconds -gt 0 ]] && [[ $SECONDS -le $((last_run_seconds + grace_seconds)) ]]; then
		# do not consider a make run if seconds falls between the last run and grace period
		continue;
	fi

    make "$@"
    last_run_seconds="$SECONDS"
done
```

Lets go!

## From scratch

Firstly I want to make sure this looks decent across many browsers. So that means considering a normalize or CSS reset.

https://github.com/necolas/normalize.css is probably the gold standard of this still to this day. So lets just minify it and dump it at the head of our `style.css` file

```
❯ curl -sL 'https://necolas.github.io/normalize.css/latest/normalize.css' -o /tmp/normalize.css
❯ sass --no-source-map --style compressed /tmp/normalize.css /tmp/normalize.min.css
❯ cat /tmp/normalize.min.css
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button}button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0}button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none}
```

Now to pick some colors starting with dark mode as it's my system preference.

```
:root {
  color-scheme: light dark;
}
```

This alone actually will make the background dark based on your browser's defaults which is perfect.

<img height="500px" width="auto" src="/img/style_a_blog_1.png" />

At this point I might consider just leaving the colors up to the browser! Why not, the main goal here is just readability.

As you can see from the screenshot, the normalize is kind of working. But we need to settle on font and size.

```css
html {
	font-size: 16px;
	font-family: sans-serif;
    line-height: 1.4;
}
```

Now to some layout stuff. I just want a simple narrow main content column which will be the `<main>` element. Basically this:

```html
<main>
    <nav>
        <!-- global top nav -->
    </nav>
    <section class="content">
        <!-- where blog list/post will be rendered -->
    </section>
    <footer>
        <!-- global top nav -->
    </footer>
</main>
```

```css
main {
	width: 600px;
	margin: 0 auto;
}

@media (width < 600px) {
	main {
		width: 100%;
		margin: auto;
	}

    section.content {
        padding: 0 1rem;
    }
}
```

Believe it or not, this is basically all you need. Normalize and browser defaults take care of the rest.

## Tweaks

A few more things that I want to differ from browser defaults.

* Remove underline from header links.
* `<pre>` monospaced font is a bit large by default.
* Inline `<code>` tags get a little padding to separate them while reading.

## Conclusion

There is nothing that profound here. But if the goal is simplicity and readability, browser defaults and simple HTML semantics take you _very_ far.

[1]: https://drewdevault.com/
[2]: https://sr.ht/
[3]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_cascading_variables/Using_CSS_custom_properties
[4]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout
[5]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_nesting/Using_CSS_nesting
[6]: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value/light-dark
