Implementing Expandable Content with Pure CSS Using :target and :checked
This article explains how to create a "show more" effect without JavaScript by leveraging CSS pseudo‑classes like :target and :checked, detailing the required HTML structure, CSS rules, code examples, and the advantages and drawbacks of each approach.
Many websites hide extra content behind a "more" or "expand" link, traditionally using JavaScript to change the container height. The simplest JS method sets height: auto , but the author explores a pure‑CSS solution for developers who prefer not to write JS.
The author first examines CSS pseudo‑classes that provide limited interactivity, focusing on :target (used with anchor links) and :checked (used with checkboxes). Other pseudo‑classes such as :hover , :active , and :focus are mentioned but deemed unsuitable for this use case.
Using the :target Approach
The HTML structure places the expandable content inside a div with an id="more" , followed by a control block containing two links: one pointing to #more ("more") and another pointing to # ("shrink").
<div class="box" id="more">
<p>...content to show...</p>
</div>
<div class="detail_ctrl">
<a href="#more">更多</a>
<a href="#">缩小</a>
</div>The accompanying CSS sets a fixed height for .box and hides overflow. When the target is activated, the rule #more:target { height: auto; } expands the box. Additional sibling selectors toggle the visibility of the two links.
body {font-size:20px;}
.box {height:2em; overflow:hidden; width:10em; margin-bottom:.5em; line-height:1em; border:1px solid #000;}
#more:target {height:auto;}
.detail_ctrl a {display:inline;}
.detail_ctrl a + a {display:none;}
#more:target + .detail_ctrl a {display:none;}
#more:target + .detail_ctrl a + a {display:inline;}While functional, this method can cause page jumps, relies on an id that may clash with other scripts, and exposes the anchor in the URL.
Using the :checked Approach
Here a hidden checkbox controls the expansion. The HTML includes an input type="checkbox" id="more_c"> followed by the content box and a label for="more_c">更多 that acts as the toggle.
<input type="checkbox" id="more_c">
<div class="box">
<p>...content to show...</p>
</div>
<label for="more_c">更多</label>The CSS expands the box when the checkbox is checked and uses sibling selectors to change the label text via :after content, hide the original label, and style the label as a clickable element.
#more_c:checked + .box {height:auto;}
#more_c:checked ~ label[for="more_c"]:after {content:"闭合"; position:absolute; top:0; left:0; right:0; bottom:0; background:#fff; z-index:2;}
label {position:relative; cursor:pointer;}
#more_c {position:absolute; z-index:-1;}To keep the checkbox invisible, it is positioned off‑screen and given opacity:0 . The author notes that this method keeps the URL clean and works without JavaScript, but it still introduces a form element into the markup.
Summary and Considerations
The author concludes that CSS should primarily handle presentation, not complex interaction, and that both :target and :checked solutions have trade‑offs regarding maintainability, cross‑team communication, and especially browser compatibility. While the techniques are clever, they may not be suitable for production code without careful evaluation.
Ctrip Technology
Official Ctrip Technology account, sharing and discussing growth.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.