Directory

Settings

Behind The Scene

A.k.a., how this m*f* website is made ahem, what consideration and technique went into each aspect of the design, etc. I will be filling this out gradually.

Try resizing this website!

A core feature of the design is in trying to make the layout zoom-adaptive, with as little JS and CSS @media queries as possible (as of Nov 22, '24: zero in the layout; a bunch for theme and persistent configs). The secret is to use a shit ton of Flexboxes. In short, it's a crazy generalized blend of horizontal / vertical stacking layouts and document flow but over boxes instead of text. And it works wonders compared to traditional div and display: float;-based layouts.

This entire page is one giant Flexbox containing a header / footer, a left / (disabled) right ToC / Chat panes, and an <article> in the center. There are a few concerns:

  1. The Article shouldn't be too wide, as it'll make reading difficult.
  2. The side panes should always make way for the Article if they happen to be put side-by-side, but should scale to fit the width if forced above / below the content.
  3. The Nav and Footer should be on their own rows, and should be the first / last respectively.

To-do: need an image here for illustration.

The container is a flex box while each element inside is a flex item (which might be its own flex box). Here, we only concern ourselves with a row-wrapping flow.

The singles

To make the Nav and Footer their own rows, they need to "ideally be biiig" but also would "fit in a space out of necessity."

To-do: image.

What I do is set their "ideal size" (i.e. flex-basis) to 220 pixels but allow them to shrink (i.e. flex-shrink: 1).

"Stretch" priorities

The side panes need to grow in parallel with the article and the page right? Make them flex-grow: 1;. But if several flex-grow: 1; items are put side-by-side, they'll use up any extra space equally โ€” which is not what I want. The trick is the Article gets a flex-grow of 220 so it totally masks the growth of the side panes. Remember, a typical screen is no more than a few thousand pixels wide.

But how do I make the side panes even fit in when the Article has a million growth weight? Fortunately, whether something goes on the same row is entirely determined by the "ideal size" i.e. flex-basis. The Article has a pretty small "ideal width" even as it would gladly take up any extra space, so it still lives on the same floor as the side panes whenever they'd fit.

Article max width

Now the article container can grow as much as it wants minus the size taken by the side panes, but how do I make sure the text itself doesn't get so wide to be uncomfortable for the eyes?

The actual <article> element lives in a <div class="article-container">. The container may grow or shrink, but the Article itself has a max-width.

  • Container "basis" controls box wrapping;
  • article "max-width" is there for eye comfort;
  • there's no minimum width, so the page doesn't overflow sideways on a phone; once the article is on its own floor, nothing will be done aside from further shrinking it when the display gets even narrower.

To-do: image.

Uncoupling layout and color schemes

The Zola static site generator has support for Sass so I'm using that instead of raw CSS, so you might find the linked stylesheets not very readable.

In short, adaptive.scss controls the colorschemes (including the background images, which is why there is an entry for background image size); base.scss controls the layout. Themeing doesn't touch the actual layout at all, while the layout file doesn't appoint any colors apart from stub colors or colors for debugging.

Finally, there is a separate fonts.scss that loads a couple open-source fonts that I store local copies of. They also adjust the font sizes for some elements (most remarkably monospace ones). This is because each font has its own sizing, and thus this kind of sizing shouldn't really be considered the same as layout sizing.

By the way, you can also find the corresponding Zola/Terra template base.html here.

Buttons with a height

You might have noticed the theme-switcher buttons that feel oddly like physical buttons you'd find on a casette record player. This is very intentional. The main technique involved in positioning is again Flexbox, with a little variation on alignment; the "height" you see is just separate border width for pressed vs released buttons.

To-do: illustration of the .buttongroup flexbox.

To-do: illustration of the button border widths.

And then there's the geometric rounding of button shapes which is done entirely through the border-radius property in combination with :first-child / :last-child pseudoelements.

To-do: illustration of the button border radii.

A little trick is to use box-sizing: border-box; so that the buttons are aligned by how big they are externally instead of how big the text area is.

Todo: illustration of box-sizing for buttons.

You'll see that the buttons reflect the current button pressed as well as the last selection (if any). The former is easily achieved via :active, while the latter is a bit hacky:

body.adaptive div.buttongroup>button.adaptive { border-width: 1px; }
body.bgdark div.buttongroup>button.bgdark { border-width: 1px; }
body.bglite div.buttongroup>button.bglite { border-width: 1px; }

The same class name is being used for both the body and the buttons to indicate a relationship of correspondence. This allows me to do without modifying any property of the buttons themselves. While the button classes hold constant, the change to the body is enough to help "reselect" the correct button to be kept pressed down.

The logo is technically "fully contained" in the gradient nav bar. It's just border-box sizing and negative margins, really. I love negative margins.

Again I'm using box-sizing: border-box; because the space used by the logo can then be determined ahead of knowing how thick the border is, allowing for easier adjustment, plus there's less ambiguity as to how "big" things are. Actually, screw that. It's about the same w.r.t. what I want to achieve.

Todo: illustration of box-sizing interacting with paddings and margins.