Apply the Contrast design principle to create visual hierarchy, direct user attention, and improve accessibility — implemented with CSS color, size, weight, and spacing differences that make interfaces scannable and usable.
Robin Williams' CRAP principles — Contrast, Repetition, Alignment, and Proximity — are the four most practical design rules for developers. They translate design thinking into specific CSS decisions.
Contrast is the most powerful of the four: it is how users know what is most important on a page. Without contrast, everything is equal — and when everything is equal, nothing is important. With effective contrast, users can scan a page in seconds and find what they need.
Contrast is not only about color. Size contrast, weight contrast, and spacing contrast are equally powerful tools — and all of them are CSS properties you already know.
In design, contrast means making important things look noticeably different from unimportant things. It answers the question: 'How does a user know what to look at first?'
Contrast works across four dimensions:
Contrast principle in practice:
1/* Without contrast: everything looks the same importance */
2.page-title { font-size: 1rem; font-weight: 400; color: #374151; }
3.body-text { font-size: 1rem; font-weight: 400; color: #374151; }
4.caption { font-size: 1rem; font-weight: 400; color: #374151; }
5
6/* With contrast: clear hierarchy */
7.page-title { font-size: 2.25rem; font-weight: 700; color: #111827; }
8.body-text { font-size: 1rem; font-weight: 400; color: #374151; }
9.caption { font-size: 0.875rem; font-weight: 400; color: #6b7280; }Rule of contrast: if two elements are NOT the same, make them VERY different — not slightly different. Slight differences look like mistakes; large differences look intentional.
Bad: h2 at 18px vs body at 16px (2px difference — looks like an error)
Good: h2 at 24px vs body at 16px (50% larger — clearly intentional)
Color contrast has both an aesthetic dimension (does it look good?) and a legal/accessibility dimension (is it readable by users with low vision?).
WCAG 2.1 contrast requirements:
1Text on background:
2 Normal text (< 18px regular or < 14px bold): 4.5:1 minimum (AA)
3 Large text (≥ 18px regular or ≥ 14px bold): 3:1 minimum (AA)
4
5UI components (buttons, inputs, icons):
6 Against adjacent colors: 3:1 minimum (AA)
7
8For WCAG AAA (higher standard):
9 Normal text: 7:1
10 Large text: 4.5:1Calculating contrast ratio:
Common contrast problems and fixes:
1/* FAIL: Light gray text on white — too low contrast */
2.label { color: #9ca3af; } /* on #ffffff: 2.85:1 — fails AA */
3
4/* FIX: Darker gray text */
5.label { color: #6b7280; } /* on #ffffff: 4.48:1 — passes AA */
6
7/* FAIL: Blue text on light blue background */
8.badge { color: #3b82f6; background-color: #eff6ff; } /* 2.67:1 — fails for small text */
9
10/* FIX: Darker blue */
11.badge { color: #1d4ed8; background-color: #eff6ff; } /* 4.53:1 — passes */
12
13/* FAIL: Green on white — common problem for success states */
14.success { color: #22c55e; } /* on white: 1.91:1 — fails badly */
15
16/* FIX: Much darker green for text */
17.success { color: #15803d; } /* on white: 5.05:1 — passes */Color contrast tools:
Checking contrast in DevTools:
Typography contrast creates the most important hierarchy on any page. Users scan headings before reading body text — the contrast between them determines how effectively information is communicated.
Typographic contrast scale:
1/* Complete typographic hierarchy using size + weight contrast */
2:root {
3 /* Type scale with deliberate contrast between levels */
4 --text-display: 3.75rem; /* 60px — extreme size for hero values */
5 --text-h1: 2.25rem; /* 36px — page titles */
6 --text-h2: 1.875rem; /* 30px — section titles */
7 --text-h3: 1.5rem; /* 24px — subsection titles */
8 --text-h4: 1.25rem; /* 20px — card titles */
9 --text-body: 1rem; /* 16px — body text */
10 --text-small: 0.875rem; /* 14px — captions, metadata */
11 --text-micro: 0.75rem; /* 12px — legal, tiny labels */
12}
13
14/* Contrast between adjacent levels should be at least 25% */
15/* 36px vs 30px = 20% difference — too close */
16/* 36px vs 24px = 50% difference — clear contrast */
17
18.heading-primary {
19 font-size: var(--text-h1); /* 36px */
20 font-weight: 700; /* weight contrast vs body 400 */
21 line-height: 1.25;
22 color: #111827; /* color contrast vs body #374151 */
23 letter-spacing: -0.025em; /* tighter tracking for large type */
24}
25
26.body-text {
27 font-size: var(--text-body); /* 16px — 56% smaller than h1 */
28 font-weight: 400;
29 line-height: 1.6;
30 color: #374151; /* lighter than heading */
31}
32
33.caption {
34 font-size: var(--text-small); /* 14px */
35 font-weight: 400;
36 color: #6b7280; /* noticeably lighter */
37 line-height: 1.4;
38}Using contrast to indicate importance:
1/* Important data (course count, students enrolled) */
2.stat-value {
3 font-size: var(--text-display); /* 60px — extreme contrast for impact */
4 font-weight: 700;
5 color: #111827; /* maximum darkness */
6 line-height: 1;
7}
8
9.stat-label {
10 font-size: var(--text-small); /* 14px — tiny vs 60px = 330% contrast */
11 font-weight: 500;
12 color: #6b7280; /* muted vs high-contrast value */
13 text-transform: uppercase;
14 letter-spacing: 0.1em;
15}
16
17/* Primary vs secondary button contrast */
18.btn-primary {
19 background-color: #2563eb; /* bold action color */
20 color: white;
21 font-weight: 600;
22}
23
24.btn-secondary {
25 background-color: transparent; /* no fill — low visual weight */
26 border: 1px solid #d1d5db;
27 color: #374151;
28 font-weight: 500; /* lighter weight than primary */
29}Whitespace is not empty space — it is a design element that creates contrast between sections and draws attention to important elements.
Whitespace contrast in practice:
1/* Primary CTA: surrounded by whitespace, draws maximum attention */
2.hero-cta {
3 margin-top: 2.5rem; /* 40px — lots of space above */
4 margin-bottom: 2.5rem; /* generous space below before next section */
5}
6
7/* Secondary link: minimal whitespace, looks less important */
8.sign-in-link {
9 margin-top: 0.5rem; /* 8px — close to form, looks connected */
10}Section whitespace for visual weight:
1/* Hero section: lots of whitespace = most important */
2.hero {
3 padding: 6rem 2rem; /* 96px top/bottom — generous breathing room */
4}
5
6/* Feature cards section: moderate whitespace = supporting content */
7.features {
8 padding: 4rem 2rem; /* 64px */
9}
10
11/* Footer: less whitespace = least important */
12.footer {
13 padding: 2rem 2rem; /* 32px */
14}Card internal spacing contrast:
1/* Card title: large internal gap = emphasized */
2.card-title {
3 margin-bottom: 1rem; /* generous space after title draws eye */
4}
5
6/* Card metadata: tight spacing = de-emphasized */
7.card-meta {
8 display: flex;
9 gap: 0.5rem; /* tight gap = low importance */
10 margin-top: 0.75rem;
11}Contrast violation: when everything has the same padding
1/* BAD: Same spacing for all elements — no hierarchy */
2.card > * {
3 margin-bottom: 1rem; /* every element equally spaced = no contrast */
4}
5
6/* GOOD: Deliberate spacing hierarchy */
7.card-category { margin-bottom: 0.25rem; } /* tight — category close to title */
8.card-title { margin-bottom: 0.75rem; } /* moderate gap after title */
9.card-description { margin-bottom: 1.5rem; } /* larger gap before CTA = emphasis */
10.card-cta { /* no margin — CTA is at the bottom, natural stop */ }The whitespace contrast rule: Give more whitespace to more important content. The whitespace around an element signals how important it is — the more isolated and spacious, the more important.
Transforming a flat, low-contrast course detail page into a hierarchy-driven layout using color, size, weight, and whitespace contrast.
1/* BEFORE: Flat design — no contrast hierarchy */
2.course-detail {
3 font-size: 1rem;
4 font-weight: 400;
5 color: #374151;
6}
7
8.course-title { font-size: 1.25rem; } /* too similar to body */
9.course-price { font-size: 1.25rem; } /* same as title = equal weight */
10.course-meta { font-size: 0.9375rem; } /* barely different from body */
11.enroll-btn {
12 padding: 0.5rem 1rem; /* undersized for a primary action */
13 background: #2563eb;
14 color: white;
15}
16
17/* AFTER: Deliberate contrast hierarchy */
18
19/* Page title: maximum contrast — user reads this first */
20.course-title {
21 font-size: 2.25rem; /* 36px vs 16px body = 125% larger */
22 font-weight: 700; /* vs 400 body = heavy contrast */
23 color: #111827; /* vs #374151 body = darker */
24 line-height: 1.3;
25 letter-spacing: -0.02em; /* tighter for large type */
26}
27
28/* Price: high contrast — financial decisions require visibility */
29.course-price {
30 font-size: 1.875rem; /* 30px — second most important */
31 font-weight: 700;
32 color: #111827;
33 letter-spacing: -0.01em;
34}
35
36.course-price-currency {
37 font-size: 1.125rem; /* smaller than the number for visual weight */
38 font-weight: 600;
39 vertical-align: top;
40 margin-top: 0.375rem;
41}
42
43/* Rating: medium contrast — important but secondary */
44.course-rating-value {
45 font-size: 1.125rem;
46 font-weight: 700;
47 color: #111827;
48}
49
50.course-rating-count {
51 font-size: 0.875rem; /* smaller = less emphasis */
52 color: #6b7280; /* muted = secondary information */
53}
54
55/* Meta information: low contrast — supporting details */
56.course-meta {
57 font-size: 0.875rem;
58 color: #6b7280; /* muted — clearly secondary */
59 line-height: 1.4;
60}
61
62/* Primary CTA: high contrast through size + color */
63.enroll-btn {
64 display: flex;
65 align-items: center;
66 justify-content: center;
67 width: 100%; /* full width = maximum presence */
68 padding: 1rem 2rem; /* larger than secondary = more important */
69 background-color: #2563eb;
70 color: white;
71 font-size: 1rem;
72 font-weight: 600;
73 border-radius: 0.5rem;
74 border: none;
75 cursor: pointer;
76 margin-top: 1.5rem; /* whitespace above = emphasis */
77}
78
79/* Spacing contrast: different gaps communicate hierarchy */
80.course-section-header { margin-bottom: 1.5rem; } /* generous = important */
81.course-meta-item { margin-bottom: 0.25rem; } /* tight = secondary */
82.enroll-section { margin-top: 2rem; } /* spacious = emphasized */The contrast improvements create a clear visual hierarchy: the 36px/700 title draws the eye first, the 30px/700 price draws it second (purchase decision), the 18px/700 rating provides social proof at a glance, and the muted 14px metadata sits quietly without competing. The full-width primary button with generous margin above it is isolated in whitespace — it commands the most attention in the purchase decision area. Every sizing and color decision is deliberate: more important = larger, heavier, darker, and more spaciously surrounded.
The next lesson covers the Repetition CRAP principle — how consistent repetition of design elements across a page creates visual cohesion and reduces cognitive load.
Your progress is saved in this browser, on this device only.