Story
One component, four densities, covering every place a story appears. This is what replaces the 47 separate article card implementations.
When to use it
- Anywhere a story is linked from: a front, a rail, a search result, a related list.
- Pick the density by the story's rank on the page, not by where it sits in the grid.
- Do not use two leads on one page. If two stories both look like the lead, neither is.
- Do not build a new card because a page "feels different". That is how 47 of them happened.
Lead
One per page. Uses display-1 for the headline and promotes the standfirst to full size and full ink.
p234-story--lead
HTML
<a class="p234-story p234-story--lead" href="#">
<span class="p234-kicker" data-section="markets">Market intelligence</span>
<h3 class="p234-story__headline">Pump prices are running 25 per cent above the last official figure</h3>
<p class="p234-story__standfirst">NBS puts Lagos petrol at 1,077 naira in May. Reporting from this week puts it between 1,270 and 1,345. The gap is the story.</p>
<div class="p234-meta">
<span class="p234-meta__source">Plus234Feed</span>
<span class="p234-meta__dot">·</span>
<span>2 hours ago</span>
<span class="p234-coverage">6 sources</span>
</div>
</a>Secondary
The strong stories under the lead. headline size, standfirst stays muted.
p234-story--secondary
HTML
<a class="p234-story p234-story--secondary" href="#">
<span class="p234-kicker" data-section="politics">Politics</span>
<h3 class="p234-story__headline">Senate passes the 2027 appropriation bill at second reading</h3>
<p class="p234-story__standfirst">The chamber moved the bill after ninety minutes of debate on the capital component.</p>
<div class="p234-meta">
<span class="p234-meta__source">Channels Television</span>
<span class="p234-meta__dot">·</span>
<span>4 hours ago</span>
</div>
</a>Default
No modifier. headline-sm. This is the workhorse for grids and search results.
p234-story
HTML
<a class="p234-story" href="#">
<span class="p234-kicker" data-section="world">World</span>
<h3 class="p234-story__headline">Canada releases list of 36 countries whose citizens can apply</h3>
<p class="p234-story__standfirst">The list sets out which passports qualify for the youth mobility pool next year.</p>
<div class="p234-meta">
<span class="p234-meta__source">IRCC</span>
<span class="p234-meta__dot">·</span>
<span>yesterday</span>
<span class="p234-coverage">12 sources</span>
</div>
</a>Compact
For rails and "also today" lists. Drops the standfirst entirely rather than truncating it, because a clipped sentence is worse than no sentence.
p234-story--compact, stacked, with rules between
UBA board approves nine-month unaudited financials
SportSuper Eagles name a 23-man squad for the qualifier
MarketsBUA Foods shifts Q3 board meeting by one day
HTML
<a class="p234-story p234-story--compact" href="#">
<span class="p234-kicker" data-section="business">Business</span>
<h3 class="p234-story__headline">UBA board approves nine-month unaudited financials</h3>
<div class="p234-meta"><span>NGX filing</span><span class="p234-meta__dot">·</span><span>1 hour ago</span></div>
</a>
<a class="p234-story p234-story--compact" href="#">
<span class="p234-kicker" data-section="sport">Sport</span>
<h3 class="p234-story__headline">Super Eagles name a 23-man squad for the qualifier</h3>
<div class="p234-meta"><span>NFF</span><span class="p234-meta__dot">·</span><span>yesterday</span></div>
</a>
<a class="p234-story p234-story--compact" href="#">
<span class="p234-kicker" data-section="markets">Markets</span>
<h3 class="p234-story__headline">BUA Foods shifts Q3 board meeting by one day</h3>
<div class="p234-meta"><span>NGX filing</span><span class="p234-meta__dot">·</span><span>2 days ago</span></div>
</a>With a picture
Most story cards on the site carry one. The image is a child of the story, not a separate component, so the two cannot drift apart. It uses the same 16:9 as Figure, and reserves its space before it loads.
Card: picture on top. The homepage and category grids.
HTML
<div style="display:grid;gap:var(--p234-space-6);grid-template-columns:repeat(auto-fit,minmax(13rem,1fr))">
<a class="p234-story p234-story--card" href="#">
<img class="p234-story__media" src="data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 480 270'%3E%3Crect width='480' height='270' fill='%23ddd8cf'/%3E%3C/svg%3E" alt="" width="480" height="270">
<span class="p234-kicker" data-section="business">Business</span>
<h3 class="p234-story__headline">UBA board approves nine-month financials</h3>
<div class="p234-meta"><span>NGX filing</span></div>
</a>
<a class="p234-story p234-story--card" href="#">
<img class="p234-story__media" src="data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 480 270'%3E%3Crect width='480' height='270' fill='%23ddd8cf'/%3E%3C/svg%3E" alt="" width="480" height="270">
<span class="p234-kicker" data-section="world">World</span>
<h3 class="p234-story__headline">Canada releases list of 36 countries</h3>
<div class="p234-meta"><span>IRCC</span></div>
</a>
</div>Thumb: picture beside the headline. Rails, search results, related lists.
HTML
<div style="max-width:28rem">
<a class="p234-story p234-story--thumb" href="#">
<span class="p234-kicker" data-section="markets">Markets</span>
<h3 class="p234-story__headline">NGX closes higher as banking stocks lead the rally</h3>
<div class="p234-meta"><span>NGX</span><span class="p234-meta__dot">·</span><span>today</span></div>
<img class="p234-story__media" src="data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 160 90'%3E%3Crect width='160' height='90' fill='%23ddd8cf'/%3E%3C/svg%3E" alt="" width="160" height="90">
</a>
<a class="p234-story p234-story--thumb" href="#">
<span class="p234-kicker" data-section="sport">Sport</span>
<h3 class="p234-story__headline">Super Eagles name a 23-man squad for the qualifier</h3>
<div class="p234-meta"><span>NFF</span><span class="p234-meta__dot">·</span><span>yesterday</span></div>
<img class="p234-story__media" src="data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 160 90'%3E%3Crect width='160' height='90' fill='%23ddd8cf'/%3E%3C/svg%3E" alt="" width="160" height="90">
</a>
</div>In the thumb variant the image comes last in the markup and is placed back on the right with CSS. A screen reader and a search crawler read the headline first, which is the thing that matters, and the picture never gets read out before the story it illustrates.
Picture rules
- Give a decorative thumbnail an empty
alt. The headline beside it already says what the story is, and repeating it makes a screen reader say everything twice. - Ask the image service for the width the thumbnail is actually drawn at. A 140px thumbnail requesting 800 downloaded about five times the bytes it showed.
- Always set
widthandheightso the list does not jump as images land.
- Do not give every story in a grid a picture. An image on the lead and none below is a stronger hierarchy than six thumbnails.
- Do not fall back to a placeholder graphic when an article has no image. Drop to the no-picture variant instead; a grid of identical house images is worse than no images.
Structure
The whole card is one link. A card with several links inside it is a card a keyboard user has to tab through three times to get past, and it blurs what the click target is.
<a class="p234-story [modifier]">
<span class="p234-kicker" data-section="..."> optional
<h3 class="p234-story__headline"> required
<p class="p234-story__standfirst"> optional, hidden when compact
<div class="p234-meta"> optional
</a>
Accessibility
- Keep the heading level right for the page outline. The class carries the look; the tag carries the structure.
- Let the visited colour show. On an archive this size it is genuinely useful, and it is the default.
Tokens this component reads
--p234-color-ink--p234-color-ink-muted--p234-color-rule--p234-color-link-visited--p234-type-display-1-*--p234-type-headline-*--p234-type-headline-sm-*--p234-type-headline-xs-*--p234-type-standfirst-*--p234-type-body-sm-*--p234-space-4--p234-space-5--p234-measure-narrow--p234-measure-text--p234-border-hairline