UI Components Without JavaScript
18 common website components — menus, tabs, filters, modals, carousels, lazy loading, scroll animations and form validation — built with semantic HTML and CSS. Each with a live demo, copy-paste code and an honest note on what still needs a script.
- JavaScript
- 0 KB in every demo
- Code
- Copy-paste HTML & CSS, no framework
- SEO
- All content and links in the HTML
- Price
- Free, no sign-up
We hear it on almost every website project: “but we need JavaScript for that.” For most interface components, you don't. Browsers have had native solutions for years — they're faster, work when scripts fail, and keep your content where search engines can read it. These patterns show how.
Page structure
Tables of contents, pagination and language versions — how visitors and crawlers move through a site.
-
13
Language Switcher with hreflang
A language menu made of plain links with
hreflang— no automatic redirects that lock search engines out of your other languages.- hreflang
- lang
- <details>
-
17
SEO-Friendly Pagination
Page links and a “Load more” link that crawlers can follow — instead of infinite scroll they never see the end of.
- <nav>
- aria-current
- real links
-
18
Table of Contents & Anchor Links
A sticky table of contents with smooth scrolling and
scroll-margin-top, so headings don't hide under a fixed header.- position: sticky
- scroll-margin-top
- :target
Content & disclosure
Show, hide and filter content without hiding it from crawlers.
-
05
Accordion Without JavaScript
Native
<details>and<summary>styled with CSS — including accordions where only one item opens at a time.- <details>
- name attribute
-
06
Tabs Without JavaScript
Tabbed content with radio buttons and
:checked. All panels stay in the HTML, where search engines can read them.- :checked
- :has()
-
07
Read More Without JavaScript
Expandable text that keeps every word in the HTML — and what collapsed content means for SEO.
- <details>
- line-clamp
-
16
Content Filter Without JavaScript
Filter cards by category with radio buttons and
:has()— every item stays in the HTML.- :has()
- :checked
Overlays & hints
Popups, image viewers and tooltips without a library.
-
08
Modal Without JavaScript
Popups built with the
popoverattribute, the dialog element and:target— no modal library.- popover
- <dialog>
- :target
-
09
CSS-Only Image Lightbox
Click a thumbnail to see the full image with its caption. Built on
:target, no gallery plugin.- :target
- <figure>
-
10
CSS Tooltip Without JavaScript
Hover and focus hints with pseudo-elements — and where a CSS-only tooltip stops being accessible.
- :focus-visible
- ::after
Media, motion & forms
Carousels, images, scroll effects and form feedback that the browser already handles.
-
11
CSS-Only Carousel with Scroll Snap
Swipeable carousels with native scrolling and scroll snap — no slider library.
- scroll-snap
- ::scroll-marker
-
12
Form Validation Without JavaScript
Native constraint validation styled with
:user-invalid, so errors appear only after the user has touched a field.- :user-invalid
- pattern
-
14
Lazy Loading Images Without JavaScript
Native
loading="lazy",fetchpriorityand image dimensions instead of a library — and whydata-srccan hide images from crawlers.- loading="lazy"
- fetchpriority
- srcset
-
15
Scroll Animations Without JavaScript
Fade-ins, a reading progress bar and a back-to-top button driven by scrolling. Content stays visible wherever the feature isn't supported.
- animation-timeline
- view()
- @supports
“But we need JavaScript for that …”
The most common objections we hear from web designers — and what HTML and CSS already do instead.
| The claim | What the browser already does | Pattern |
|---|---|---|
| “A dropdown menu needs JavaScript.” | :hover and :focus-within open nested lists for mouse and keyboard. | Dropdown menu → |
| “The mobile menu needs JavaScript.” | A checkbox and a <label> toggle an off-canvas menu with :checked. | Hamburger menu → |
| “Accordions need a script.” | <details> and <summary> are built in — the name attribute makes only one open at a time. | Accordion → |
| “Tabs need JavaScript.” | Radio buttons hold the state; :checked shows the matching panel. | Tabs → |
| “Read more needs JavaScript.” | <details> or a checkbox expands the text. Every word stays in the HTML. | Read more → |
| “A popup needs a modal library.” | The popover attribute and :target open and close overlays natively. | Modal → |
| “An image lightbox needs a plugin.” | :target shows the full image when its thumbnail link is clicked. | Lightbox → |
| “A carousel needs a slider library.” | CSS scroll snap gives native swiping that locks onto each slide. | Carousel → |
| “Form validation needs a script.” | required, type and pattern validate; :user-invalid styles the errors. | Form validation → |
| “We need a script to send visitors to their language.” | Plain links with hreflang let visitors — and crawlers — choose. Automatic redirects can hide whole language versions from search engines. | Language switcher → |
| “Lazy loading needs a library.” | loading="lazy" is built into every current browser — and the real image URL stays in src, where crawlers find it. | Lazy loading → |
| “Scroll animations need a JavaScript library.” | animation-timeline: view() ties CSS animations to scrolling, with content visible where it isn't supported. | Scroll animations → |
| “Filtering needs JavaScript.” | Radio buttons and :has() show and hide cards by category — all items stay in the HTML. | Filter → |
| “Load more needs JavaScript.” | A “Load more” link to page 2 works everywhere — and crawlers can follow it, unlike infinite scroll. | Pagination → |
| “Smooth scrolling and header offsets need a script.” | scroll-behavior: smooth and scroll-margin-top do both in two lines. | Table of contents → |
The role of JavaScript: enhancement, not requirement
Build the working version first
Too many pages ship hundreds of kilobytes of JavaScript to do what HTML and CSS already do. That slows the page down and, worse, puts content and links where some crawlers can't reach them.
A CSS-first approach starts with a version that works with HTML and CSS alone. JavaScript is then added on top — for smooth extras, keyboard shortcuts or analytics. If the script fails to load, nothing important breaks.
When JavaScript is the right tool
Real-time filtering of large datasets, drag-and-drop, live data from an API, complex app state or 3D rendering — use JavaScript for these. Every pattern page in this library also says where the CSS-only version ends, for example Esc to close or aria-expanded on menu buttons.
The rule is simple: the content and the core function should never depend on a script.
Why it matters for SEO — especially in China
Not every crawler runs your scripts
Google renders JavaScript, but in a second step, with time limits, and not always completely. Baidu, other Chinese search engines and many AI crawlers mostly work with the HTML they download. Content and links that only appear after a script runs may simply not exist for them.
Lean HTML gets crawled and loads faster
In our experience, Baidu reads the beginning of a page's HTML most reliably — so content buried under large inline scripts is a risk. Lean pages also load faster on mobile networks, which helps users everywhere. Our Baidu ranking factor studies show what else matters.
Building or relaunching a website for China?
We audit Chinese websites for content and links that crawlers can't see, help your developers fix them, and run Baidu SEO, Chinese GEO and Baidu Ads for Western companies.
CSS-First UI Patterns are written and maintained by Jademond Digital, a Chinese digital marketing agency founded in Guangzhou in 2012. We build and audit websites for Baidu, Google and AI search — which is why we care what works without JavaScript. About us →