Visual Depth — box-shadow, text-shadow, and opacity
The STO site now has a color palette, readable typography, and web fonts. This lesson adds the finishing layer: visual depth. Shadows and transparency are among the most satisfying properties to experiment with — small values produce a significant visual impact.
box-shadow
Section titled “box-shadow”box-shadow adds a shadow to the outside (or inside) of an element. The syntax is:
box-shadow: offset-x offset-y blur-radius spread-radius color;- offset-x — horizontal shift. Positive = right, negative = left.
- offset-y — vertical shift. Positive = down, negative = up.
- blur-radius — how soft the shadow edges are. 0 = sharp edge, larger = softer.
- spread-radius — how much larger than the element the shadow is. Positive = expands, negative = contracts. Optional.
- color — the shadow color. Use
rgba()for semi-transparent shadows.
/* Subtle card elevation */.tour-card { box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);}
/* More pronounced elevation */.tour-card:hover { box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);}The analogy: box-shadow is like the shadow cast by a physical card lifted off a surface. A card held close to a surface casts a small, sharp shadow. A card held higher casts a larger, softer shadow. blur-radius controls the height; offset-y controls the direction.
Multiple shadows
Section titled “Multiple shadows”Separate multiple shadows with commas. The first shadow listed is on top:
.tour-card { box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08), /* tight ambient shadow */ 0 4px 16px rgba(0, 0, 0, 0.12); /* softer elevation shadow */}Layering a tight ambient shadow and a softer elevation shadow produces a more realistic result than a single shadow.
Inset shadows
Section titled “Inset shadows”The inset keyword moves the shadow inside the element, creating a pressed or recessed effect:
/* Button pressed state */.btn:active { box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.2);}
/* Input focus ring alternative */input:focus { box-shadow: inset 0 0 0 2px #2c4a1e;}An inset shadow with 0 offset and 0 blur but a non-zero spread creates a clean inner border — an alternative to outline that respects border-radius.
box-shadow with border-radius
Section titled “box-shadow with border-radius”Shadows respect border-radius — a rounded card casts a rounded shadow automatically.
.tour-card { border-radius: 8px; box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1); /* shadow follows the rounded corners */}text-shadow
Section titled “text-shadow”text-shadow applies a shadow to text characters. The syntax is the same as box-shadow, minus the spread radius:
text-shadow: offset-x offset-y blur-radius color;/* Subtle text shadow on hero heading for contrast over an image */.hero h1 { color: #f5f0eb; text-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);}
/* Multiple text shadows for a glow effect */.highlight { text-shadow: 0 0 8px rgba(44, 74, 30, 0.4), 0 0 20px rgba(44, 74, 30, 0.2);}text-shadow is most useful on text displayed over a background image, where contrast with the background is uncertain. A small, dark shadow behind light text ensures legibility regardless of the image content.
Use text-shadow sparingly. Overused shadows make text harder to read, not easier.
opacity
Section titled “opacity”opacity controls the transparency of an entire element — including all its children and their backgrounds, borders, and text:
.disabled-btn { opacity: 0.5;}
.hero-overlay { opacity: 0.8;}Values range from 0 (fully transparent, invisible) to 1 (fully opaque, default).
The key distinction: opacity vs rgba()
opacityaffects the entire element and everything inside it, including text and child elements.rgba()/hsla()affects only the single property it is applied to.
/* This makes the entire card — text, borders, everything — 50% transparent */.card { opacity: 0.5;}
/* This only makes the background color transparent — text remains fully opaque */.card { background-color: rgba(255, 255, 255, 0.5);}For overlays, rgba() on the background is almost always the right choice. opacity is useful for disabled states, fade animations, or hover dimming effects.
opacity: 0 vs visibility: hidden vs display: none
Section titled “opacity: 0 vs visibility: hidden vs display: none”| Declaration | Visible | Takes space | Interactive |
|---|---|---|---|
opacity: 0 | No | Yes | Yes (still clickable) |
visibility: hidden | No | Yes | No |
display: none | No | No | No |
opacity: 0 is the correct choice when animating a fade — display and visibility cannot be transitioned.
Exercise
Section titled “Exercise”Add depth to three elements on the STO site:
1. Tour card elevation and hover lift:
.tour-card { border-radius: 8px; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08), 0 4px 12px rgba(0, 0, 0, 0.1); transition: box-shadow 0.2s ease, transform 0.2s ease;}
.tour-card:hover { box-shadow: 0 4px 16px rgba(0, 0, 0, 0.14), 0 12px 32px rgba(0, 0, 0, 0.12); transform: translateY(-2px);}2. Hero heading text shadow for image contrast:
.hero h1 { text-shadow: 0 2px 12px rgba(0, 0, 0, 0.5);}3. Button pressed state with inset shadow:
.btn { background-color: #2c4a1e; color: #f5f0eb; padding: 0.75rem 1.5rem; border: none; border-radius: 4px; cursor: pointer; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); transition: box-shadow 0.1s ease;}
.btn:active { box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.25); transform: translateY(1px);}Open the browser and hover over the tour cards. The subtle lift and shadow change makes the cards feel interactive and elevated — a significant improvement from flat rectangles.
Module 04 Recap
Section titled “Module 04 Recap”- CSS color formats: named colors (prototyping), hex (fixed brand colors),
rgba()(transparency),hsl()/hsla()(palettes and theming). - Background properties:
background-coloras fallback,background-image: url()for images,no-repeat center / coverfor hero sections, multiple backgrounds for overlays. - Font properties:
font-familywith a fallback stack,remunits for font-size,font-weight400/700 for normal/bold,font-style: italic. - Text styling:
line-height: 1.6for body readability,letter-spacingfor headings and uppercase labels,text-alignandtext-decorationfor links and layout. - Web fonts: Google Fonts via
<link>method withrel="preconnect"anddisplay=swap; load only needed weights; always include fallbacks. - Visual depth:
box-shadowwithrgba()for card elevation;insetfor pressed states;text-shadowfor text on images;opacityfor whole-element transparency.
Module 05 introduces layout: Flexbox — the modern CSS layout system that makes aligning and distributing elements across rows and columns intuitive and flexible.