Adaptive Accordion Paragraph
Show the “more” control only when content becomes scrollable; expand to reveal the full text.
Key Implementation Points
Markup
Place the checkbox inside the label and use :has() to toggle expansion. Only .scroll-container is scrollable.
<div class="scroll-container">
<p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's
standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a
type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting,
remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing
Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of
Lorem Ipsum.
</p>
<label class="more" for="more">more<input type="checkbox" id="more" name="more" /></label>
</div>
Scroll-State Container
Enable scroll-state queries with container-type: scroll-state. Use max-height + overflow to define the threshold.
.scroll-container {
container-type: scroll-state;
max-height: 200px;
overflow: hidden;
position: relative;
}
Gradient Hint on Overflow
Apply @container scroll-state(scrollable: bottom) to a pseudo-element to paint a bottom fade only when overflowing.
.scroll-container:after {
content: '';
position: absolute;
bottom: 0;
inset-inline: 0;
display: block;
width: 100%;
height: 8em;
@container scroll-state(scrollable: bottom) {
background-image: linear-gradient(to bottom, transparent, white);
}
}
Expand/Collapse Control
Lift the height cap with :has(input:checked) and hide the overlay/button when expanded.
.scroll-container:has(input:checked) {
max-height: none;
&:after {
display: none;
}
.more {
display: none;
}
}
Note: .hint is pinned to the container’s bottom-right with anchor-name, position-anchor, and anchor().
<main>
<h2>When the height exceeds 200px, it becomes an accordion.</h2>
<div class="container">
<div class="scroll-container">
<p>
Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's
standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a
type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting,
remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing
Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of
Lorem Ipsum.
</p>
<label class="more" for="more">more<input type="checkbox" id="more" name="more" /></label>
</div>
<div class="hint">Resize</div>
</div>
</main>
<style>
main {
padding: 1rem;
}
h2 {
margin-bottom: 0.5rem;
}
p {
font-size: 18px;
}
.container {
position: relative;
border: 1px dashed #aaa;
border-radius: 8px;
padding: 10px;
width: 100%;
height: 100%;
resize: horizontal;
overflow: hidden;
anchor-name: --container;
}
.scroll-container {
container-type: scroll-state;
max-height: 200px;
overflow: hidden;
position: relative;
}
.scroll-container:after {
content: '';
position: absolute;
bottom: 0;
inset-inline: 0;
display: block;
width: 100%;
height: 8em;
@container scroll-state(scrollable: bottom) {
background-image: linear-gradient(to bottom, transparent, white);
}
}
.scroll-container:has(input:checked) {
max-height: none;
&:after {
display: none;
}
.more {
display: none;
}
}
.more {
display: none;
width: 100px;
position: absolute;
bottom: 0.5rem;
inset-inline: 0;
margin-inline: auto;
padding-block: 0.375rem;
padding-inline: 0.625rem;
font-size: 0.875rem;
line-height: 1.25rem;
font-weight: 600;
color: #111827;
background-color: #ffffff;
cursor: pointer;
border-radius: 9999px;
border: 1px solid #363636;
z-index: 1;
&:hover {
background-color: #F9FAFB;
}
@container scroll-state(scrollable: bottom) {
display: block;
}
}
label {
text-align: center;
}
input {
display: none;
}
.hint {
position: fixed;
position-anchor: --container;
bottom: anchor(bottom);
right: anchor(right);
margin: 12px;
background: #232323;
color: white;
padding: 0.5rem;
border-radius: 12px;
font-size: 0.875rem;
opacity: 0.9;
user-select: none;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
.hint::before {
content: '';
position: absolute;
bottom: -4px;
right: -4px;
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 12px solid #232323;
filter: drop-shadow(0 -2px 2px rgba(0, 0, 0, 0.1));
rotate: -45deg;
}
</style>