Skip to main content

Course Progress

Loading...

Working with Colors, Fonts, and Text Properties

Duration: 45 minutes
Module 1: CSS Basics

Learning Objectives

  • Master CSS styling techniques
  • Control visual presentation
  • Create attractive designs
  • Understand CSS best practices

Introduction

Colors, fonts, and text properties are the fundamental building blocks of visual design on the web. These properties allow you to establish the mood, tone, and personality of your website while ensuring readability and accessibility for your users.

                flowchart LR
                    A[Visual Design Fundamentals] --> B[Colors]
                    A --> C[Fonts]
                    A --> D[Text Properties]
                    
                    B --> B1[Color Models]
                    B --> B2[Color Values]
                    B --> B3[Color Functions]
                    
                    C --> C1[Font Families]
                    C --> C2[Font Properties]
                    C --> C3[Web Fonts]
                    
                    D --> D1[Text Styling]
                    D --> D2[Text Layout]
                    D --> D3[Text Decoration]
                    
                    style A fill:#f9d5e5,stroke:#333,stroke-width:2px
                    style B fill:#eeac99,stroke:#333,stroke-width:2px
                    style C fill:#e6d7b9,stroke:#333,stroke-width:2px
                    style D fill:#b6dcfe,stroke:#333,stroke-width:2px
                

The Canvas Analogy

Think of your website as a canvas:

  • Colors are like the paints you choose - they set the mood and evoke emotions
  • Fonts are like the brushes - they determine how the content is rendered and its personality
  • Text properties are like the techniques you use - they refine how the text appears and flows

Just as an artist carefully selects their materials and techniques, a web developer carefully chooses colors, fonts, and text properties to create a harmonious and effective visual experience.

Understanding Colors in CSS

Colors define the visual tone of your website and can significantly impact user experience, brand perception, and readability. CSS provides several ways to define colors, each with its own advantages.

Color Models

RGB Red Green Blue HSL Hue Saturation Lightness HEX #FF5733 Hexadecimal Color Value Examples RGB(255, 0, 0) HSL(0, 100%, 50%) #FF0000 RGB(70, 130, 180) HSL(207, 44%, 49%) #4682B4 RGB(138, 43, 226) HSL(271, 76%, 53%) #8A2BE2

RGB (Red, Green, Blue)

The RGB color model is an additive color model where red, green, and blue light are combined in various proportions to produce a wide array of colors.

/* RGB color values */
color: rgb(255, 0, 0);     /* Red */
color: rgb(0, 255, 0);     /* Green */
color: rgb(0, 0, 255);     /* Blue */
color: rgb(255, 255, 0);   /* Yellow (Red + Green) */
color: rgb(0, 255, 255);   /* Cyan (Green + Blue) */
color: rgb(255, 0, 255);   /* Magenta (Red + Blue) */
color: rgb(255, 255, 255); /* White (All colors at full intensity) */
color: rgb(0, 0, 0);       /* Black (No color) */
color: rgb(128, 128, 128); /* Gray (All colors at half intensity) */

RGBA (RGB with Alpha/Transparency)

RGBA extends the RGB color model by adding an alpha channel, which specifies the opacity of the color.

/* RGBA color values */
color: rgba(255, 0, 0, 1);    /* Solid red (fully opaque) */
color: rgba(255, 0, 0, 0.5);  /* Semi-transparent red (50% opacity) */
color: rgba(0, 0, 255, 0.25); /* Very transparent blue (25% opacity) */
background-color: rgba(0, 0, 0, 0.7); /* Semi-transparent black overlay */

HEX (Hexadecimal)

