HTML & CSS From Scratch, Volume 3: Intro to Basic Styling, Units of Measure, Font Properties, and Text Properties

Kenneth Roraback (he/him)
11 min readApr 5, 2018

--

Basic Styling

We’ve gone into a lot of detail on targeting, but we have yet to cover the basics of styling in CSS! Most styling properties in CSS are quite simple on their own, but can be a bit confusing to understand and remember as you work. For example, the names for style properties can seem quite arbitrary at times. To understand the approach behind a lot of the styling properties, it is useful to take a look back at the original (outdated) CSS1 specification. This divides styling properties into the following categories:

  • Font properties: properties that define the font family, size, and style
  • Color and background properties
  • Text properties: properties that define how a block of text behaves
  • Box properties: margin, padding, border, width, height, and more — all the styles needed to define how big an element is and how it interacts with others.
  • Classification properties: properties that define an element’s core behavior

Since the standard is outdated, take it with a grain of salt — some things have since been deprecated, and others have been added — but the original CSS standard breaks down the thinking that went into developing CSS’s core set of styles.

Units of measure

There are a bunch of different units that you can use CSS, and each has its usefulness in different circumstances. As you saw above with pixels, when you write a number in CSS, it almost always has a suffix to indicate what unit of measure you are referring to. If I assign something like font-size: 18; the style will be invalid and browsers will ignore it.

Use Relative Measurements for Text (most of the time)

Absolute measurements are recommended primarily for known outputs, like printing styles. (Yes, you can define print styles as distinct from screen styles!) Relative measurements are recommended for screens, since they will scale more intuitively and can be more easily adjusted for different formats. Typically, what a developer will do is to set absolute sizes for text in pixels on the root element (<html>) and then set everything else relative to that. Then, if you want to make the font bigger or smaller for mobile formats or for printing, you only have to scale a single number down, and everything else will adjust to match it.

Options for absolute units are pixels and some of our more traditional units of length (an aside: picas and points aren’t used in most people’s daily lives, but they’re a huge part of the typesetting and printing press culture that preceded digital production, which is why they still have a place in digital production):

  • px: pixels. For high-density screens, this is translated to effective pixels based on the default display resolution, so it isn’t really in pixels. Note also that this will change based on the size and effective pixel density of a screen. For example, effective pixels are smaller on my laptop screen than on my external monitor, which means elements in a webpage are displayed at a smaller size on my laptop.
  • cm: centimeters
  • mm: millimeters
  • in: inches
  • pc: picas, 1/12th of an inch
  • pt: points, 1/72nd of an inch

Or in relative units:

  • %: percentage of the parent element’s font size. This one is relatively intuitive: 100% is the size of the parent font-size. Below 100% is smaller, and >100% is bigger.
  • em: relative to the font-size of the element; 1em = font-size of the element. This is used a LOT for assigning relative type sizes.
  • rem: relative to the font-size of the root element, also used a lot for assigning type sizes relative to the html element
  • ex: relative to the x-height of the font. I literally have never used this, and I have never seen it used in a webpage. Still, it’s available if you want to try it! (An aside: x-height is what it sounds like: the height of a lowercase ‘x’ in a font. This varies from one typeface to another and has implications for legibility of the font at small sizes and our perception of how elegant it is.)
  • ch: relative to the width of the zero ‘0’ of a font. I have also never used this or seen it used by anyone else. This one is a newer standard, supported by IE 9 and above, so it’s safe to use for most websites.
  • vw: relative to 1% of the width of the viewport; 100vw = 100% of the width of the viewport. This is VERY useful, especially in conjunction with the calc() function. Both of them, along with vh below, were introduced to CSS3 and are supported by IE9 and above.
  • vh: relative to 1% of the height of the viewport; 100vh = full height of the viewport.
  • vmin: relative to 1% of the height or width—whichever is smaller. Note that this is compatible with IE9 and above, but IE9 is special and calls the unit vm instead of vmin.
  • vmax: relative to 1% of the height or width—whichever is larger. Unlike vmin, this is not supported on any version of IE or MS Edge, so I do not recommend using it unless you hate Windows users and want them to see a broken website.

An Aside About Accessibility

Some of you who are more experienced in styling might have balked above where I said to set font-size in pixels. The older way of thinking of font sizes was to set the initial font-size of the html element as a percentage, so that if a user has non-standard browser settings for a larger font-size, all text would appear larger on their screens than on the average user’s.

