The Underscores (_s) theme with Sass and Gulp Part3: set up custom webfonts

Untitled Document

==================================================================

On this page:

  1. Set up custom webfonts.
  2. Allow translators to control webfonts.
  3. Preconnect custom web fonts for improved performance.
  4. Work with Sass and source maps.
  5. Create responsive typography.
  6. Begin with reponsive layout.

==================================================================

11. Set up custom webfonts

Github repo branch: part3_11

For my design I want to use two font families:

  1. Ubuntu Regular, for headings and meta content
  2. Open Sans Light, for body content and other main content

All I need to do is grab the URL to the style sheet that Google fonts give me after selecting my fonts:

	<link href="https://fonts.googleapis.com/css?family=Open+Sans:300|Ubuntu" rel="stylesheet"> 

and copy it, then go to functions.php for our theme, and scroll down until I find the enqueue section: function pre_underscores_scripts(), and add the following line to the function

	//Enqueue Google fonts: Open+Sans and Ubuntu
wp_enqueue_style('pre-underscore-fonts', 'https://fonts.googleapis.com/css?family=Open+Sans:300|Ubuntu');

Now when I go back to the browser and look at this page source, and you'll see the custom style sheet in the head section of my page. So that means we have the fonts available, now I just need to apply the fonts using CSS.

I first set up a new font family in sass/variables-sites/_typography.scss. I'll call one font__sans, and one font__headers. Then I need to point at my new fonts. So I'll go back to Google Fonts for a second and see what the names are. So I end up with:

$font__headings: 'Ubuntu', sans-serif;
$font__sans: 'Open Sans', sans-serif;
$font__main: sans-serif;
$font__code: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace;
$font__pre: "Courier 10 Pitch", Courier, monospace;
$font__line-height-body: 1.5;
$font__line-height-pre: 1.6;	

And then while I'm at it, I'll also add some fall back fonts in case the font is not working:

$font__headings: 'Ubuntu', sans-serif, Helvetica, Verdana, Arial ;
$font__sans: 'Open Sans', sans-serif, "Lucida Grande", "Lucida Sans Unicode","Lucida Sans" ;
$font__main: sans-serif;
$font__code: Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace;
$font__pre: "Courier 10 Pitch", Courier, monospace;
$font__line-height-body: 1.5;
$font__line-height-pre: 1.6;	

Next I go to the file sass/typography/_typography.scss

and change the font-family to $font__sans

body,
  button,
  input,
  select,
  optgroup,
  textarea {
  color: $color__text-main;
  font-family: $font__sans;
  @include font-size(1);
  line-height: $font__line-height-body;
  }
@import "headings";
@import "copy";

Then I go to the file sass/typography/_headings.scss and and change the font-family to $font__headings

h1, h2, h3, h4, h5, h6 {
clear: both;
font-family:$font__headings;
}

Finally go back to the browser, and you'll see that my headings are Ubuntu, and my body font is Open Sans. Awesome!

==================================================================

12. Allow translators to control webfonts

Github repo branch: part3_12

In the previous movie, we added Google fonts to the theme by simply enqueueing the stylesheet, and this is fine, as long as we know the theme will only display content written in English, or other Latin languages. However, if there's a chance a theme may be translated, we should give the translator a chance to turn the font off, if it doesn't support the characters in the translated language. The problem of how ro do this has been partially solved in the twentyseventeen theme, so we can go and borrow the code, and then modify it to fit our needs. Inside twentyseventeen, in functions.php, if you scroll down to the enqueue section, and you'll see here, we enqueue the style, twentyseventeen-fonts, but instead of putting in the font URL, they use this function, twentyseventeen_fonts_url.

