Skillversitas

CSS Fonts

Typography is one of the most important design aspects on the web. CSS provides many properties for controlling the appearance of text, from typeface, size, and weight to line-height. Choosing the right font affects the readability and visual impression of a website.

1. font-family

The font-family property determines the typeface used.

/* Font stack: always provide a fallback */
body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}

/* Serif font */
.serif {
    font-family: Georgia, 'Times New Roman', Times, serif;
}

/* Monospace font */
.code {
    font-family: 'Courier New', Courier, monospace;
}

/* Cursive font */
.cursive {
    font-family: 'Brush Script MT', cursive;
}

/* Custom web font */
.custom {
    font-family: 'Roboto', Arial, sans-serif;
}

Font Stacks and Fallbacks

/* Font stack: order from most desired to fallback */
.heading {
    /* If Montserrat is not available, try Helvetica Neue, then Helvetica, then Arial, then sans-serif */
    font-family: 'Montserrat', 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

/* System font (best performance) */
.system-font {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 
                 'Helvetica Neue', Arial, sans-serif;
}

/* Indonesian/Unicode fonts */
.indonesian {
    font-family: 'Noto Sans', 'Source Sans Pro', 'Open Sans', sans-serif;
}

2. font-size

The font-size property sets the size of the text. CSS supports various units.

Absolute Units

/* Pixel: absolute unit, fixed */
.small { font-size: 12px; }
.normal { font-size: 16px; }
.large { font-size: 24px; }
.xlarge { font-size: 32px; }

Relative Units

/* em: relative to the parent element */
.parent { font-size: 16px; }
.child { font-size: 1.5em; }      /* 24px (1.5 × 16px) */
.grandchild { font-size: 1.5em; } /* 36px (1.5 × 24px) */

/* rem: relative to the root (html) */
html { font-size: 16px; }
.rem-1 { font-size: 1rem; }       /* 16px */
.rem-2 { font-size: 2rem; }       /* 32px */
.rem-0-5 { font-size: 0.5rem; }   /* 8px */

/* Percentage */
.pct-50 { font-size: 50%; }       /* 50% of the parent element */
.pct-100 { font-size: 100%; }     /* Same as the parent element */
.pct-150 { font-size: 150%; }     /* 1.5 times the parent element */

/* viewport units */
.vw-small { font-size: 1vw; }     /* 1% of viewport width */
.vw-large { font-size: 5vw; }     /* 5% of viewport width */

Unit Tips

  • Use rem for font sizes (easy to control from the root)
  • Use em for internal spacing
  • Avoid px for fonts (not scalable)
  • Set font-size: 62.5% on the root to make rem calculations easier
/* Reset: 1rem = 10px */
html {
    font-size: 62.5%;  /* 16px × 0.625 = 10px */
}

body {
    font-size: 1.6rem;  /* 16px */
}

h1 { font-size: 3.2rem; }  /* 32px */
h2 { font-size: 2.4rem; }  /* 24px */
h3 { font-size: 2rem; }    /* 20px */
p { font-size: 1.6rem; }   /* 16px */
small { font-size: 1.4rem; } /* 14px */

3. font-weight

The font-weight property sets the thickness of the font.

/* Named values */
.thin { font-weight: 100; }       /* Thin */
.extra-light { font-weight: 200; } /* Extra Light */
.light { font-weight: 300; }      /* Light */
.normal { font-weight: 400; }     /* Normal (default) */
.medium { font-weight: 500; }     /* Medium */
.semi-bold { font-weight: 600; }  /* Semi Bold */
.bold { font-weight: 700; }       /* Bold */
.extra-bold { font-weight: 800; } /* Extra Bold */
.black { font-weight: 900; }      /* Black */

/* Keyword values */
.normal { font-weight: normal; }
.bold { font-weight: bold; }
.lighter { font-weight: lighter; }  /* Thinner than the parent element */
.bolder { font-weight: bolder; }    /* Thicker than the parent element */

/* Heading hierarchy */
h1 { font-weight: 800; }  /* Extra Bold */
h2 { font-weight: 700; }  /* Bold */
h3 { font-weight: 600; }  /* Semi Bold */
h4 { font-weight: 600; }  /* Semi Bold */
h5 { font-weight: 500; }  /* Medium */
h6 { font-weight: 500; }  /* Medium */

/* Body text */
p { font-weight: 400; }   /* Normal */
.lead { font-weight: 500; } /* Medium for lead text */
.strong { font-weight: 700; } /* Bold for emphasis */

4. font-style

The font-style property sets the style of the font (normal, italic, oblique).

/* Normal (default) */
.normal { font-style: normal; }

/* Italic: uses the italic version of the font */
.italic { font-style: italic; }

/* Oblique: slants the normal version */
.oblique { font-style: oblique; }

/* Common usage */
em, i { font-style: italic; }
cite { font-style: italic; }
.article-intro { font-style: italic; font-size: 1.2rem; }

5. font-variant

The font-variant property sets font variations.

/* Small caps */
.small-caps { font-variant: small-caps; }

/* Normal */
.normal { font-variant: normal; }

/* Common usage */
.abbreviation {
    font-variant: small-caps;
    letter-spacing: 0.05em;
}

/* Font variant numeric */
.tabular-nums {
    font-variant-numeric: tabular-nums;  /* Digits with equal width */
}

.ordinal {
    font-variant-numeric: ordinal;  /* 1st, 2nd, 3rd */
}

.fraction {
    font-variant-numeric: diagonal-fractions;  /* 1/2, 3/4 */
}

6. @font-face (Custom Fonts)

The @font-face rule enables the use of custom fonts loaded from the server.

/* Custom font definition */
@font-face {
    font-family: 'MyCustomFont';
    src: url('fonts/MyCustomFont-Regular.woff2') format('woff2'),
         url('fonts/MyCustomFont-Regular.woff') format('woff');
    font-weight: 400;
    font-style: normal;
    font-display: swap;  /* Text is displayed immediately, the font loads in the background */
}

@font-face {
    font-family: 'MyCustomFont';
    src: url('fonts/MyCustomFont-Bold.woff2') format('woff2'),
         url('fonts/MyCustomFont-Bold.woff') format('woff');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

@font-face {
    font-family: 'MyCustomFont';
    src: url('fonts/MyCustomFont-Italic.woff2') format('woff2'),
         url('fonts/MyCustomFont-Italic.woff') format('woff');
    font-weight: 400;
    font-style: italic;
    font-display: swap;
}

/* Using the custom font */
body {
    font-family: 'MyCustomFont', Arial, sans-serif;
}

h1 {
    font-family: 'MyCustomFont', Arial, sans-serif;
    font-weight: 700;
}

/* Font format */
@font-face {
    font-family: 'IconFont';
    src: url('icons.woff2') format('woff2'),
         url('icons.woff') format('woff'),
         url('icons.ttf') format('truetype');
    font-weight: normal;
    font-style: normal;
}

.icon {
    font-family: 'IconFont';
    font-size: 24px;
}

Font Display Values

/* swap: display the fallback text, replace it with the font after it loads */
@font-face {
    font-family: 'MyFont';
    src: url('myfont.woff2') format('woff2');
    font-display: swap;
}

/* block: hide the text until the font loads */
@font-face {
    font-family: 'MyFont';
    src: url('myfont.woff2') format('woff2');
    font-display: block;
}

/* fallback: hide briefly, then display the fallback */
@font-face {
    font-family: 'MyFont';
    src: url('myfont.woff2') format('woff2');
    font-display: fallback;
}

/* optional: use the font only if it loads quickly */
@font-face {
    font-family: 'MyFont';
    src: url('myfont.woff2') format('woff2');
    font-display: optional;
}

7. Google Fonts Integration

Google Fonts provides thousands of free fonts that can be used on a website.

How to Use Google Fonts

Method 1: Link tag in HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Google Fonts</title>
    <!-- Single font -->
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">

    <!-- Multiple fonts -->
    <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600;700&family=Open+Sans:wght@300;400;600&display=swap" rel="stylesheet">

    <!-- Font with variations -->
    <link href="https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,300;0,400;0,700;1,400&display=swap" rel="stylesheet">
</head>
<body>
    <h1>Title with Montserrat</h1>
    <p>Paragraph with Open Sans</p>
</body>
</html>

Method 2: @import in CSS

/* Import from Google Fonts */
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap');

/* Multiple imports */
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;600;700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;600&display=swap');

/* Using the imported fonts */
body {
    font-family: 'Open Sans', sans-serif;
}

h1, h2, h3 {
    font-family: 'Montserrat', sans-serif;
}

Typography System Example with Google Fonts

/* Google Fonts import */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;500;600;700&display=swap');

:root {
    --font-primary: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    --font-display: 'Playfair Display', Georgia, serif;

    --text-xs: 0.75rem;
    --text-sm: 0.875rem;
    --text-base: 1rem;
    --text-lg: 1.125rem;
    --text-xl: 1.25rem;
    --text-2xl: 1.5rem;
    --text-3xl: 1.875rem;
    --text-4xl: 2.25rem;
    --text-5xl: 3rem;
}

body {
    font-family: var(--font-primary);
    font-size: var(--text-base);
    line-height: 1.6;
    color: #333;
}

/* Display font for headings */
h1, h2, h3, h4 {
    font-family: var(--font-display);
    line-height: 1.2;
}

h1 { font-size: var(--text-5xl); font-weight: 700; }
h2 { font-size: var(--text-4xl); font-weight: 600; }
h3 { font-size: var(--text-3xl); font-weight: 600; }
h4 { font-size: var(--text-2xl); font-weight: 500; }

/* Body text */
p { font-size: var(--text-base); line-height: 1.8; }

/* Lead paragraph */
.lead {
    font-size: var(--text-xl);
    font-weight: 300;
    line-height: 1.8;
    color: #555;
}

8. font Shorthand

The font property is a shorthand for several font properties.

/* font: style variant weight size/line-height family; */
.font-shorthand {
    font: italic bold 16px/1.5 'Arial', sans-serif;
}

/* Minimal: size and family are required */
.minimal {
    font: 16px 'Arial', sans-serif;
}

/* With all properties */
.complete {
    font: italic small-caps 700 20px/1.4 'Georgia', serif;
}

/* A few examples */
.example1 { font: 14px/1.6 'Helvetica Neue', Arial, sans-serif; }
.example2 { font: bold 1.5rem/1.2 'Montserrat', sans-serif; }
.example3 { font: 300 16px/1.8 'Inter', sans-serif; }

9. line-height

The line-height property sets the spacing between lines of text.

/* Numeric values (recommended) */
.tight { line-height: 1.2; }     /* For headings */
.normal { line-height: 1.5; }    /* For body text */
.loose { line-height: 1.8; }    /* For long-form text */
.relaxed { line-height: 2; }    /* For high readability */

/* Pixel values */
.fixed { line-height: 24px; }

/* Percentage */
.percentage { line-height: 150%; }

/* Unitless: recommended */
.good { line-height: 1.6; }     /* 160% of font-size */

/* Practical usage */
body {
    font-size: 16px;
    line-height: 1.6;  /* 25.6px */
}

h1 {
    font-size: 32px;
    line-height: 1.2;  /* 38.4px */
}

.small-text {
    font-size: 12px;
    line-height: 1.4;  /* 16.8px */
}

Practice: Typography System

/* Complete Typography System */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap');

:root {
    /* Font families */
    --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --font-serif: Georgia, 'Times New Roman', Times, serif;
    --font-mono: 'Courier New', Courier, monospace;

    /* Font sizes */
    --text-xs: clamp(0.75rem, 0.7rem + 0.25vw, 0.875rem);
    --text-sm: clamp(0.875rem, 0.8rem + 0.375vw, 1rem);
    --text-base: clamp(1rem, 0.9rem + 0.5vw, 1.125rem);
    --text-lg: clamp(1.125rem, 1rem + 0.625vw, 1.375rem);
    --text-xl: clamp(1.25rem, 1.1rem + 0.75vw, 1.625rem);
    --text-2xl: clamp(1.5rem, 1.25rem + 1.25vw, 2.125rem);
    --text-3xl: clamp(1.875rem, 1.5rem + 1.875vw, 2.75rem);
    --text-4xl: clamp(2.25rem, 1.75rem + 2.5vw, 3.5rem);
    --text-5xl: clamp(3rem, 2.25rem + 3.75vw, 4.5rem);

    /* Line heights */
    --leading-none: 1;
    --leading-tight: 1.25;
    --leading-snug: 1.375;
    --leading-normal: 1.5;
    --leading-relaxed: 1.625;
    --leading-loose: 2;

    /* Letter spacing */
    --tracking-tighter: -0.05em;
    --tracking-tight: -0.025em;
    --tracking-normal: 0;
    --tracking-wide: 0.025em;
    --tracking-wider: 0.05em;
}

/* Base typography */
body {
    font-family: var(--font-sans);
    font-size: var(--text-base);
    line-height: var(--leading-normal);
    color: #1a1a1a;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Headings */
h1, h2, h3, h4, h5, h6 {
    font-weight: 700;
    line-height: var(--leading-tight);
    letter-spacing: var(--tracking-tight);
    color: #111;
}

h1 { font-size: var(--text-5xl); }
h2 { font-size: var(--text-4xl); }
h3 { font-size: var(--text-3xl); }
h4 { font-size: var(--text-2xl); }
h5 { font-size: var(--text-xl); }
h6 { font-size: var(--text-lg); }

/* Paragraphs */
p {
    margin-bottom: 1.5em;
    line-height: var(--leading-relaxed);
}

/* Lead paragraph */
.lead {
    font-size: var(--text-xl);
    font-weight: 300;
    line-height: var(--leading-relaxed);
    color: #444;
    margin-bottom: 2em;
}

/* Links */
a {
    color: #3498db;
    text-decoration: none;
    transition: color 0.3s ease;
}

a:hover {
    color: #2980b9;
    text-decoration: underline;
}

/* Lists */
ul, ol {
    margin-bottom: 1.5em;
    padding-left: 1.5em;
}

li {
    margin-bottom: 0.5em;
    line-height: var(--leading-relaxed);
}

/* Blockquote */
blockquote {
    font-family: var(--font-serif);
    font-size: var(--text-xl);
    font-style: italic;
    line-height: var(--leading-relaxed);
    color: #555;
    border-left: 4px solid #3498db;
    padding-left: 1.5em;
    margin: 2em 0;
}

/* Code */
code {
    font-family: var(--font-mono);
    font-size: 0.9em;
    background-color: #f5f5f5;
    padding: 0.2em 0.4em;
    border-radius: 3px;
}

pre {
    font-family: var(--font-mono);
    font-size: var(--text-sm);
    line-height: var(--leading-relaxed);
    background-color: #2d2d2d;
    color: #f8f8f2;
    padding: 1.5em;
    border-radius: 8px;
    overflow-x: auto;
    margin: 2em 0;
}

pre code {
    background: none;
    padding: 0;
    color: inherit;
}

/* Small text */
small {
    font-size: var(--text-sm);
    color: #666;
}

/* Text utilities */
.text-center { text-align: center; }
.text-right { text-align: right; }
.text-justify { text-align: justify; }

.text-uppercase { text-transform: uppercase; }
.text-lowercase { text-transform: lowercase; }
.text-capitalize { text-transform: capitalize; }

.font-light { font-weight: 300; }
.font-normal { font-weight: 400; }
.font-medium { font-weight: 500; }
.font-semibold { font-weight: 600; }
.font-bold { font-weight: 700; }

.tracking-tight { letter-spacing: -0.025em; }
.tracking-normal { letter-spacing: 0; }
.tracking-wide { letter-spacing: 0.025em; }

.leading-none { line-height: 1; }
.leading-tight { line-height: 1.25; }
.leading-normal { line-height: 1.5; }
.leading-loose { line-height: 2; }

/* Responsive typography */
@media (max-width: 768px) {
    body {
        font-size: 1rem;
    }

    h1 { font-size: var(--text-3xl); }
    h2 { font-size: var(--text-2xl); }
    h3 { font-size: var(--text-xl); }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Typography System</title>
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap" rel="stylesheet">
    <style>
        /* CSS from the example above */
    </style>
</head>
<body>
    <article>
        <h1>Main Article Title</h1>
        <p class="lead">Lead paragraph with a larger font-size and a lighter weight to grab the reader's attention.</p>

        <h2>First Subtitle</h2>
        <p>A regular paragraph with a comfortable line-height for reading. Good typography makes content easier to digest and gives the website a professional impression.</p>

        <blockquote>
            "Typography is the voice of visual design."
        </blockquote>

        <h3>Small Subtitle</h3>
        <p>Use <code>font-family</code> to choose a typeface that matches the character of the website. Make sure the chosen font has <strong>various weight variations</strong> for different needs.</p>

        <ul>
            <li>Use <code>rem</code> for font sizes</li>
            <li>Use <code>line-height: 1.5</code> for body text</li>
            <li>Use <code>font-weight: 600-700</code> for headings</li>
        </ul>

        <small>Last updated: January 1, 2024</small>
    </article>
</body>
</html>

Summary

CSS provides a complete set of font properties: font-family for the typeface, font-size for the size (use rem), font-weight for the thickness, font-style for the style, font-variant for variations, @font-face for custom fonts, and line-height for the spacing between lines. Google Fonts is a popular source of free fonts. A good typography system uses custom properties for consistency and clamp() for responsiveness.