Hexadecimal color values are expressed as a hash sign (#) followed by six hexadecimal digits, representing the RGB components in the order red, green, blue.

/* HEX color values */
color: #FF0000;  /* Red */
color: #00FF00;  /* Green */
color: #0000FF;  /* Blue */
color: #FFFF00;  /* Yellow */
color: #00FFFF;  /* Cyan */
color: #FF00FF;  /* Magenta */
color: #FFFFFF;  /* White */
color: #000000;  /* Black */
color: #808080;  /* Gray */

/* Shorthand HEX (when pairs of digits are the same) */
color: #F00;     /* Same as #FF0000 (Red) */
color: #0F0;     /* Same as #00FF00 (Green) */
color: #00F;     /* Same as #0000FF (Blue) */

HSL (Hue, Saturation, Lightness)

HSL represents colors based on their hue, saturation, and lightness attributes, which is often more intuitive for designers to work with.

/* HSL color values */
color: hsl(0, 100%, 50%);     /* Red: 0° hue, 100% saturation, 50% lightness */
color: hsl(120, 100%, 50%);   /* Green: 120° hue, 100% saturation, 50% lightness */
color: hsl(240, 100%, 50%);   /* Blue: 240° hue, 100% saturation, 50% lightness */
color: hsl(60, 100%, 50%);    /* Yellow: 60° hue, 100% saturation, 50% lightness */
color: hsl(180, 100%, 50%);   /* Cyan: 180° hue, 100% saturation, 50% lightness */
color: hsl(300, 100%, 50%);   /* Magenta: 300° hue, 100% saturation, 50% lightness */
color: hsl(0, 0%, 100%);      /* White: any hue, 0% saturation, 100% lightness */
color: hsl(0, 0%, 0%);        /* Black: any hue, 0% saturation, 0% lightness */
color: hsl(0, 0%, 50%);       /* Gray: any hue, 0% saturation, 50% lightness */

HSLA (HSL with Alpha/Transparency)

HSLA extends the HSL color model by adding an alpha channel, specifying the opacity of the color.

/* HSLA color values */
color: hsla(0, 100%, 50%, 1);      /* Solid red (fully opaque) */
color: hsla(120, 100%, 50%, 0.5);  /* Semi-transparent green (50% opacity) */
color: hsla(240, 100%, 50%, 0.25); /* Very transparent blue (25% opacity) */

Named Colors

CSS provides a set of predefined color names that can be used for simplicity.

/* Named colors */
color: red;
color: green;
color: blue;
color: yellow;
color: cyan;
color: magenta;
color: white;
color: black;
color: gray;
color: silver;
color: gold;
color: purple;
color: orange;
/* And many more... */

Modern Color Functions

CSS Color Module Level 4 introduces more advanced color functions for greater control and flexibility.

rgba() and hsla() as Unified Functions

/* Modern syntax allows alpha as an optional parameter */
color: rgb(255 0 0 / 0.5);   /* Red at 50% opacity */
color: hsl(120 100% 50% / 0.7); /* Green at 70% opacity */

color-mix()

The color-mix() function allows you to mix two colors in different color spaces.

/* Mixing colors */
color: color-mix(in srgb, #ff0000, #0000ff);      /* Mix red and blue */
color: color-mix(in hsl, red 50%, blue);          /* Mix red and blue in HSL space */
color: color-mix(in srgb, red 25%, blue 75%);     /* 25% red, 75% blue */
background-color: color-mix(in srgb, currentColor, white 80%); /* Tint of current text color */

color-contrast()

The color-contrast() function (still experimental) selects the color with the highest contrast from a list.

/* Select highest contrast color for accessibility */
color: color-contrast(#background-color vs white, black, #767676);

color() Function

The color() function allows working in different color spaces beyond sRGB.

/* Colors in different color spaces */
color: color(display-p3 1 0.5 0);    /* Color in display-p3 color space */
color: color(xyz 0.1 0.2 0.3);       /* Color in CIE XYZ color space */

CSS Custom Properties for Colors

CSS variables (custom properties) allow you to define and reuse colors throughout your stylesheet.

/* Defining color variables */
:root {
    --primary-color: #4a90e2;
    --secondary-color: #5cb85c;
    --accent-color: #f0ad4e;
    --text-color: #333333;
    --light-text: #f8f9fa;
    --link-color: #0275d8;
    --hover-color: #025aa5;
}

/* Using color variables */
body {
    color: var(--text-color);
    background-color: white;
}

h1, h2, h3 {
    color: var(--primary-color);
}

.button-primary {
    background-color: var(--primary-color);
    color: var(--light-text);
}

.button-secondary {
    background-color: var(--secondary-color);
    color: var(--light-text);
}

a {
    color: var(--link-color);
}

a:hover {
    color: var(--hover-color);
}

Benefits of Using CSS Variables for Colors

  • Consistency: Ensure the same colors are used throughout the site
  • Maintainability: Change a color in one place rather than throughout the stylesheet
  • Theming: Create dark/light modes or different color schemes easily
  • Dynamic changes: Colors can be updated with JavaScript

Common Color Applications

Text Colors

/* Basic text coloring */
p {
    color: #333333;  /* Dark gray text color */
}

/* Different colors for different text elements */
h1 {
    color: #2c3e50;  /* Darker blue for headings */
}

.subtitle {
    color: #7f8c8d;  /* Lighter gray for less emphasis */
}

.highlight {
    color: #e74c3c;  /* Red for highlighting important text */
}

/* Link colors */
a {
    color: #3498db;         /* Blue for unvisited links */
}

a:visited {
    color: #8e44ad;         /* Purple for visited links */
}

a:hover, a:focus {
    color: #2980b9;         /* Darker blue when hovering/focusing */
}

a:active {
    color: #e74c3c;         /* Red when clicking/activating */
}

Background Colors

/* Basic background coloring */
body {
    background-color: #f5f5f5;  /* Light gray background */
}

/* Sections with different backgrounds */
header {
    background-color: #2c3e50;  /* Dark blue header */
    color: white;               /* White text on dark background */
}

.alternate-section {
    background-color: #ecf0f1;  /* Slightly darker gray for alternating sections */
}

/* Gradient backgrounds */
.gradient-bg {
    background: linear-gradient(to right, #3498db, #2c3e50);  /* Blue gradient */
    color: white;
}

/* Subtle background patterns */
.pattern-bg {
    background-color: #ffffff;
    background-image: radial-gradient(#000000 1px, transparent 1px);
    background-size: 20px 20px;
}

Border Colors

/* Basic border coloring */
.box {
    border: 1px solid #dddddd;  /* Light gray border */
}

/* Colored borders for different states */
.input {
    border: 2px solid #cccccc;  /* Default border */
}

.input:focus {
    border-color: #3498db;      /* Blue border when focused */
}

.input.error {
    border-color: #e74c3c;      /* Red border for error state */
}

.input.success {
    border-color: #2ecc71;      /* Green border for success state */
}

/* Colored border accents */
.card {
    border-left: 4px solid #f39c12;  /* Orange left border accent */
    border-top: 1px solid #eeeeee;
    border-right: 1px solid #eeeeee;
    border-bottom: 1px solid #eeeeee;
    padding: 20px;
}

Shadow Colors

/* Basic box shadows */
.card {
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);  /* Light shadow */
}

/* Colored shadows */
.primary-shadow {
    box-shadow: 0 4px 8px rgba(52, 152, 219, 0.3);  /* Blue shadow */
}

.warning-shadow {
    box-shadow: 0 4px 8px rgba(243, 156, 18, 0.3);  /* Orange shadow */
}

/* Text shadows */
.hero-text {
    color: white;
    text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);  /* Dark shadow for text on light backgrounds */
}

.glowing-text {
    color: #3498db;
    text-shadow: 0 0 10px rgba(52, 152, 219, 0.5);  /* Glow effect */
}

Color Best Practices

Accessibility Considerations

  • Contrast ratio: Maintain a contrast ratio of at least 4.5:1 between text and background colors (7:1 for enhanced accessibility)
  • Color blindness: Don't rely solely on color to convey important information
  • Text on images: Ensure text remains readable when placed on colored backgrounds or images

Color Schemes

  • Complementary: Colors opposite each other on the color wheel (e.g., blue and orange)
  • Analogous: Colors adjacent to each other on the color wheel (e.g., blue, blue-green, green)
  • Triadic: Three colors equally spaced on the color wheel (e.g., red, yellow, blue)
  • Monochromatic: Different shades and tints of a single color

Organizational Tips

  • Use variables: Define colors as CSS custom properties for consistency
  • Create a color system: Define primary, secondary, accent, and neutral colors
  • Document your colors: Maintain a color guide for your project

Example: Complete Color System

/* Comprehensive color system */
:root {
    /* Primary colors */
    --primary-100: #ebf8ff;
    --primary-200: #bee3f8;
    --primary-300: #90cdf4;
    --primary-400: #63b3ed;
    --primary-500: #4299e1;  /* Base primary color */
    --primary-600: #3182ce;
    --primary-700: #2b6cb0;
    --primary-800: #2c5282;
    --primary-900: #2a4365;
    
    /* Accent colors */
    --accent-100: #faf5ff;
    --accent-200: #e9d8fd;
    --accent-300: #d6bcfa;
    --accent-400: #b794f4;
    --accent-500: #9f7aea;  /* Base accent color */
    --accent-600: #805ad5;
    --accent-700: #6b46c1;
    --accent-800: #553c9a;
    --accent-900: #44337a;
    
    /* Neutral colors */
    --gray-100: #f7fafc;
    --gray-200: #edf2f7;
    --gray-300: #e2e8f0;
    --gray-400: #cbd5e0;
    --gray-500: #a0aec0;
    --gray-600: #718096;
    --gray-700: #4a5568;
    --gray-800: #2d3748;
    --gray-900: #1a202c;
    
    /* Feedback colors */
    --success: #48bb78;
    --warning: #ed8936;
    --error: #f56565;
    --info: #4299e1;
    
    /* Text colors */
    --text-primary: var(--gray-900);
    --text-secondary: var(--gray-700);
    --text-tertiary: var(--gray-500);
    --text-inverse: white;
}

/* Using the color system */
body {
    color: var(--text-primary);
    background-color: white;
}

.btn-primary {
    background-color: var(--primary-500);
    color: white;
}

.btn-primary:hover {
    background-color: var(--primary-600);
}

.alert-success {
    background-color: var(--success);
    color: white;
}

.alert-error {
    background-color: var(--error);
    color: white;
}

Working with Fonts in CSS

Typography plays a crucial role in web design, affecting readability, user experience, and the overall aesthetic of your site. CSS provides robust tools for controlling fonts and their appearance.

Font Families and Stacks

The font-family property specifies the typeface to use for text. It's recommended to provide a "font stack" with fallback options.

Generic Font Families

Generic Family Description Example
serif Fonts with small lines at the ends of characters Times New Roman, Georgia
sans-serif Fonts without serifs Arial, Helvetica, Verdana
monospace Fixed-width fonts where all characters take up the same space Courier New, Consolas
cursive Fonts that mimic human handwriting Comic Sans MS, Brush Script
fantasy Decorative fonts for titles Impact, Papyrus
system-ui The default user interface font on a platform Varies by operating system

Font Stacks

/* Basic font stacks */
body {
    font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}

h1, h2, h3 {
    font-family: Georgia, "Times New Roman", Times, serif;
}

code {
    font-family: "Courier New", Courier, monospace;
}

/* Modern system font stack */
body {
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
}

Note: Font names containing spaces must be wrapped in quotes (e.g., "Times New Roman").

Web Fonts

Web fonts allow you to use custom fonts beyond the standard system fonts. There are two main methods for implementing web fonts:

1. Using @font-face

/* Defining custom fonts with @font-face */
@font-face {
    font-family: 'MyCustomFont';
    src: url('fonts/mycustomfont.woff2') format('woff2'),
         url('fonts/mycustomfont.woff') format('woff');
    font-weight: normal;
    font-style: normal;
    font-display: swap;  /* Controls how the font is displayed while loading */
}

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

2. Using Google Fonts

<!-- In the HTML head section -->
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&family=Playfair+Display:ital@0;1&display=swap" rel="stylesheet">

/* In your CSS */
body {
    font-family: 'Roboto', sans-serif;
}

h1, h2, h3 {
    font-family: 'Playfair Display', serif;
}

3. Using @import in CSS

/* At the top of your CSS file */
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&family=Playfair+Display:ital@0;1&display=swap');

/* Then use the fonts */
body {
    font-family: 'Roboto', sans-serif;
}

h1, h2, h3 {
    font-family: 'Playfair Display', serif;
}

Note: While @import is convenient, it can block page rendering. The <link> method in the HTML head is generally preferred for performance.

Font Formats

  • WOFF2 - Web Open Font Format 2, best compression and performance
  • WOFF - Web Open Font Format, good browser support
  • TTF/OTF - TrueType/OpenType fonts, wider compatibility but larger size
  • EOT - Embedded OpenType, for older IE support

Variable Fonts

Variable fonts are a modern font format that allows multiple variations (weight, width, slant, etc.) in a single file.

/* Using a variable font */
@font-face {
    font-family: 'MyVariableFont';
    src: url('fonts/myvariablefont.woff2') format('woff2-variations');
    font-weight: 100 900;  /* Range of weights supported */
    font-style: normal;
}

/* Using different weights */
.light {
    font-family: 'MyVariableFont', sans-serif;
    font-weight: 300;
}

.regular {
    font-family: 'MyVariableFont', sans-serif;
    font-weight: 400;
}

.bold {
    font-family: 'MyVariableFont', sans-serif;
    font-weight: 700;
}

/* Using custom axes */
.custom-variation {
    font-family: 'MyVariableFont', sans-serif;
    font-variation-settings: 'wght' 450, 'wdth' 80;
}

Font Properties

font-size

Controls the size of the text. Can be specified in various units.

/* Absolute units */
.absolute-pixels {
    font-size: 16px;  /* Pixels */
}

.absolute-points {
    font-size: 12pt;  /* Points */
}

/* Relative units */
.relative-em {
    font-size: 1.2em;  /* Relative to parent element's font size */
}

.relative-rem {
    font-size: 1.2rem;  /* Relative to root element's font size */
}

.relative-vh {
    font-size: 3vh;  /* Relative to viewport height */
}

.relative-percent {
    font-size: 120%;  /* Percentage of parent element's font size */
}

/* Keyword values */
.keyword-small {
    font-size: small;
}

.keyword-medium {
    font-size: medium;
}

.keyword-large {
    font-size: large;
}

.keyword-larger {
    font-size: larger;  /* Relative to parent element */
}
Responsive Font Size Approach
/* Root element sizing for rem units */
:root {
    font-size: 16px;  /* Base font size */
}

/* Responsive scaling */
@media (max-width: 768px) {
    :root {
        font-size: 14px;  /* Smaller base size on small screens */
    }
}

/* Using rem units throughout */
h1 {
    font-size: 2.5rem;  /* 40px at base size */
}

h2 {
    font-size: 2rem;    /* 32px at base size */
}

p {
    font-size: 1rem;    /* 16px at base size */
}

.small-text {
    font-size: 0.875rem; /* 14px at base size */
}

font-weight

Specifies the thickness of characters in text.

/* Numeric weights */
.thin {
    font-weight: 100;
}

.light {
    font-weight: 300;
}

.normal {
    font-weight: 400;  /* Same as normal */
}

.medium {
    font-weight: 500;
}

.semi-bold {
    font-weight: 600;
}

.bold {
    font-weight: 700;  /* Same as bold */
}

.extra-bold {
    font-weight: 800;
}

.black {
    font-weight: 900;
}

/* Keyword values */
.normal-keyword {
    font-weight: normal;  /* 400 */
}

.bold-keyword {
    font-weight: bold;    /* 700 */
}

/* Relative values */
.bolder {
    font-weight: bolder;  /* Bolder than parent */
}

.lighter {
    font-weight: lighter; /* Lighter than parent */
}

font-style

Specifies whether text should be rendered in an italic or normal style.

/* Font style values */
.normal-style {
    font-style: normal;  /* Default */
}

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

.oblique {
    font-style: oblique;  /* Artificially slanted version */
}

font-variant

Controls alternate glyphs used in a font, such as small-caps.

/* Font variant values */
.normal-variant {
    font-variant: normal;  /* Default */
}

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

/* Modern property with more options */
.advanced-variant {
    font-variant: small-caps slashed-zero;
}

/* Individual properties */
.numeric-variant {
    font-variant-numeric: oldstyle-nums tabular-nums;
}

font-stretch

Controls the width of characters, from condensed to expanded.

/* Font stretch values */
.ultra-condensed {
    font-stretch: ultra-condensed;  /* 50% */
}

.condensed {
    font-stretch: condensed;  /* 75% */
}

.normal-stretch {
    font-stretch: normal;  /* 100% */
}

.expanded {
    font-stretch: expanded;  /* 125% */
}

.ultra-expanded {
    font-stretch: ultra-expanded;  /* 200% */
}

/* Percentage values */
.custom-stretch {
    font-stretch: 90%;
}

line-height

Controls the space between lines of text, also known as "leading".

/* Line height values */
.normal-line-height {
    line-height: normal;  /* Browser default, typically ~1.2 */
}

.specific-line-height {
    line-height: 1.5;  /* 1.5 times the font size (recommended) */
}

.line-height-px {
    line-height: 24px;  /* Absolute value - NOT recommended */
}

.line-height-percent {
    line-height: 150%;  /* Percentage of the font size */
}

/* Best practice for body text */
body {
    line-height: 1.5;  /* Good for readability */
}

/* Tighter line height for headings */
h1, h2, h3 {
    line-height: 1.2;
}

Note: For line-height, unitless values (like 1.5) are best practice as they're calculated based on the element's font size.

font Shorthand

The font shorthand property allows you to set multiple font properties in a single declaration.

/* Font shorthand syntax */
/* font: [font-style] [font-variant] [font-weight] [font-stretch] font-size[/line-height] font-family */

/* Examples */
.complete-shorthand {
    font: italic small-caps bold 16px/1.5 "Helvetica Neue", Arial, sans-serif;
}

.basic-shorthand {
    font: bold 14px Arial, sans-serif;  /* Style and variant default to normal */
}

/* Required properties: font-size and font-family */
.minimal-shorthand {
    font: 16px Georgia, serif;
}

Note: The font shorthand resets any omitted font properties to their initial values.

Advanced Font Features

font-feature-settings

Controls advanced typographic features in OpenType fonts.

/* Font feature settings */
.ligatures {
    font-feature-settings: "liga" 1;  /* Standard ligatures */
}

.old-style-figures {
    font-feature-settings: "onum" 1;  /* Old-style figures */
}

.stylistic-alternates {
    font-feature-settings: "salt" 1;  /* Stylistic alternates */
}

.small-caps-feature {
    font-feature-settings: "smcp" 1;  /* Small caps */
}

.multiple-features {
    font-feature-settings: "kern" 1, "liga" 1, "pnum" 1, "tnum" 0;
}

font-kerning

Controls the spacing between characters based on their shapes.

/* Font kerning */
.normal-kerning {
    font-kerning: normal;  /* Default, use font's kerning information */
}

.no-kerning {
    font-kerning: none;  /* Disable kerning */
}

.auto-kerning {
    font-kerning: auto;  /* Browser determines kerning */
}

font-optical-sizing

Adjusts the rendering of a font based on its size.

/* Font optical sizing */
.auto-optical-sizing {
    font-optical-sizing: auto;  /* Default, adjust rendering based on font size */
}

.no-optical-sizing {
    font-optical-sizing: none;  /* Disable optical sizing */
}

font-synthesis

Controls whether the browser can synthesize bold or italic font faces when they are not available.

/* Font synthesis */
.no-synthesis {
    font-synthesis: none;  /* Prevent synthetic bold and italic */
}

.weight-only {
    font-synthesis: weight;  /* Allow synthetic bold only */
}

.style-only {
    font-synthesis: style;  /* Allow synthetic italic only */
}

.allow-synthesis {
    font-synthesis: weight style;  /* Allow both (default) */
}

Common Font Applications

Creating a Type Scale

A type scale establishes a hierarchy and consistent sizing across your design.

/* Type scale based on the golden ratio (1.618) */
:root {
    --base-size: 1rem;  /* 16px */
    --scale-ratio: 1.618;
    
    --text-xs: calc(var(--base-size) / var(--scale-ratio));  /* ~0.62rem */
    --text-sm: calc(var(--text-xs) * var(--scale-ratio));    /* ~1rem */
    --text-md: calc(var(--text-sm) * var(--scale-ratio));    /* ~1.62rem */
    --text-lg: calc(var(--text-md) * var(--scale-ratio));    /* ~2.62rem */
    --text-xl: calc(var(--text-lg) * var(--scale-ratio));    /* ~4.24rem */
    --text-xxl: calc(var(--text-xl) * var(--scale-ratio));   /* ~6.85rem */
}

/* Using the type scale */
.caption {
    font-size: var(--text-xs);
}

body {
    font-size: var(--text-sm);
}

h3 {
    font-size: var(--text-md);
}

h2 {
    font-size: var(--text-lg);
}

h1 {
    font-size: var(--text-xl);
}

.hero-text {
    font-size: var(--text-xxl);
}

Responsive Typography

Adjusts font sizes based on screen size for optimal readability.

/* Responsive typography with fluid scaling */
html {
    font-size: 16px;
}

/* Fluid typography using viewport width */
h1 {
    font-size: calc(1.5rem + 2vw);  /* Scales with viewport width */
    /* 1.5rem (24px) minimum, grows by 2% of viewport width */
}

p {
    font-size: calc(1rem + 0.3vw);  /* Subtly scales with viewport */
}

/* Responsive typography with media queries */
@media (max-width: 768px) {
    html {
        font-size: 14px;  /* Smaller base size on tablets */
    }
    
    h1 {
        font-size: 2rem;  /* 28px at 14px base */
    }
}

@media (max-width: 480px) {
    html {
        font-size: 12px;  /* Even smaller on phones */
    }
}

Font Pairing

Combining complementary fonts for headings and body text.

/* Classic serif and sans-serif pairing */
h1, h2, h3, h4, h5, h6 {
    font-family: 'Playfair Display', Georgia, serif;
    font-weight: 700;
}

body {
    font-family: 'Source Sans Pro', Arial, sans-serif;
    font-weight: 400;
}

/* Sans-serif heading with serif body */
h1, h2, h3, h4, h5, h6 {
    font-family: 'Montserrat', Arial, sans-serif;
    font-weight: 700;
    letter-spacing: -0.02em;  /* Tighter letter spacing for headings */
}

body {
    font-family: 'Merriweather', Georgia, serif;
    font-weight: 400;
    letter-spacing: 0.01em;  /* Slightly looser for body text */
}

Font Performance Considerations

  • Limit font families: Using too many fonts increases load time
  • Subset fonts: Include only the characters you need
  • Preload critical fonts: Use the preload hint for important fonts
  • Font display: Use font-display to control rendering behavior during loading
  • System fonts: Consider system font stacks for better performance
/* Preloading critical fonts */
<link rel="preload" href="fonts/critical-font.woff2" as="font" type="font/woff2" crossorigin>

/* Controlling font display behavior */
@font-face {
    font-family: 'MyFont';
    src: url('fonts/myfont.woff2') format('woff2');
    font-weight: normal;
    font-style: normal;
    font-display: swap;  /* Show fallback font until custom font loads, then swap */
}

/* Other font-display options:
   - auto: Browser default behavior
   - block: Brief invisible text, then custom font (FOIT)
   - swap: Fallback font, then custom font when loaded (FOUT)
   - fallback: Brief invisible text, then fallback if custom font takes too long
   - optional: Brief invisible text, may not use custom font if too slow
*/

Text Properties in CSS

CSS provides numerous properties to control how text is rendered, aligned, transformed, and decorated. These properties help create readable, visually appealing typography.

Text Alignment and Direction

text-align

Controls the horizontal alignment of text within its container.

/* Text alignment */
.text-left {
    text-align: left;  /* Default for LTR languages */
}

.text-center {
    text-align: center;  /* Centered text */
}

.text-right {
    text-align: right;  /* Right-aligned text */
}

.text-justify {
    text-align: justify;  /* Text is justified (flush left and right) */
}

text-align-last

Controls the alignment of the last line in a justified block of text.

/* Last line alignment for justified text */
.text-justify-last-center {
    text-align: justify;
    text-align-last: center;  /* Last line is centered */
}

.text-justify-last-right {
    text-align: justify;
    text-align-last: right;   /* Last line is right-aligned */
}

text-direction and unicode-bidi

Controls the direction of text, primarily for multilingual sites.

/* Text direction */
.rtl-text {
    direction: rtl;  /* Right-to-left (for Arabic, Hebrew, etc.) */
}

.ltr-text {
    direction: ltr;  /* Left-to-right (default) */
}

/* For embedded opposite-direction text */
.embedded-rtl {
    direction: rtl;
    unicode-bidi: embed;
}

writing-mode

Defines whether lines of text are laid out horizontally or vertically.

/* Writing mode */
.horizontal-tb {
    writing-mode: horizontal-tb;  /* Standard horizontal, top-to-bottom */
}

.vertical-rl {
    writing-mode: vertical-rl;  /* Vertical, right-to-left (traditional Chinese, Japanese) */
}

.vertical-lr {
    writing-mode: vertical-lr;  /* Vertical, left-to-right */
}

Text Spacing

letter-spacing

Controls the space between characters (kerning).

/* Letter spacing */
.normal-letter-spacing {
    letter-spacing: normal;  /* Default */
}

.tight-letter-spacing {
    letter-spacing: -0.05em;  /* Negative value decreases spacing */
}

.loose-letter-spacing {
    letter-spacing: 0.1em;  /* Positive value increases spacing */
}

/* Practical examples */
h1, h2, h3 {
    letter-spacing: -0.02em;  /* Slightly tighter for headings */
}

.all-caps {
    text-transform: uppercase;
    letter-spacing: 0.05em;  /* Increased spacing for legibility of uppercase text */
}

word-spacing

Controls the space between words.

/* Word spacing */
.normal-word-spacing {
    word-spacing: normal;  /* Default */
}

.tight-word-spacing {
    word-spacing: -0.1em;  /* Negative value decreases spacing */
}

.loose-word-spacing {
    word-spacing: 0.2em;  /* Positive value increases spacing */
}

text-indent

Controls the indentation of the first line of a block of text.

/* Text indent */
.paragraph-indent {
    text-indent: 2em;  /* Positive value indents the first line */
}

.hanging-indent {
    text-indent: -2em;  /* Negative value creates a hanging indent */
    padding-left: 2em;  /* Offset to prevent text running off the edge */
}

/* Traditional book paragraph styling */
.book-style p {
    text-indent: 1.5em;
    margin-top: 0;
    margin-bottom: 0;
}

white-space

Controls how whitespace within an element is handled.

/* White space handling */
.normal-white-space {
    white-space: normal;  /* Default: collapses whitespace, wraps text */
}

.pre-white-space {
    white-space: pre;  /* Preserves whitespace, no wrapping (like HTML <pre>) */
}

.nowrap-white-space {
    white-space: nowrap;  /* Collapses whitespace, prevents wrapping */
}

.pre-wrap-white-space {
    white-space: pre-wrap;  /* Preserves whitespace, allows wrapping */
}

.pre-line-white-space {
    white-space: pre-line;  /* Collapses whitespace, preserves line breaks, wraps */
}

word-break and overflow-wrap

Controls how words should break across lines.

/* Word breaking */
.normal-word-break {
    word-break: normal;  /* Default */
}

.break-all-word-break {
    word-break: break-all;  /* Break anywhere, even within words */
}

.keep-all-word-break {
    word-break: keep-all;  /* Don't break non-CJK text */
}

.break-word-overflow {
    overflow-wrap: break-word;  /* Break long words if needed to prevent overflow */
}

/* Common long-word wrapping solution */
.wrap-long-words {
    word-break: normal;
    overflow-wrap: break-word;
    hyphens: auto;  /* Add hyphens when breaking words, where supported */
}

Text Decoration and Styling

text-decoration

Adds decorative lines to text.

/* Text decoration */
.underline {
    text-decoration: underline;  /* Underlined text */
}

.overline {
    text-decoration: overline;  /* Line above text */
}

.line-through {
    text-decoration: line-through;  /* Strikethrough text */
}

.no-decoration {
    text-decoration: none;  /* Remove decoration (e.g., from links) */
}

/* Multiple decorations */
.multi-decoration {
    text-decoration: underline overline;
}

/* Modern individual properties */
.styled-underline {
    text-decoration-line: underline;
    text-decoration-style: wavy;
    text-decoration-color: #ff3366;
    text-decoration-thickness: 2px;
}

/* Shorthand for modern browsers */
.styled-underline-shorthand {
    text-decoration: wavy underline #ff3366 2px;
}

text-transform

Controls the capitalization of text.

/* Text transformation */
.uppercase {
    text-transform: uppercase;  /* ALL CAPS */
}

.lowercase {
    text-transform: lowercase;  /* all lowercase */
}

.capitalize {
    text-transform: capitalize;  /* First Letter Of Each Word */
}

.normal-case {
    text-transform: none;  /* Default, no transformation */
}

text-shadow

Adds shadow effects to text.

/* Text shadow */
.simple-shadow {
    text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
    /* Syntax: h-offset v-offset blur-radius color */
}

.text-outline {
    text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
    color: white;  /* Creates an outline effect */
}

.glow-effect {
    text-shadow: 0 0 10px rgba(0, 255, 255, 0.8);  /* Blue glow */
}

.multi-shadow {
    text-shadow: 1px 1px 2px #000, 0 0 1em #00f, 0 0 0.2em #00f;  /* Multiple shadows */
}

font-variant Alternatives

Modern properties that provide more granular control than the font-variant shorthand.

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

.numeric-variants {
    font-variant-numeric: oldstyle-nums tabular-nums;  /* Old-style figures with equal widths */
}

.ligature-variants {
    font-variant-ligatures: common-ligatures discretionary-ligatures;  /* Enable common and special ligatures */
}

.position-variants {
    font-variant-position: sub;  /* Subscript, if available in the font */
}

Text Overflow and Truncation

text-overflow

Controls how overflowed content is signaled to users. Works with overflow properties.

/* Text overflow handling */
.ellipsis-overflow {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;  /* Show "..." for overflowed text */
}

.clip-overflow {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: clip;  /* Simply clip overflowed text */
}

/* Multi-line ellipsis (using WebKit's non-standard properties) */
.multi-line-ellipsis {
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 3;  /* Show only 3 lines */
    -webkit-box-orient: vertical;
    text-overflow: ellipsis;
}

Multi-line Truncation Alternatives

Cross-browser solutions for truncating multi-line text.

/* Line clamp with fallback for non-WebKit browsers */
.line-clamp {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    
    /* Fallback for browsers that don't support -webkit-line-clamp */
    max-height: 4.5em;  /* line-height × number of lines */
    position: relative;
}

/* Add ellipsis using pseudo-element (more compatible fallback) */
.line-clamp-fallback {
    overflow: hidden;
    max-height: 4.5em;  /* line-height × number of lines */
    position: relative;
}

.line-clamp-fallback::after {
    content: "...";
    position: absolute;
    bottom: 0;
    right: 0;
    padding: 0 5px 0 20px;
    background: linear-gradient(to right, transparent, white 30%);
}

Vertical Alignment

vertical-align

Controls the vertical alignment of inline or table-cell elements. Does not work for block-level elements.

/* Vertical alignment for inline elements */
.baseline {
    vertical-align: baseline;  /* Default, align the baseline of the element with the baseline of the parent */
}

.sub {
    vertical-align: sub;  /* Subscript alignment */
}

.super {
    vertical-align: super;  /* Superscript alignment */
}

.text-top {
    vertical-align: text-top;  /* Align with the top of the parent's font */
}

.text-bottom {
    vertical-align: text-bottom;  /* Align with the bottom of the parent's font */
}

.middle {
    vertical-align: middle;  /* Align with the middle of the parent */
}

.top {
    vertical-align: top;  /* Align with the top of the line */
}

.bottom {
    vertical-align: bottom;  /* Align with the bottom of the line */
}

/* Using percentage or length values */
.custom-vertical {
    vertical-align: 0.2em;  /* Raise the element by 0.2em */
}

.percent-vertical {
    vertical-align: 25%;  /* Raise by 25% of the line-height */
}

Note: For centering block-level elements vertically, you would use other techniques like flexbox, grid, or positioning.

Multi-column Text

column-count and column-width

Creates newspaper-style columns of text.

/* Multi-column layout */
.two-columns {
    column-count: 2;  /* Split into 2 columns */
    column-gap: 2em;  /* Space between columns */
}

.three-columns {
    column-count: 3;  /* Split into 3 columns */
    column-gap: 2em;
    column-rule: 1px solid #ddd;  /* Line between columns */
}

/* Responsive columns based on width */
.responsive-columns {
    column-width: 20em;  /* Create as many columns as fit with at least 20em width */
    column-gap: 2em;
}

/* Column spanning */
.column-heading {
    column-span: all;  /* Make a heading span all columns */
}

break-inside

Controls how page/column/region breaks should occur within elements.

/* Prevent elements from breaking across columns */
.no-break {
    break-inside: avoid;  /* Modern property */
    page-break-inside: avoid;  /* Legacy property for compatibility */
}

Hyphenation and Language

hyphens

Controls whether hyphenation is used when text wraps across multiple lines.

/* Hyphenation control */
.auto-hyphens {
    hyphens: auto;  /* Automatically hyphenate where appropriate */
    /* Note: requires lang attribute on the element or its ancestors */
}

.manual-hyphens {
    hyphens: manual;  /* Only hyphenate at specified points (using ­ entity) */
}

.no-hyphens {
    hyphens: none;  /* No hyphenation */
}

Note: For automatic hyphenation to work correctly, you should specify the language of your content using the lang attribute in HTML:

<p lang="en">This text might be hyphenated.</p>
<p lang="de">Dieser Text könnte mit Bindestrichen versehen werden.</p>

lang Attribute and Typography

The lang attribute affects how text is rendered, including hyphenation and quotation marks.

/* CSS targeting different languages */
:lang(fr) q {
    quotes: "«" "»";  /* French style quotation marks */
}

:lang(de) q {
    quotes: "„" """;  /* German style quotation marks */
}

/* Using the :lang pseudo-class */
:lang(ja) {
    line-height: 1.8;  /* Increased line height for Japanese text */
}

Quotes and Counters

quotes

Specifies the quotation marks to use for the q element and for generated content.

/* Quotation marks */
q {
    quotes: """ """ "'" "'";  /* Primary and nested quotes */
}

/* Custom quotation style */
.custom-quotes {
    quotes: "❝" "❞" "❛" "❜";
}

/* Generating quotes with pseudo-elements */
q::before {
    content: open-quote;
}

q::after {
    content: close-quote;
}

counters

Creates automatic numbering with CSS.

/* Basic counters */
body {
    counter-reset: section;  /* Initialize a counter named "section" */
}

h2 {
    counter-increment: section;  /* Increment the section counter */
}

h2::before {
    content: "Section " counter(section) ": ";  /* Display the counter */
}

/* Nested counters */
ol {
    counter-reset: item;
}

li {
    display: block;
    counter-increment: item;
}

li::before {
    content: counters(item, ".") " ";  /* Creates nested numbering like 1.1, 1.2, etc. */
}

Advanced Text Effects

text-stroke

WebKit/Blink-specific property that adds an outline to text.

/* Text stroke (non-standard, WebKit only) */
.text-outline {
    -webkit-text-stroke: 1px black;
    color: white;  /* Text color */
}

/* Transparent text with outline */
.outline-only {
    -webkit-text-stroke: 1px black;
    color: transparent;
}

Note: text-stroke is non-standard. For better cross-browser support, consider using text-shadow to create outline effects.

text-fill-color

WebKit/Blink-specific property that sets the fill color of text.

/* Text fill color (non-standard, WebKit only) */
.gradient-text {
    background: linear-gradient(to right, #833ab4, #fd1d1d, #fcb045);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
}

background-clip: text

Clips the background to the shape of the text.

/* Modern syntax for gradient text (with fallbacks) */
.modern-gradient-text {
    /* Fallback */
    color: #833ab4;
    
    /* Gradient text */
    background: linear-gradient(to right, #833ab4, #fd1d1d, #fcb045);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent; /* Modern browsers */
}

mask-image

Creates text with a pattern or image showing through.

/* Text with image showing through */
.image-text {
    font-size: 6rem;
    font-weight: bold;
    color: #fff; /* Fallback */
    background-color: #000;
    
    /* Image mask */
    -webkit-mask-image: url('pattern.png');
    mask-image: url('pattern.png');
    -webkit-mask-repeat: repeat;
    mask-repeat: repeat;
}

Practical Examples: Putting It All Together

Modern Blog Typography

/* Modern blog typography */
:root {
    /* Color palette */
    --text-primary: #333333;
    --text-secondary: #666666;
    --accent-color: #4a90e2;
    --bg-color: #ffffff;
    --bg-secondary: #f7f9fc;
    
    /* Type scale */
    --base-size: 1.125rem; /* 18px base font size */
    --scale: 1.25;
    --h1: calc(var(--base-size) * var(--scale) * var(--scale) * var(--scale) * var(--scale));
    --h2: calc(var(--base-size) * var(--scale) * var(--scale) * var(--scale));
    --h3: calc(var(--base-size) * var(--scale) * var(--scale));
    --h4: calc(var(--base-size) * var(--scale));
    --small: calc(var(--base-size) / var(--scale));
}

/* Base styles */
body {
    font-family: "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
    font-size: var(--base-size);
    line-height: 1.6;
    color: var(--text-primary);
    background-color: var(--bg-color);
}

/* Heading typography */
h1, h2, h3, h4, h5, h6 {
    font-family: "Playfair Display", Georgia, serif;
    font-weight: 700;
    line-height: 1.2;
    margin-top: 1.5em;
    margin-bottom: 0.5em;
    color: var(--text-primary);
}

h1 {
    font-size: var(--h1);
    letter-spacing: -0.03em;
}

h2 {
    font-size: var(--h2);
    letter-spacing: -0.02em;
}

h3 {
    font-size: var(--h3);
    letter-spacing: -0.01em;
}

h4 {
    font-size: var(--h4);
}

/* Article content */
.article {
    max-width: 40rem;
    margin: 0 auto;
    padding: 1rem;
}

.article p {
    margin-bottom: 1.5em;
}

/* First paragraph larger (lead paragraph) */
.article > p:first-of-type {
    font-size: var(--h4);
    color: var(--text-secondary);
    line-height: 1.5;
}

/* Quotes */
blockquote {
    border-left: 4px solid var(--accent-color);
    padding-left: 1.5rem;
    margin-left: 0;
    margin-right: 0;
    font-style: italic;
    color: var(--text-secondary);
}

/* Links */
a {
    color: var(--accent-color);
    text-decoration: none;
    border-bottom: 1px solid transparent;
    transition: border-color 0.2s ease;
}

a:hover {
    border-bottom-color: var(--accent-color);
}

/* Small text */
small, .meta {
    font-size: var(--small);
    color: var(--text-secondary);
}

/* Code blocks */
pre, code {
    font-family: "Source Code Pro", Consolas, Monaco, monospace;
    font-size: 0.9em;
    background-color: var(--bg-secondary);
    border-radius: 3px;
}

code {
    padding: 0.2em 0.4em;
}

pre {
    padding: 1rem;
    overflow-x: auto;
}

pre code {
    padding: 0;
    background-color: transparent;
}

Color Theme Switcher (Light/Dark Mode)

/* Color theme with auto dark mode and manual toggle */
:root {
    /* Light theme (default) */
    --bg-color: #ffffff;
    --bg-secondary: #f5f7fa;
    --text-primary: #2d3748;
    --text-secondary: #718096;
    --accent-color: #4a5568;
    --border-color: #e2e8f0;
    --shadow-color: rgba(0, 0, 0, 0.1);
}

/* Dark theme colors */
[data-theme="dark"] {
    --bg-color: #1a202c;
    --bg-secondary: #2d3748;
    --text-primary: #f7fafc;
    --text-secondary: #a0aec0;
    --accent-color: #63b3ed;
    --border-color: #4a5568;
    --shadow-color: rgba(0, 0, 0, 0.3);
}

/* Media query for automatic dark mode */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --bg-color: #1a202c;
        --bg-secondary: #2d3748;
        --text-primary: #f7fafc;
        --text-secondary: #a0aec0;
        --accent-color: #63b3ed;
        --border-color: #4a5568;
        --shadow-color: rgba(0, 0, 0, 0.3);
    }
}

/* Apply theme colors */
body {
    color: var(--text-primary);
    background-color: var(--bg-color);
    transition: background-color 0.3s ease, color 0.3s ease;
}

.card {
    background-color: var(--bg-color);
    border: 1px solid var(--border-color);
    box-shadow: 0 4px 6px var(--shadow-color);
    padding: 1.5rem;
    margin-bottom: 1.5rem;
}

.card h3 {
    color: var(--text-primary);
    margin-top: 0;
}

.card p {
    color: var(--text-secondary);
}

/* Theme toggle button */
.theme-toggle {
    background-color: var(--bg-secondary);
    color: var(--text-primary);
    border: 1px solid var(--border-color);
    padding: 0.5rem 1rem;
    border-radius: 4px;
    cursor: pointer;
}

/* Example implementation of theme switcher with JavaScript:
document.querySelector('.theme-toggle').addEventListener('click', function() {
    const currentTheme = document.documentElement.getAttribute('data-theme');
    if (currentTheme === 'dark') {
        document.documentElement.setAttribute('data-theme', 'light');
    } else {
        document.documentElement.setAttribute('data-theme', 'dark');
    }
});
*/

Modern Text Effects

/* Collection of modern text effects */

/* Gradient text */
.gradient-text {
    font-size: 3rem;
    font-weight: bold;
    background: linear-gradient(45deg, #12c2e9, #c471ed, #f64f59);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
}

/* Glowing text */
.glow-text {
    color: #fff;
    font-size: 3rem;
    font-weight: bold;
    text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 15px #0073e6, 0 0 20px #0073e6, 0 0 25px #0073e6;
}

/* Text with 3D effect */
.text-3d {
    font-size: 3rem;
    font-weight: bold;
    color: #fcfcfc;
    text-shadow: 0 1px 0 #c0c0c0,
                 0 2px 0 #b0b0b0,
                 0 3px 0 #a0a0a0,
                 0 4px 0 #909090,
                 0 5px 10px rgba(0, 0, 0, 0.6);
}

/* Retro wave text */
.retro-text {
    font-size: 3rem;
    font-weight: bold;
    color: #fff;
    background-color: #000;
    padding: 0.5em;
    text-shadow: 0.05em 0 0 rgba(255, 0, 0, 0.75),
                -0.025em -0.05em 0 rgba(0, 255, 0, 0.75),
                0.025em 0.05em 0 rgba(0, 0, 255, 0.75);
    animation: retro 2s ease infinite;
}

@keyframes retro {
    0% { text-shadow: 0.05em 0 0 rgba(255, 0, 0, 0.75),
                     -0.05em -0.025em 0 rgba(0, 255, 0, 0.75),
                      0.025em 0.05em 0 rgba(0, 0, 255, 0.75); }
    14% { text-shadow: 0.05em 0 0 rgba(255, 0, 0, 0.75),
                      -0.05em -0.025em 0 rgba(0, 255, 0, 0.75),
                       0.025em 0.05em 0 rgba(0, 0, 255, 0.75); }
    15% { text-shadow: -0.05em -0.025em 0 rgba(255, 0, 0, 0.75),
                        0.025em 0.025em 0 rgba(0, 255, 0, 0.75),
                       -0.05em -0.05em 0 rgba(0, 0, 255, 0.75); }
    49% { text-shadow: -0.05em -0.025em 0 rgba(255, 0, 0, 0.75),
                        0.025em 0.025em 0 rgba(0, 255, 0, 0.75),
                       -0.05em -0.05em 0 rgba(0, 0, 255, 0.75); }
    50% { text-shadow: 0.025em 0.05em 0 rgba(255, 0, 0, 0.75),
                        0.05em 0 0 rgba(0, 255, 0, 0.75),
                        0 -0.05em 0 rgba(0, 0, 255, 0.75); }
    99% { text-shadow: 0.025em 0.05em 0 rgba(255, 0, 0, 0.75),
                        0.05em 0 0 rgba(0, 255, 0, 0.75),
                        0 -0.05em 0 rgba(0, 0, 255, 0.75); }
    100% { text-shadow: -0.025em 0 0 rgba(255, 0, 0, 0.75),
                        -0.025em -0.025em 0 rgba(0, 255, 0, 0.75),
                        -0.025em -0.05em 0 rgba(0, 0, 255, 0.75); }
}

/* Highlight text animaton */
.highlight-text {
    font-size: 2rem;
    display: inline;
    background: linear-gradient(120deg, rgba(255, 220, 0, 0.5) 0%, rgba(255, 220, 0, 0.5) 100%);
    background-repeat: no-repeat;
    background-size: 0% 100%;
    background-position: 0 90%;
    transition: background-size 0.5s ease;
}

.highlight-text:hover {
    background-size: 100% 100%;
}

Responsive Typography System

/* Comprehensive responsive typography system */

/* Base settings */
:root {
    /* Base sizes for different screen categories */
    --base-font-size-desktop: 1.125rem;  /* 18px */
    --base-font-size-tablet: 1rem;       /* 16px */
    --base-font-size-mobile: 0.875rem;   /* 14px */
    
    /* Scale ratio */
    --ratio: 1.25;
    
    /* Fluid typography transitions */
    --fluid-bp-tablet: 768px;
    --fluid-bp-desktop: 1366px;
    --fluid-min: 0.875;  /* 14px relative to 16px browser default */
    --fluid-max: 1.125;  /* 18px relative to 16px browser default */
}

/* Set base font size for different devices */
html {
    /* Default (mobile) */
    font-size: var(--base-font-size-mobile);
    
    /* Tablet */
    @media (min-width: 768px) {
        font-size: var(--base-font-size-tablet);
    }
    
    /* Desktop */
    @media (min-width: 1366px) {
        font-size: var(--base-font-size-desktop);
    }
}

/* Alternative: Fluid typography approach */
html {
    font-size: calc(var(--fluid-min) * 1rem);
}

@media screen and (min-width: 768px) {
    html {
        font-size: calc(var(--fluid-min) * 1rem + (var(--fluid-max) - var(--fluid-min)) * (100vw - var(--fluid-bp-tablet)) / (var(--fluid-bp-desktop) - var(--fluid-bp-tablet)));
    }
}

@media screen and (min-width: 1366px) {
    html {
        font-size: calc(var(--fluid-max) * 1rem);
    }
}

/* Typography scale (using the ratio) */
h1, .h1 {
    font-size: calc(1rem * var(--ratio) * var(--ratio) * var(--ratio) * var(--ratio));
    line-height: 1.1;
    margin-top: 0;
    margin-bottom: 0.5em;
}

h2, .h2 {
    font-size: calc(1rem * var(--ratio) * var(--ratio) * var(--ratio));
    line-height: 1.15;
    margin-top: 1em;
    margin-bottom: 0.5em;
}

h3, .h3 {
    font-size: calc(1rem * var(--ratio) * var(--ratio));
    line-height: 1.2;
    margin-top: 1em;
    margin-bottom: 0.5em;
}

h4, .h4 {
    font-size: calc(1rem * var(--ratio));
    line-height: 1.25;
    margin-top: 1em;
    margin-bottom: 0.5em;
}

p, ul, ol, pre, table, blockquote {
    font-size: 1rem;
    line-height: 1.6;
    margin-top: 0;
    margin-bottom: 1.25em;
}

small, .small {
    font-size: calc(1rem / var(--ratio));
    line-height: 1.4;
}

/* Responsive adjustments */
@media (max-width: 480px) {
    h1, .h1 {
        font-size: calc(1rem * var(--ratio) * var(--ratio) * var(--ratio));
    }
    
    h2, .h2 {
        font-size: calc(1rem * var(--ratio) * var(--ratio));
    }
    
    h3, .h3 {
        font-size: calc(1rem * var(--ratio));
    }
    
    h4, .h4 {
        font-size: calc(1rem * 1.1);
    }
}

Accessibility Considerations

Color Contrast

Ensuring sufficient contrast between text and background colors is crucial for readability and accessibility.

WCAG Guidelines

  • AA Level (minimum standard):
    • Normal text: contrast ratio of at least 4.5:1
    • Large text (18pt or 14pt bold and larger): contrast ratio of at least 3:1
  • AAA Level (enhanced standard):
    • Normal text: contrast ratio of at least 7:1
    • Large text: contrast ratio of at least 4.5:1

Good Practices

/* Accessible color combinations */
/* Good contrast (4.5:1 or higher) */
.accessible-text {
    color: #333333; /* Dark gray text */
    background-color: #ffffff; /* White background */
}

/* Avoid low contrast */
.poor-contrast {
    color: #999999; /* Light gray text - avoid on white */
    background-color: #ffffff;
}

/* Better alternative for light backgrounds */
.better-contrast {
    color: #595959; /* Darker gray that meets contrast requirements */
    background-color: #ffffff;
}

/* Use custom properties for easy maintenance */
:root {
    --text-regular: #333333;
    --text-muted: #595959; /* Accessible muted text */
    --background-primary: #ffffff;
    --background-secondary: #f5f5f5;
    --accent-color: #0056b3; /* Accessible blue */
}

Contrast Checking Tools

  • WebAIM Contrast Checker
  • Colour Contrast Analyser
  • Chrome Developer Tools Accessibility Audit
  • Contrast browser extension

Font Size and Readability

Guidelines

  • Base font size: At least 16px (1rem) for body text
  • Line spacing: At least 1.5 times the font size
  • Letter spacing: Not too compressed
  • Paragraph spacing: At least 1.5 times larger than line spacing
  • Line length: 50-75 characters per line

Good Practices

/* Accessible text styling */
body {
    font-family: "Open Sans", Arial, sans-serif;
    font-size: 1rem; /* 16px */
    line-height: 1.5;
    color: #333333;
}

p {
    margin-bottom: 1.5em; /* Adequate paragraph spacing */
    max-width: 70ch; /* Approx. 70 characters per line */
}

/* Allow text resizing */
html {
    font-size: 100%; /* Allows browsers to resize text */
}

/* Avoid font sizes below 14px */
.small {
    font-size: 0.875rem; /* 14px */
}

/* Ensure text remains accessible when user zooms */
@media screen and (max-width: 767px) {
    body {
        font-size: 1rem; /* Maintain minimum 16px even on small screens */
    }
}

Responsive and Adaptable Text

Good Practices

/* Ensure text scales properly */
html {
    font-size: 100%; /* Allow user font size preferences */
}

/* Use relative units for text */
body {
    font-size: 1rem;
}

h1 {
    font-size: 2rem; /* Relative to root element */
}

/* Don't use fixed values for font size */
.avoid {
    font-size: 16px; /* Avoid fixed pixel sizes */
}

.better {
    font-size: 1rem; /* Use relative units */
}

/* Make sure text scales on different devices */
@media (max-width: 767px) {
    h1 {
        font-size: 1.75rem; /* Smaller on mobile but still relatively sized */
    }
}

/* Support user preferences */
@media (prefers-reduced-motion: reduce) {
    * {
        animation-duration: 0.01ms !important;
        transition-duration: 0.01ms !important;
    }
}

/* Support high contrast mode */
@media (forced-colors: active) {
    button {
        border: 1px solid currentColor;
    }
}

Color Blindness Considerations

Good Practices

/* Don't rely on color alone to convey information */

/* Bad: Using only color for state */
.error-text-bad {
    color: red; /* Some users can't distinguish red */
}

/* Good: Using color AND another visual indicator */
.error-text-good {
    color: #d32f2f; /* Accessible red */
    padding-left: 1.5em;
    position: relative;
}

.error-text-good::before {
    content: "!";
    position: absolute;
    left: 0.5em;
    font-weight: bold;
}

/* Use patterns or shapes in addition to colors */
.success-indicator {
    background-color: #388e3c; /* Green */
    border-left: 4px solid #1b5e20; /* Darker green border */
    padding-left: 1em;
}

Testing for Color Blindness

  • Sim Daltonism (Mac)
  • Color Oracle (Windows, Mac, Linux)
  • Chrome DevTools' Emulate Vision Deficiencies

Wrapping Up

Colors, fonts, and text properties form the foundation of visual design in CSS. By mastering these properties, you can create websites that are both visually appealing and accessible to all users.

Key Takeaways

  • Colors set the mood and personality of your site. Use them consistently and ensure sufficient contrast for readability.
  • Fonts determine how your content is presented. Choose appropriate fonts for your audience and ensure they're loaded efficiently.
  • Text properties refine the appearance and layout of your text. Use them to improve readability and visual hierarchy.
  • Accessibility should be considered throughout your design process, not as an afterthought.
  • Responsive design ensures your typography works well across all devices and screen sizes.

Best Practices Summary

  • Use CSS variables (custom properties) for consistent colors and spacing
  • Create a type scale for hierarchical typography
  • Use relative units (rem, em) for font sizes and spacing
  • Ensure sufficient color contrast for readability
  • Create font stacks with appropriate fallbacks
  • Optimize font loading for performance
  • Test your design across different devices and screen sizes
  • Consider accessibility for all users, including those with visual impairments

Further Resources