/**
* Enqueue scripts and styles.
*/
function twentyseventeen_scripts() {
// Add custom fonts, used in the main stylesheet.
wp_enqueue_style( 'twentyseventeen-fonts', twentyseventeen_fonts_url(), array(), null );

So if we find the source of that function, by either holding down Control or Command, and clicking the function name, you go to the function itself, and this is what generates the actual font URL that we're going to use. So, copy this entire string here, down to the end of the function, and go to your functions file, scroll up, until you find the end of pre_underscores_setup, create some space, paste it in, and then quickly do a search replace for twentyseventeen, to swap it out for pre_underscores. See code 3.12.1 below

/**
  * Register custom fonts.
  */
  function pre_underscores_fonts_url() {
  $fonts_url = '';
 /*
  * Translators: If there are characters in your language that are not
  * supported by Libre Franklin, translate this to 'off'. Do not translate
  * into your own language.
  */
  $libre_franklin = _x( 'on', 'Libre Franklin font: on or off', 'pre_underscores' );
 if ( 'off' !== $libre_franklin ) {
  $font_families = array();
 $font_families[] = 'Libre Franklin:300,300i,400,400i,600,600i,800,800i';
 $query_args = array(
  'family' => urlencode( implode( '|', $font_families ) ),
  'subset' => urlencode( 'latin,latin-ext' ),
  );
 $fonts_url = add_query_arg( $query_args, 'https://fonts.googleapis.com/css' );
  }
 return esc_url_raw( $fonts_url );
  }
  
code 3.12.1 Paste this code in the function.php file of the pre_underscores theme

Now, we can break down this function, and see exactly what's happening. First, pre_underscores_fonts_url sets up a new variable called fonts_url, and sets it to an empty string. Then, at the very bottom of the function, it escapes that URL, to make sure there's no clutter in it that we don't need, and returns it to wherever we call the function. So that will either be nothing, if the fonts are turned off, or the URL to the correct stylesheet on Google fonts, if it's turned on.

To actually hook the fonts_url to the site, we have to enqueue it, and we do that by calling the function itself, so I'll copy the function name, go down to our enqueue section, and replace the URL to the font that we have here, with just the function name.

So, replace

wp_enqueue_style('pre-underscore-fonts', 'https://fonts.googleapis.com/css?family=Open+Sans:300|Ubuntu');

with

wp_enqueue_style('pre-underscore-fonts', 'pre_underscores_fonts_url()');

So now, the function will run on enqueue, and outputs the URI to the stylesheet from Google fonts. We can quickly check to make sure it still works by going back to the site, and viewing page source. Scroll down, and here you have the URI again, only now, we're lining up Libre Franklin rather than the fonts we actually want, so we need to change the function pre_underscores_fonts_url() to:

/**
  * Register custom fonts.
  */
  function pre_underscores_fonts_url() {
  $fonts_url = '';
 /**
  * Translators: If there are characters in your language that are not
  * supported by Open Sans and Ubuntu, translate this to 'off'. Do not translate
  * into your own language.
  */
  
  $open_sans = _x( 'on', 'Open Sans font: on or off', 'pre_underscores' );
  $ubuntu = _x( 'on', 'Ubuntu: on or off', 'pre_underscores' );
 
  $font_families = array();
 
 if ( 'off' !== $open_sans ) {
  $font_families[] = 'Open Sans:300';
  }
  
 if ( 'off' !== $ubuntu ) {
  $font_families[] = 'Ubuntu';
  }

 if ( in_array( 'on', array($open_sans, $ubuntu) ) ) {
 $query_args = array(
  'family' => urlencode( implode( '|', $font_families ) ),
  'subset' => urlencode( 'latin,latin-ext' ),
  );
 $fonts_url = add_query_arg( $query_args, 'https://fonts.googleapis.com/css' );
  }
 return esc_url_raw( $fonts_url );
  }
  

The items are the array of Open Sans, and Ubuntu. Save that, go back to the site, and here you can see already that all the fonts have been reapplied, which means, it actually works. If I want to, I can check the page source, and here you see the call to fonts.googleapis, Open Sans, and Ubuntu. With this function in place, translators are now able to toggle either of these fonts on and off, and if you want to test it, simply go into the definitions for Open Sans, and Ubuntu, and change it from on to off, and you'll see that the two fonts toggle off individually.

==================================================================

13. Preconnect custom web fonts for improved performance

Github repo branch: part3_13

If I inspect any element on the page, you can see under computed that that element will have some font applied in this case Open Sans en Ubuntu, but to really see what's going on we have to go to sources. From here we can see all the sources that are currently in play on the page and this tells me all the files that are being used and where they live and you can see we have these two entries font Google APIS and fonts G static.

So what's happening is for each of the font weights that we're calling in, the browser has to navigate to fonts.gstatic.com and download the correct weight for the entire font set so it can be used.

This is a really labor intensive process. We're going to do that using a function in Wordpress called wp_resource_hints() in the file wp_include/general-template.php file.

This function does exactly what it sounds like. This function improve the performance by telling the page and the browser right off the top to make a connection to fonts.gstatic.com because in a little while you're going to be asked to get content from it and you might as well open a port so you can just pull that content down

Again we're going to borrow the code from 2017 to do this. If we scroll down past the function that generated the Google font URL, you'll find an additional function called twentyseventeen_resource_hints(). And I will just copy that entire function, paste it in directly below pre_underscores_fonts_url() then I'll do a search replace again, to change all the 'twentyseventeen' s for 'pre_underscores' so that everything is set for my theme.

/**
  * Add preconnect for Google Fonts.
  *
  * @since Twenty Seventeen 1.0
  *
  * @param array  $urls           URLs to print for resource hints.
  * @param string $relation_type  The relation type the URLs are printed.
  * @return array $urls           URLs to print for resource hints.
  */
  function pre_underscore_resource_hints( $urls, $relation_type ) {
  if ( wp_style_is( 'pre-underscore-fonts', 'queue' ) && 'preconnect' === $relation_type ) {
  $urls[] = array(
  'href' => 'https://fonts.gstatic.com',
  'crossorigin',
  );
  }
 return $urls;
  }
  add_filter( 'wp_resource_hints', 'pre_underscore_resource_hint', 10, 2 );

All that's really happening here is we're saying 'hey if pre-underscore-fonts is defined,' meaning we've defined it in the pre_underscores_scripts() function in the same functions.php file, then tell the browser 'hey there's this URL you need to open a port for,' it's right here, the browser opens the port, and when we bring in the style sheet for the Google fonts, the browser will say 'hey I already have an open port to fonts.gstatic.com that was easy' and then it will bring in all the necessary fonts and we can use them on the page.

This improves performance on your site ever so slightly. It's only a matter of milliseconds but it does make a difference and it makes everything a little bit cleaner and a little bit easier. And like you see, all you have to do is copy the content in, save it, and everything just works.

==================================================================

14. Work with Sass and source maps

Github repo branch: part3_14

If we want to know the styles that are attached to a certain element on a page, we can rightclick that element and choose the inspect option. The developer windows opens with the css panel showing the styles for our element. It alse shows the naame of the stylesheet in which the style rules are formulated. However we rather want to know the source .sccs file which generates the CSS file in question. Therefor we will generate what's known as source maps. These source maps are hint files for the browser that tell the browser what's the original source of the CSS was. But to see that information, we need to toggle that information on in the browser.

So, open the Developer Tools, and click on the 3-dotted icon on the top-right hand corner. Go to Settings. And then, in Settings, scroll down a bit, and you'll find the option 'Enable CSS source maps'. Toggle that option on, and close your Settings. And now, if I right-click on the link again, and inspect it. You'll see instead of telling me it's in style.css, which I already knew, it tells me the name of the .sccs file. If I hover over this link, you will see the tool tip that pops up with the URL to the .scss file.

==================================================================

15. Create responsive typography

Github repo branch: part3_15

With the fonts in place and working, I want to lay the ground work for responsive layouts. And that starts by making the fonts responsive. Right now, the fonts will be the same size regardless of what width of screen we're looking at the site in. I want the fonts to be slightly smaller on smaller screens and then larger on larger screens. And I'll do that by changing the overall font size on the entire site. First, I need to figure out what is controlling the current font size. So I'll inspect any element on the page, and then navigate my way up to the body element.

So this is where the overall font size is defined. Here I can see there is a rule under the typography.scss file that defines the body font size and it's set to 16 pixels, or one rem. That is relative ems relative to the overall window. One rem will always be 16 pixels, because the default's font size for browser is always 16 pixels. I want that font size to be slightly bigger. I want it to be 20 pixels, or the rem equivalent.

So I need to change this rule. I know where it is, it's sitting in typography/typography.scss. So I can go to my project, go to the sass folder, typography and typography.scss.

But here you see the font size is actually defined using a mixin.

@include font-size(1);

So I need to get to that mixin to change the value. Mixins are in the mixins folder under mixins-master, and here we find the mixin.

// Rem output with px fallback
@mixin font-size($sizeValue: 1) {
font-size: ($sizeValue * 16) * 1px;
font-size: $sizeValue * 1rem;
}

Now, the reason why the theme is using a mixin is because we want to output both the pixel size and the rem size in case the browser doesn't support rem sizes because they're relatively new.

So, here I need to change the default sizes for both the pixel size and the rem size. The pixel size is easy, I just set it to whatever pixel value I want, in our case 20 pixels. The rem will be 1.25 rems. Save the mixin, go back to the browser, and you'll already notice the fonts are bigger.

If I now select the body class again, you can see that the fonts size is set to 1.25 rems. Now I need to make sure that actually means 20 pixels. So I'll go to computed here, and scroll down, and here under font size, you will see the calculated font size, and it is in fact 20 pixels. By applying that rule to the body element, I am effectively changing the default font size for the entire site. So everything will now be based off of 20 pixels font size.

Now I can make my typography responsive using some simple media queries. Back in typography.scss, I'm going to change the default font size from one to .9 This will equate to 18 pixels.

Then I'll nest the media query inside this rule, so I'll say at media screen and min-width and just guess at some random width let's say 700 pixels for now, we'll change that later. And set at include font size to one. Because this is nested inside the rule it means there will now be a media query, that triggers on the min-width of 700 pixels that changes this rule's font size to be one, which is 20, instead of .9 which is 18.

body,
  button,
  input,
  select,
  optgroup,
  textarea {
  color: $color__text-main;
  font-family: $font__sans;
  @include font-size(0.9);
  line-height: $font__line-height-body;
 
@media screen and (min-width: 700px){
  @include font-size(1);
  }
  
}
  
Save that, back in the browser and open the inspector and here I'm going to toggle on responsive view. Then we can go and look at the computed sizes for the font so right now is 20 pixels you can see it down here, and if I reduce the width of the screen, it'll drop down to 18 pixels when we hit 700 pixels.

So you see up here, we hit 700 pixels and when we do, it switches back to 20. So now we have somewhat responsive typography. It's a subtle difference, but it's actually significant when we start looking at smaller screens, and very large screens.

So this is what I want so far. While we're at it, we should also add some basic styling to our headings. I'll go back to just typography folder and headings, this is where we have all our headings. And right now you can see there is no definition for the heading sizes. So I'm going to create headings rules for each of the headings.


 h1 {
  font-size: 3em;
  }
h2 {
  font-size: 2.6em;
  }
h3 {
  font-size: 2.2em;
  }
h4 {
  font-size: 2em;
  }
h5 {
  font-size: 1.8em;
  }
h6 {
  font-size: 1.6em;
  }
When I resize the browser now, you'll see that the headings change size. And that's because the media query is hooked to the body element, and I'm using ems to control the heading sizes. And ems are relative to the next container up that has a firm font size. And since that container happens to be the body element, my headings now become responsive as well. So there you have it, creating responsive typography in underscores using sass, is really straight foreword once you know where all the different pieces are.

==================================================================

16. Begin with reponsive layout

Github repo branch: part3_16

As we start applying our designs to the theme using CSS, it's important that we structure our style sheet in such a way that everything comes in a logical order. Now this can get a little challenging when we work with Sass and partials, because the partials are kind of spread all over the place and it's hard to remember exactly what the structure is. Right now I want to start by creating global layout styles that apply to the entire site and make the entire site responsive. Because to be honest with you, when I look at a layout like this, where the content is jammed up against the edges of the browser, it makes me really itchy so I need to get rid of that by adding some padding to the sides right away and while I'm at it I might as well make it responsive.

16.1 Change 1

In style.scss change


/*--------------------------------------------------------------
  # Widgets
  --------------------------------------------------------------*/
  @import "site/secondary/widgets";
  
  /*--------------------------------------------------------------
  # Content
  --------------------------------------------------------------*/
  @import "site/site";
  

into:

/*--------------------------------------------------------------
  # Content
  --------------------------------------------------------------*/
  @import "site/site";

 /*--------------------------------------------------------------
  # Widgets
  --------------------------------------------------------------*/
  @import "site/secondary/widgets";
  

This is because we want the global styles to render first, because they contain the main content.

16.2 Change 2

In sass/site/_site.scss change

// @import "../layout/content-sidebar";
  // @import "../layout/sidebar-content";
  /*--------------------------------------------------------------
  ## Posts and pages
  --------------------------------------------------------------*/
  @import "primary/posts-and-pages";
/*--------------------------------------------------------------
  ## Comments
  --------------------------------------------------------------*/
  @import "primary/comments";
  

into:


/*--------------------------------------------------------------
## Global Layouts
--------------------------------------------------------------*/
@import "../layout/global";
/*--------------------------------------------------------------
  ## Posts and pages
  --------------------------------------------------------------*/
  @import "primary/posts-and-pages";
/*--------------------------------------------------------------
  ## Comments
  --------------------------------------------------------------*/
  @import "primary/comments";
  

(we will not need the sidebar layouts so we can get rid of them.)

And then create a new file _global.scss in the sass/layout folder with the following code:

.site-content {
padding:1em;
}

If I reduce the width here you see one em is okay. But as I get to a wider screen I really should have more padding so I'll put in a media-query here to increase the padding on wider screens. Now before I do that I should really start using consistent media-query sizes so I'm going to define some sizes in the variables folder. I'll go to variables and structure.css. And here I'll create some query sizes

So I open the sass/variables-site/_structure.scss and add the following query sizes:

$query__small: 600px;
$query__medium: 900px;

And if I ever want to change these queries I just change them in the variables and they will change throughout the entire setup.

Then I can set up my media query. So I'll say inside the site content class (in_global.scss) , I'll nest the media query, at media screen and min-width, query small, so this will be 600 pixels. And when we get above 600 pixels I'll set the padding to two ems. Save, back and check it, and now you'll see here we have two ems of space, and when we hit 600 pixels it turns to one em of space.

 .site-content {
  padding: 1em;
 	
	@media screen and (min-width: $query__small) {
  	padding: 2em;
  	}

  }
  

As we move forward we'll add all our global layout styles to this file, global scss because it's called early on, so that means as the browser goes down the cascade it'll first create the layout then style the posts and pages, then style the comments, then style the widgets and so on and so on and so on.

Leave a comment