The web has largely moved away from setting font sizes as a percentage of user defaults. As webpages have become more visually nuanced and complex, it has become impractical to scale font sizes separate from the rest of the page without breaking the page layout. The approach that I, along with many others, take to this conundrum is to make pages that scale well across all screen sizes, such that if someone zooms in on the page, they will still have an aesthetically pleasing view with their desired font-size. Perhaps recognizing this, modern browsers bury text size settings, whereas page zoom is is typically accessible from a drop-down menu.

As long as you make fully responsive website that can handle zooming appropriately, you will meet accessibility standards. See the W3C standard for accessibility of text resizing if you have any doubts on that!

An Aside About Why I Keep Mentioning IE Compatibility

Microsoft has historically been very slow to match the latest web standards in its browsers, though that has progressively improved on that over time. Additionally, because Microsoft has historically bundled the Internet Explorer (and now Microsoft Edge) browser with Windows without a great process for upgrading users to the latest browser as time goes on, IE users have historically used outdated browsers longer than other users. A browser like Chrome just updates itself in the background by default, and other browsers are great about prompting the user to update. As such, when I mention compatibility with IE9 and above, or IE11 and above, you can assume that all other major browsers were in alignment well before Microsoft.

Font properties

These are the properties you use to set up a font:

  • font-style: defines whether a font is italic or normal. Also an option: ‘oblique,’ but don’t use that. It programmatically slants a font, which is something that you should never do. Font families get specially-created italic styles, and programmatically slanting a font never looks elegant. Note, for example, that the characters in this italicized font are unique from the ‘normal’ characters, and that’s part of what makes italic text stand out and feel so special.
  • font-variant: normal or small caps. You’ll almost never want to use this. For similar reasons to why you don’t want to use oblique text, you should avoid small caps, unless you’re using a font that has a special small caps variant.
  • font-weight: normal, bold, light, or 100, 200,…900. This is how you define how bold text is. For a simple font, you might only ever use normal and bold, but many modern fonts have multiple weights. The most common font weights (and the associated CSS property) are: thin (100), light (300), normal (400), semi-bold or medium (600), bold (700), and black (900).
  • font-size: how big or small the font is. This can be defined in many different units, both absolute and relative! We’ll get into more detail on units next time, but for simplicity, let’s talk about size in pixels for now. If you want a preview on different unit options, check out the W3Schools page about CSS units.
  • font-family: a comma-separated list of font family names that assigns font-family fallbacks for browsers to use. In the early days of the web, you couldn’t embed fonts in websites, so you had to rely on users’ installed fonts, which vary from computer to computer, particularly across Windows and Mac machines. For example, if your preferred font was Helvetica (available on Macs), you might list Arial as a 2nd option, since Helvetica isn’t installed on Windows computers by default. Note that if a font has a space in the name, you should enclose it with quote marks. Even in the modern web, if you are embedding a font, it is good to have fallbacks listed in case something happens to your font files or if you’re embedding a font by referencing a bit of code from the Google Fonts project (WHICH IS AWESOME; YOU SHOULD CHECK IT OUT), in case the apocalypse happens and Google’s hosting goes down. Also note, you can tell the browser as a final fallback whether you want it to use a serif or sans-serif font.
  • font: a property that you can use to define all of these at once, as well as line-height—in shorthand. You might use this one at the start of your CSS font definitions, when you define defaults, and then you might override it with more granular styles for elements like headings or for certain widgets. For this, the value for each font style definition above is defined with a space between it and the next, in the precise order of the list above, with line-height, one of the text properties, inserted after font-size with a / between font-size and line-height. For example, font: italic normal normal 14px/18px Helvetica, 'Hevetica Neue', Arial, sans-serif; As you can see, this isn’t especially legible, so I don’t recommend using it frequently throughout your code.

Let’s see these in action! How might we structure styles for a set of headings and paragraph text, for example?

<h1>Playing with Font Properties</h1>
<h2>I'm a 2nd-level heading</h2>
<p>Paragraph text gets the default font-size unless you override it. You can always override browser defaults; nearly every major web destination does so.</p>

The very-straight-forward-but-somewhat-terrible way to write our styles would be something like this:

h1 {
font-size: 26px;
font-family: Helvetica, 'Hevetica Neue', Arial, sans-serif;
font-weight: 600;
}
h2 {
font-size: 18px;
font-family: Helvetica, 'Hevetica Neue', Arial, sans-serif;
font-weight: 300;
}
p {
font-size: 14px;
font-family: Helvetica, 'Hevetica Neue', Arial, sans-serif;
font-weight: 400;
}

See it in action in this codepin.

