Sticky
Pins content to the top or bottom of its scroll container and tells you when it is stuck, optionally hiding it while the reader scrolls down.
c2-sticky keeps a toolbar, a row of tabs, a section heading or an action bar in view while the content around it scrolls. Stickiness itself is CSS position: sticky, so it costs nothing at rest; what the element adds is the stuck state: once content runs beneath it the host matches :state(stuck), fires stuck-change, and its surface switches to the __stuck--* background and shadow, so a bar can sit flat on the page until it actually overlaps something. edge="bottom" pins it to the bottom edge instead. With hide-on-scroll it slides out of view while the reader scrolls down and comes back on the way up, or as soon as focus moves into it.
The element sticks within its parent, and the nearest ancestor with overflow set is the box it sticks to, exactly as for any sticky box. Keep a distance from the edge with --c2-sticky--offset (the height of a sticky header above it, for instance), and switch pinning off under a breakpoint with --c2-sticky--position: static, which also switches the stuck state off. c2-header uses the same behaviour for its sticky mode.
Import
import '@c2n/components/sticky'Usage
Scroll inside each box.
Quarterly report. Scroll down: the toolbar below sits flat on the page until content runs beneath it.
Revenue grew 14% quarter over quarter, led by the enterprise segment.
Operating costs held flat as the new region came online ahead of plan.
Churn fell to 2.1%, the lowest since the product launched.
Hiring slowed in the second half of the quarter, by design.
The board approved the expansion budget for the next two quarters.
Cash on hand covers 30 months of runway at the current burn.
Next quarter focuses on onboarding and self-serve upgrades.
Scroll down and the bar slides away; scroll back up a little and it returns.
Design review moved to Thursday at 10:00.
Your invoice for September is ready.
Three new comments on the roadmap document.
Deploy to production finished in 4 minutes.
Reminder: quarterly planning starts next week.
New sign-in from a browser on Linux.
The team lunch is booked for Friday.
Weekly metrics digest: all dashboards green.
Terms of service, section 1. The actions stay in reach until the end of the text.
Section 2. Accounts and access.
Section 3. Payment and billing.
Section 4. Acceptable use.
Section 5. Data and privacy.
Section 6. Termination.
Section 7. Liability.
Section 8. Changes to these terms.
Reacting to the stuck state
Style a stuck element from outside with :state(stuck) and :state(retracted), or listen for stuck-change and retract-change, which do not bubble. The element’s stuck and retracted properties read the current state, and reveal() brings a retracted element back.
const toolbar = document.querySelector('c2-sticky')!
toolbar.addEventListener('stuck-change', (event) => {
console.log(event.detail.stuck ? 'content runs beneath the toolbar' : 'toolbar back in the flow')
})c2-sticky:state(stuck) .title {
font-size: 14px;
}