LEARNING OBJECTIVES โต
- Understand why digital hyperlinks become useless on paper and how CSS
attr(href)solves this. - Implement smart URL expansion rules that filter out internal
#anchors,javascript:;, and relative paths. - Prevent page layout breakage caused by long unbroken URL strings using
word-break: break-all. - Generate print-only citation tables and embedded QR codes for mobile URL scanning.
๐ The Mental Model & Story (Intuitive Foundation)
Imagine printing out an important academic research paper or a legal brief. Throughout the text, the author writes:
- "For more information on the protocol, see [our technical documentation]."
- "To verify our cryptographic audit, check [this verification dashboard]."
On a computer screen, you tap the blue underlined text and your browser instantly navigates to the destination. But when that document is printed on paper, the reader is left staring at the words "our technical documentation" with absolutely no way to know where that link points. The link is an invisible dead end.
CSS provides the attr() function. With a single CSS rule, you can tell the browser: "Whenever this document is printed, inspect the HTML href attribute on every link, extract the destination URL string, and print it in parentheses directly after the anchor text."
DIGITAL SCREEN RENDER (Interactive)
"Please refer to our API Documentation for complete endpoint schemas."
\-----------------/
(Clickable)
PAGED PRINT RENDER (URL Expanded)
"Please refer to our API Documentation (https://api.acme.corp/v2/docs) for complete endpoint schemas."
\----------------/ \----------------------------/
Anchor Text Extracted URL via attr(href)
Technical Deep Dive & Specifications
1. The Core attr(href) Selector
The CSS attr() function retrieves the value of an attribute of the selected element and uses it in the stylesheet:
@media print {
a[href]::after {
content: " (" attr(href) ")";
font-size: 0.85em;
font-weight: normal;
color: #475569;
}
}
2. Filtering Irrelevant and Broken Links
If you blindly apply a[href]::after to every link, your printed document will be filled with useless clutter:
Click here (#)-> Prints:Click here (#)Jump to Section 2 (#section-2)-> Prints:Jump to Section 2 (#section-2)Run Script (javascript:void(0))-> Prints:Run Script (javascript:void(0))Home (/index.html)-> Prints:Home (/index.html)(Useless without domain!)
To produce professional documents, use CSS attribute substring matching selectors (^=, *=, $=):
@media print {
/* 1. Only expand external web URLs (http and https) */
a[href^="http://"]::after,
a[href^="https://"]::after {
content: " (" attr(href) ")";
font-size: 8.5pt;
color: #334155;
word-break: break-all; /* Critical for long URLs */
}
/* 2. Format mailto links cleanly */
a[href^="mailto:"]::after {
content: " [" attr(href) "]";
font-size: 8.5pt;
}
/* 3. Explicitly suppress internal hash anchors and script links */
a[href^="#"]::after,
a[href^="javascript:"]::after,
a.no-print-url::after {
content: "" !important;
}
}
+------------------------------------------------------------------------------------+
| CSS ATTRIBUTE SELECTOR LOGIC |
+------------------------------------------------------------------------------------+
Selector Matches Print Action
----------------------------------------------------------------------------------
a[href^="https://"] Starts with "https://" โ
Expand full URL
a[href^="http://"] Starts with "http://" โ
Expand full URL
a[href^="mailto:"] Starts with "mailto:" โ
Expand email address
a[href^="#"] Starts with "#" (Internal Anchor) โ Suppress (No Value)
a[href^="javascript:"] Starts with "javascript:" โ Suppress (Security/Noise)
3. Preventing Layout Breakage with word-break: break-all
Modern tracking URLs, tokenized links, and deep API routes can easily exceed 150 characters in length without a single space (e.g., https://example.com/api/v2/auth/callback?token=eyJhbGciOi...).
Without word-breaking rules, the browser will refuse to break the URL string, causing it to push beyond the right physical paper margin and get cut off by the printer edge:
@media print {
a[href^="http"]::after {
content: " (" attr(href) ")";
/* Prevents horizontal overflow past paper edge */
word-break: break-all;
overflow-wrap: anywhere;
}
}
๐ป Interactive Code Playground
Below is a complete, runnable HTML document demonstrating smart URL expansion, filtering of internal and JavaScript links, and print-ready formatting.
Starter Code
Line-by-Line Code Breakdown
- Lines 50โ53 (
a): Resets link color to#000000with standard underline so links are identifiable on monochrome laser paper. - Lines 56โ63 (
a[href^="http..."]::after): Injects the target URL inside square brackets[URL], sets a smaller9ptfont size, and appliesword-break: break-allso long query parameters wrap smoothly across lines without clipping. - Lines 66โ69 (
a[href^="mailto:"]::after): Extracts and prints email contact endpoints inside angle brackets<mailto:...>. - Lines 72โ76 (
a[href^="#"]::after, a[href^="javascript:"]::after): Usescontent: none !importantto ensure that#table-of-contents,#contact-footer, andjavascript:void(0)do not print meaningless text artifacts.
Expected Browser Render Output
- Screen View: A standard interactive security bulletin with blue links and a blue "Print Official Disclosure" button.
- Print Preview (
Cmd/Ctrl + P):- The "Print" button is hidden.
- The CVE link reads:
CVE-2026-98124 Entry [https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2026-98124]. - The GitHub link displays the complete repository URL.
- The email link displays:
[email protected] <mailto:[email protected]>. - The
[Jump to Index]andVerify Security Checksumlinks do not append any bracketed URLs.
๐๏ธ Hands-On Exercise
๐ฏ The Challenge: Academic Bibliography Link Extractor
Scenario: You are preparing an engineering whitepaper for print distribution. The body text contains links to external W3C standards, RFC documents, internal section anchors, and author email links.
Instructions:
- Configure
@media printso that all external HTTP and HTTPS links expand their target URL in parentheses:(https://...). - Format
mailto:links so they expand as:<email>. - Suppress URL expansions on all internal
#hashnavigation links. - Ensure long URLs do not overflow the right margin by using
overflow-wrap: anywhereandword-break: break-all.
๐ Starter Code Sandbox
โ ๏ธ Common Pitfalls
- Applying
attr(href)Globally to All<a>Tags: Usinga::after { content: " (" attr(href) ")"; }without attribute filtering causes ugly artifacts on internal hash links (#section), anchor buttons, and JavaScript callbacks (javascript:void(0)). Always filter witha[href^="http"]. - Forgetting
word-break: break-all: Long URLs with URL-encoded query parameters (e.g. tracking tokens, UTM parameters) have no whitespace. Withoutword-break: break-all, they push outside the right margin and get chopped off by the physical printer. - Expanding Obvious Redundant URLs: If the link text is already the URL (e.g.
<a href="https://github.com">https://github.com</a>), expanding it produces:https://github.com (https://github.com). Use class exclusions (.no-expand::after { content: none; }) for redundant text.
๐ก Pro Tips
- Generate Dynamic Print QR Codes: For mobile readers scanning physical paper, embed print-only SVG QR codes alongside complex URLs:
In<div class="print-qr-code" style="display: none;"> <img src="https://api.qrserver.com/v1/create-qr-code/?data=https%3A%2F%2Fexample.com" width="80" height="80" alt="QR Code"> </div>@media print, set.print-qr-code { display: inline-block !important; }. - Build a Footnote Bibliography Pipeline: For academic papers, you can use CSS counters to convert inline links into numbered superscript citations
[1],[2]and generate a compiled bibliography list at the end of the document. - Clean Up
mailto:Prefixes: When expandingmailto:, the raw attribute containsmailto:[email protected]. In advanced CSS (or templating engines), format this cleanly to avoid displaying the redundantmailto:scheme.
๐ Key Takeaways
- Digital hyperlinks lose their navigation capability on physical paper unless their target URL is visibly revealed.
- The CSS
attr(href)function extracts the destination URL and injects it via pseudo-elements (::after). - Always filter links with
a[href^="http://"]anda[href^="https://"]to avoid displaying#hashanchors andjavascript:scripts. - Enforce
word-break: break-allandoverflow-wrap: anywhereon expanded URLs to prevent horizontal print clipping. - Combine URL expansions with print QR codes for seamless paper-to-mobile user transitions.
- --