There are some issues with the above:

  • It’s extremely verbose.
  • It’s duplicative. Notice how you’re repeating the font-family over and over. Now imagine all of the other HTML elements that we covered in the last entry. HTML and CSS would be truly awful if you had to write the same style over and over.
  • Related to the above 2 points: it doesn’t take advantage of the ‘cascading’ part of Cascading Style Sheets (CSS).
  • The font-weight of the <p> element is 400 (normal) by default, so we’re just writing extra code that does nothing useful, on that line.

Now, suppose I told you that unless it’s explicitly defined otherwise in your style sheet(s) the font-family and font-sizes are inherited from the html element. Not only that, but heading elements are, by default, sized relative to the root font-size. So another way of writing the above styles would be:

html {
font-size: 14px;
font-family: Helvetica, 'Hevetica Neue', Arial, sans-serif;
}
h1 {
font-size: 26px;
font-weight: 600
}
h2 {
font-size: 18px;
font-weight 300;
}

Or if you want to use the shorthand property:

html {
font: 14px Helvetica, 'Hevetica Neue', Arial, sans-serif;
}
h1 {
font-size: 26px;
font-weight: 600
}
h2 {
font-size: 18px;
font-weight 300;
}

Alternatively, if you use relative units such as rem or em (see below):

html {
font: 14px Helvetica, 'Hevetica Neue', Arial, sans-serif;
}
h1 {
font-size: 1.9rem;
font-weight: 600
}
h2 {
font-size: 1.3rem;
font-weight 300;
}

See this last example in action on codepin.

Text Properties

Text properties extend our capabilities for manipulating text to more than just the letters, and allow an engineer to manage how text is decorated, transformed, aligned, and even how letters and words are spaced. Basically, how do we manage groups of text beyond how each single letter is displayed?

Text properties include:

  • word-spacing: how much space to put between words in an element, in addition to the default spacing. By default, this is set to normal. You can use units described in the next section to increase/decrease word spacing.
  • letter-spacing: how much space to put between letters in an element, in addition to the default spacing. By default, this is set to normal. You can use units described in the next section to increase/decrease letter spacing.
  • text-decoration: Options here are underline, overline, line-through, and blink. Please please please never use blink unless you really want to embrace the cheese of an already cheesy website. This was quite commonly used in the 90s and it was a bit intense.
  • vertical-align: How is text aligned, vertically? baseline (the default, which you’ll almost always use for text), middle, sub, super, text-top, text-bottom, top, or bottom? We’ll dive a bit deeper into these in a moment
  • text-transform: Transforms capitalization of text in the element. Options are capitalize (title-case every word), uppercase (make every letter uppercase), lowercase (make every letter lowercase), and the default is none.
  • text-align: horizontal alignment. Options are left, center, right, and justify. The designer in me is going to strongly advise you not to use text-align: justify. When people read, they use the ‘rag’—the uneven side of the text block—to understand where they are from line to line. When you ‘justify’ text, you align that edge, making your text harder to read. Also, typically when this is done in book publishing, it’s a very careful process in which the spacing is spread across letters and word spaces. Browsers aren’t nearly so good at this, though, and the space is just distributed between words, so justify ends up creating huge gaping spaces between words in some lines, which makes your text that much harder to read, not to mention awkward and unprofessional!
  • line-height: height of each line of text. This is most often defined in the relative unit, em, in which case it sized based on the text size for the element.

Vertical alignment has a lot of options! Thankfully, for most text, you’ll just use baseline to ensure that the baseline (the imaginary line on which the letters sit, but that certain characters such as y, j, q, and p have ‘descenders’ that dip below) matches across the text in an element, regardless of the font-size. Once we get into box models, though, you’ll find that there are some other cases in which people use display: inline-block to achieve layouts in which you can vertically align elements like text. We’re going to cover inline-block in more depth a bit later, though, because a) it has a lot of nuances that are deserving of its own post, and b) it is overused, typically by people who never learned more basic positioning tactics!

There’s Much More!

I have only covered a tiny portion of the CSS styles you might use, but we’ll tackle more, next week. In the meantime, some homework for you:

  1. Set up a set of HTML elements with headings, paragraphs, and more, as desired. Style them using font styles with pixel values for sizing. Then try setting the font size on the html element in pixels, but others using a em or rem units. Compare the two to see how easy/hard it is to adjust the font size of your document.
  2. Add text properties like text-align, line-height, and text-decoration.
  3. Go to one of your favorite websites and inspect how they set font sizes across the site. What do they do well? What do they do poorly?

--

--

Kenneth Roraback (he/him)
Kenneth Roraback (he/him)

Written by Kenneth Roraback (he/him)

UX Designer + Product Design@Teleport. Defender of usability, clear communication, & semantic HTML. More Sondheim than Lloyd-Webber. www.kennethroraback.com

No responses yet