Compare commits
No commits in common. "7b13fa794e3a6607c4c97c66b6d8a8899415ee27" and "e0d63e0edaf7278e41d275a79bcec826204068e0" have entirely different histories.
7b13fa794e
...
e0d63e0eda
7 changed files with 10093 additions and 10307 deletions
4
Makefile
4
Makefile
|
@ -1,4 +0,0 @@
|
||||||
|
|
||||||
.PHONY: all
|
|
||||||
all:
|
|
||||||
python3 ./main.py
|
|
|
@ -5,21 +5,20 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<title>cfebs.com${more_title}</title>
|
<title>cfebs.com${more_title}</title>
|
||||||
<link rel="icon" type="image/png" href="/avatar.png">
|
<link rel="icon" type="image/png" href="/avatar.png">
|
||||||
<link rel="stylesheet" href="/style.css?v=${_now}">
|
<link rel="stylesheet" href="/style.css?v=2">
|
||||||
<link rel="stylesheet" href="/chalk.min.css?v=${_now}">
|
<link rel="stylesheet" href="/chalk.min.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<main>
|
<nav class="container navbar navbar-light">
|
||||||
<nav>
|
<span class="navbar-brand"><a href="/">cfebs.com</a></span>
|
||||||
<img class="logo" alt="A yellow monster thing and iconic avatar used by cfebs" src="/avatar.png" />
|
|
||||||
<a href="/" class="home">cfebs.com</a>
|
|
||||||
</nav>
|
</nav>
|
||||||
<hr />
|
<section class="container">
|
||||||
<section class="content">
|
<div class="row">
|
||||||
|
<div class="col-md-8 col-sm-12">
|
||||||
${content}
|
${content}
|
||||||
</section>
|
</div>
|
||||||
<hr />
|
<div class="col-md-4 col-sm-12">
|
||||||
<footer>
|
<img style="height: 5rem" class="mb-2" alt="A yellow monster thing and iconic avatar used by cfebs" src="/avatar.png" />
|
||||||
<dl>
|
<dl>
|
||||||
<dt>Contact</dt>
|
<dt>Contact</dt>
|
||||||
<dd><a href="mailto:mail@cfebs.com">mail@cfebs.com</a></dd>
|
<dd><a href="mailto:mail@cfebs.com">mail@cfebs.com</a></dd>
|
||||||
|
@ -28,8 +27,9 @@
|
||||||
<dt>Bluesky</dt>
|
<dt>Bluesky</dt>
|
||||||
<dd><a rel="me" href="https://bsky.app/profile/cfebs.com">@cfebs</a></dd>
|
<dd><a rel="me" href="https://bsky.app/profile/cfebs.com">@cfebs</a></dd>
|
||||||
</dl>
|
</dl>
|
||||||
</footer>
|
</div>
|
||||||
</main>
|
</div>
|
||||||
|
</section>
|
||||||
<script src="/highlight.min.js"></script>
|
<script src="/highlight.min.js"></script>
|
||||||
<script>hljs.highlightAll();</script>
|
<script>hljs.highlightAll();</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
5
main.py
5
main.py
|
@ -2,9 +2,9 @@ import os
|
||||||
import re
|
import re
|
||||||
import glob
|
import glob
|
||||||
import html
|
import html
|
||||||
|
import email
|
||||||
import logging
|
import logging
|
||||||
import datetime
|
import datetime
|
||||||
import email.utils
|
|
||||||
from multiprocessing import Pool
|
from multiprocessing import Pool
|
||||||
from string import Template
|
from string import Template
|
||||||
|
|
||||||
|
@ -92,9 +92,6 @@ def render_template(tpl_fname, out_fname, subs):
|
||||||
with open(tpl_fname, "r", encoding="utf-8") as inf:
|
with open(tpl_fname, "r", encoding="utf-8") as inf:
|
||||||
tmpl = Template(inf.read())
|
tmpl = Template(inf.read())
|
||||||
|
|
||||||
# include in every template
|
|
||||||
subs["_now"] = int(datetime.datetime.now().timestamp())
|
|
||||||
|
|
||||||
out = tmpl.substitute(subs)
|
out = tmpl.substitute(subs)
|
||||||
|
|
||||||
out_fname = os.path.join("public/", out_fname)
|
out_fname = os.path.join("public/", out_fname)
|
||||||
|
|
|
@ -1,143 +0,0 @@
|
||||||
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
|
|
Binary file not shown.
Before Width: | Height: | Size: 281 KiB |
10106
public/style.css
10106
public/style.css
File diff suppressed because it is too large
Load diff
10094
public/style.old.css
10094
public/style.old.css
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue