Styling the Tours Page — Tour Cards, Grid Layout, and Hover Effects
The tours page is the functional heart of the STO site — a scannable product listing where visitors discover which hikes are available. This lesson builds it with a more detailed card layout than the homepage preview, polished hover effects, and category tags.
Page header
Section titled “Page header”A consistent page header treatment used on every interior page:
/* === Page Header === */
.page-header { background-color: var(--color-primary); padding: var(--space-xl) 0; text-align: center;}
.page-header h1 { color: var(--color-bg); font-size: 2.5rem; margin-bottom: var(--space-sm);}
.page-header p { color: var(--color-accent); font-size: 1.125rem; max-width: 560px; margin: 0 auto;}This same .page-header block is reused on tours, blog, about, and contact pages — one rule, consistent across all interior pages.
Category tag pills
Section titled “Category tag pills”Tags let users visually scan for the type of tour they want:
/* === Tour Tags === */
.tour-tags { display: flex; flex-wrap: wrap; gap: var(--space-sm); margin-bottom: var(--space-lg);}
.tour-tag { display: inline-block; background-color: var(--color-accent); color: var(--color-primary); font-size: 0.75rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; padding: 0.25rem 0.75rem; border-radius: var(--radius-full);}
.tour-tag-difficulty-hard { background-color: var(--color-primary); color: var(--color-white);}
.tour-tag-difficulty-moderate { background-color: var(--color-secondary); color: var(--color-white);}Tours page layout
Section titled “Tours page layout”/* === Tours Page === */
.tours-page-content { padding: var(--space-xl) 0;}Reuse the .tours-grid and .tour-card from the global styles, extended with the more detailed card layout below.
Full tour card
Section titled “Full tour card”/* === Detailed Tour Card (tours page) === */
.tour-card-image-wrap { overflow: hidden;}
.tour-card-image { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; transition: transform var(--transition-normal);}
.tour-card:hover .tour-card-image { transform: scale(1.05);}
.tour-card-body { flex: 1; padding: var(--space-md); display: flex; flex-direction: column;}
.tour-card-title { font-size: 1.25rem; margin-bottom: var(--space-xs);}
.tour-card-meta { display: flex; align-items: center; gap: var(--space-md); margin-bottom: var(--space-sm); font-size: 0.85rem; color: var(--color-text-muted);}
.tour-card-meta-item { display: flex; align-items: center; gap: var(--space-xs);}
.tour-card-description { color: var(--color-text-muted); font-size: 0.95rem; line-height: 1.6; flex: 1; margin-bottom: var(--space-md);}
.tour-card-footer { display: flex; justify-content: space-between; align-items: center; padding-top: var(--space-sm); border-top: 1px solid var(--color-border); margin-top: auto;}
.tour-price { font-size: 1.25rem; font-weight: 700; color: var(--color-primary);}
.tour-price-label { font-size: 0.75rem; color: var(--color-text-muted); display: block; font-weight: 400;}The .tour-card-footer uses justify-content: space-between to push the price to the left and the CTA button to the right — a common product listing pattern.
Hover effects
Section titled “Hover effects”The hover state lifts the card and subtly zooms the image:
.tour-card { /* ... existing styles from Lesson 01 ... */ transition: transform var(--transition-normal), box-shadow var(--transition-normal);}
.tour-card:hover { transform: translateY(-6px); box-shadow: var(--shadow-lg);}The image zoom is handled by transform: scale(1.05) on .tour-card-image when the card is hovered — note the selector .tour-card:hover .tour-card-image targets the image inside a hovered card.
Responsive grid at three breakpoints
Section titled “Responsive grid at three breakpoints”.tours-grid { display: flex; flex-direction: column; gap: var(--space-md);}
/* Two columns at tablet */@media (min-width: 600px) { .tours-grid { flex-direction: row; flex-wrap: wrap; gap: var(--space-lg); }
.tour-card { flex: 1 1 calc(50% - var(--space-md)); }}
/* Three columns at desktop */@media (min-width: 1024px) { .tour-card { flex: 1 1 calc(33.333% - var(--space-lg)); }}Exercise
Section titled “Exercise”Style the STO tours page:
-
Add the page header, tour tag, and detailed card styles to
styles.css. -
In
tours.html, add the correct class names:.page-header,.tours-page-content,.tour-tags,.tour-tag,.tour-card-meta,.tour-card-footer. -
Wrap each tour card’s
<img>in a<div class="tour-card-image-wrap">and addclass="tour-card-image"to the<img>itself:<div class="tour-card-image-wrap"><img class="tour-card-image" src="images/pine-ridge-loop.jpg" alt="Forested trail through cedar and fir trees on the Pine Ridge Loop"></div>The wrapper provides the
overflow: hiddenboundary that clips the zoom effect to the card edges. Without it, the scaled image bleeds outside the card on hover. -
Verify the card hover effect — the card should lift and the image should zoom. If the image still overflows on hover, confirm
.tour-card-image-wraphasoverflow: hiddenand that.tour-carditself also hasoverflow: hiddenset (it was added in the global card styles from Lesson 01). -
Test at 375px (one column), 700px (two columns), and 1100px (three columns). The grid should reflow cleanly at each breakpoint.
-
Check that category tags wrap gracefully on mobile —
flex-wrap: wrapon.tour-tagshandles this.
.page-headeris a reusable component — one CSS block styles the header on every interior page consistently.- Category tags use
border-radius: var(--radius-full)(9999px) for the pill shape. - The
.tour-card-metarow uses Flexbox withgapto display duration, difficulty, and other attributes horizontally. transform: scale()on the image inside the hovered card requiresoverflow: hiddenon the image wrapper to clip the zoom to the card boundary.- The
calc()width approach gives precise column counts; theflex: 1 1 280pxapproach from Module 05 is equally valid and simpler.
Lesson 05 styles the blog listing and article pages — a different design challenge from marketing pages, focused on reading typography and comfortable line lengths.