Give ability for user to select site font from panel

Was playing with my starter theme, and checking how different font would look like, and came to simple, but nice to have solution:

So, first I create “font” field in site.yml:

          font:
            label: Font
            type: radio
            options:
              graphik: Graphik Pro
              myriad: Myriad Pro 
              gordita: Gordita

So user can select font:

select-font

In <head> let’s put this code:

<?= css(['assets/fonts/'.$site->font().'/font.css', '@auto']) ?>

And put all fonts in /assets/fonts/ folder, with folder names, same as machine names of radio, in this example:
/assets/fonts/graphik/
/assets/fonts/myriad/
/assets/fonts/gordita/

Then in each folder should be file “font.css” (/assets/fonts/graphik/font.css) with:

body {
	font-family: Graphik !important; /* according font */
	}

and @font-face

And in my case, I am using Bootstrap, so adding missing font weights classes, like light (300), or semibold (600):

.font-weight-600,
.font-weight-semibold {
	font-weight: 600 !important;
}

etc.

There should be no need to use !important. I tell the developers I train that !important is a swear word, and they have to put £1 in a charity box every time they use it.

I would drive it through body classes for each font instead, and put them in the main stylesheet. Can save an HTTP request then.

1 Like

:point_up_2:

(frameworks like Bootstrap swear a lot)

1 Like

That they do. The record was £52 on top of the framework stuff.

1 Like

Agree :slight_smile: but that’s still less evil, than hiding unneeded elements with display: none :slight_smile:

Actually checked both font-family and font-weight is working fine without !important, probably I put it “just in case” here, or had other rules to override.

@jimbobrjames didn’t get your idea, do you mean it’s possible to put variable in css file? Didn’t try that, but still decided to make separate files, as some fonts css take more than 100 lines, so just easier to organize that way, and as I know for HTTP/2 it’s ok to have few smaller files compared to one bigger.

Well, rather than use the assets link to add, i would set the font families in a bunch of classes.

.times {
font-family: Times, 'Times New Roman', serif;
}
.garamond {
font-family: 'Apple Garamond', 'ITC Garamond Narrow', 'Garamond', serif;
}

That way you can just add classes to the body tag from your panel choice. HTTP/2 does download things in parallel, yes, but you are still downloading every font for all the weights that you want, after the css download. You can mitigate this with server push, but it’s a still quite a bit of downloading / requesting going on.

Personally I use SASS, and have fonts wired up as variables. font-weight: $thin, and use sass for font face rules to keep the code light. As a rule, I wouldnt recommend using more than 2 fonts on a site, and 2 - 3 weights on each. I generally use 1 custom font and make the other font a browser safe one that doesnt not require a font file.

Heres my web safe font variables if it helps… it uses fancy variants first, and falls back to the more commonly installed versions.

// Simple Times Font Stack
$times: Times, 'Times New Roman', serif;
// Simple Arial Font Stack
$arial: Arial, sans-serif;
// Simple Georgia Font Stack
$georgia: Georgia, serif;
// Simple Garamond Font Stack
$garamond: 'Apple Garamond', 'ITC Garamond Narrow', 'Garamond', serif;
// Simple Helvetica Font Stack
$helvetica: 'Helvetica Neue', Helvetica, sans-serif;
// Simple Verdana Font Stack
$verdana: 'Verdana Ref', Verdana, sans-serif;
// Simple Trebuchet Font Stack
$trebuchet: 'Trebuchet MS', sans-serif;
// Simple Gill Sans Font Stack
$gillsans: 'Gill Sans MT', 'Gill Sans', Tahoma, Geneva, sans-serif;
// Full Times Font Stack
$stimes: Cambria, 'Hoefler Text', Utopia, 'Liberation Serif', 'Nimbus Roman No9 L Regular', 'Times New Roman', Times, serif;
// Full Georgia Font Stack
$sgeorgia: Constantia, 'Lucida Bright', Lucidabright, 'Lucida Serif', Lucida, 'DejaVu Serif', 'Bitstream Vera Serif', 'Liberation Serif', Georgia, serif;
// Full Garamond Font Stack
$sgaramond: 'Palatino Linotype', Palatino, Palladio, 'URW Palladio L', 'Book Antiqua', Baskerville, 'Bookman Old Style', 'Bitstream Charter', 'Nimbus Roman No9 L', 'Apple Garamond', 'ITC Garamond Narrow', 'New Century Schoolbook', 'Century Schoolbook', 'Century Schoolbook L', Garamond, serif;
// Full Helvetica Font Stack
$shelvetica: Frutiger, 'Frutiger Linotype', Univers, Calibri, 'Gill Sans', 'Gill Sans MT', 'Myriad Pro', Myriad, 'DejaVu Sans Condensed', 'Liberation Sans', 'Nimbus Sans L', Tahoma, Geneva, 'Helvetica Neue', Helvetica, sans-serif;
// Full Verdana Font Stack
$sverdana: Corbel, 'Lucida Grande', 'Lucida Sans Unicode', 'Lucida Sans', 'DejaVu Sans', 'Bitstream Vera Sans', 'Liberation Sans', 'Verdana Ref', Verdana, sans-serif;
// Full Trebuchet Font Stack
$strebuchet: 'Segoe UI', Candara, 'Bitstream Vera Sans', 'DejaVu Sans', 'Bitstream Vera Sans', 'Trebuchet MS', Trebuchet, sans-serif;
// Full Gill Sans Font Stack
$sgillsans: Frutiger, 'Frutiger Linotype', Univers, Calibri, 'Myriad Pro', Myriad, 'DejaVu Sans Condensed', 'Liberation Sans', 'Nimbus Sans L', Tahoma, Geneva, 'Gill Sans MT', 'Gill Sans', sans-serif;
// Terminal / Monospace font
$terminal: Monaco, 'Lucida Sans Typewriter', Consolas, 'Courier New', monospace;
1 Like

Ah, ok, clear with body classes, thanks, good idea.