609
Note: This article is outdated, but will be kept here for archival purposes.
I’ve recently been working on making this site lighter. Most of that time was spent obsessing over streamlining CSS. This post details various optimisations I’ve used.
reset
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-style: normal
}
This is a simple reset. There’s the usual margin and padding resets. Box sizing is set to border-box
so that borders and paddings are taken into account when defining elements’ widths and heights.
The font style is reset because I use the dfn
and cite
tags, which are italicised by default. Italics more apropros for serifs.
body
body {
background-color: #e3dbc3;
font-family: sans-serif;
font-size: 20px;
line-height: 1.6;
margin: 0 auto;
max-width: 64ch;
padding: 3.3em 1.6em 3.3em 1.6em;
}
The site features a simple central column for content. The body is set to a maximum width of 64 ch. The ch
unit is defined by the width of the numeral “0.”
The font size is set to 20 px and a line height of 1.6. The font is set to the browser’s default sans-serif. These can be reduced to a single property.
font: 20px/1.6 sans-serif
The body is divided into four sections: header, aside, main, and footer.
aside, header, main { margin: 0 0 2.6rem 0 }
scale
The values used in margins, paddings, and the type scale are derived from the golden ratio (φ). I round these values to the nearest tenths to trim off a few bytes.
0.78, 1.00, 1.27, 1.62, 2.06, 2.59, 2.62, 3.33, …
aside
The aside
section appears in project pages and contains links and time-tracker summaries. It’s a simple 3-column grid.
aside {
display: grid;
gap: 1.3em;
grid-template-columns: 3fr 3fr 3fr
}
Using the grid shorthand property and the repeat function, this can be shortened.
grid: auto / repeat(3, 3fr)
The links appear in a list with disabled bullets
nav ul { list-style: none }
main
The main section contains various elements like paragraphs, images, and blockquotes, which are evenly spaced apart.
main p, main blockquote,
main img, main code:not(.inline), main h2 {
margin: 0 0 1.3rem 0
}
However, this takes up way too much space. But since only direct children of the element are being targeted, the child combinator selector can be used:
main > * { margin: 0 0 1.3rem 0 }
hyperlinks
Hyperlinks are set to match to the body text colour. To avoid duplicated declarations, I combined the two into a separate block:
a, body { color: #222 }
I set the links’ focus and hover states to the inverse of the background and foreground colours. This was also applied to text selection and inline code
and kbd
elements.
::selection, a:focus, a:hover, code.inline, kbd {
background-color: #222;
color: #e3dbc3
}
I didn’t style links any further. I used to dislike how underlined text was rendered because lines went through descenders but this is no longer the case in modern browsers.
blocks
As demonstrated on this page, code blocks are a big part of the site. Code blocks are set to horizontally scroll when text overflows. Wrapping of the blocks’ contents is disabled.
code:not(.inline) {
display: block;
overflow-x: auto;
padding: 0 1.6em 0 1.6em 0;
white-space: nowrap
}
Like the code blocks, blockquotes are padded to visually separate them from the rest of the content. The .q
class targets the paragraph element housing the quote itself; its only function is to provide a bit of space between the quote and the attribution.
blockquote { padding: 0.8em 1.3em 0.8em 1.3em }
.q { margin: 0 0 .8rem 0 }
Trifles make perfection and perfection is no trifle.
— Michelangelo
Images are housed in figure
blocks as they may have captions. The figure blocks aren’t modified, but the captions are center-aligned.
figcaption { text-align: center }
Images are set to a width of 100% to make them responsive. The .p
class uses the image-rendering
property to scale pixel-art images. This enables me to host smaller images, effectively improving page load times.
img { width: 100% }
.p { image-rendering: crisp-edges }
trifles
Here are some additional tricks I used for further reductions. I don’t necessarily recommend these practices as the savings they provide are somewhat trivial. That and you may be sacrificing some degree of stylesheet readability. However, for this endeavour, those savings are quite substantial.
Remove units for zero values. If a value is a decimal below one, the zero can be omitted
kbd { padding: 0px 5px 0px 0px }
kbd { padding: 0 5px 0 0 }
Use IDs or class names in lieu of tag names, where appropriate
figcaption { text-align: center }
.f { text-align: center }
aside, header, main { margin: 0 0 2.6rem 0 }
.m { margin: 0 0 2.6rem 0; }
Make use of shorthand properties. Margins, for example, can be shortened like so:
body {
margin-top: 3.3em;
margin-right: 1.6em;
margin-bottom: 3.3em;
margin-left: 1.6em
}
body { margin: 3.3em 1.6em 3.3em 1.6em }
body { margin: 3.3em 1.6em }
Remove spaces around curly brackets and after semicolons and the last semicolon of each block.
body { margin: 0 auto; padding: 3.3em 1.6em; }
body{margin:0 auto;padding:3.3em 1.6em}
Optional: Forget vendor prefixes. Forget IE. Forget Chrome.
results
I ended up with 609 bytes. According to CSS Stats, there are a total of 18 rules, 23 selectors, 30 declarations (all unique, no repetitions), and 19 properties.
Update: As of , the stylesheet has been reduced to 489 bytes
Update: 461 bytes as of