Modern CSS Alternatives to JavaScript: Sliders, Dialogs, Accordions & More!
Discover how modern CSS can replace JavaScript for common UI components like accordions, modals, and carousels, leading to faster, more performant, and easier-to-maintain websites.
CSS has evolved significantly over the years. With new specifications and enhanced browser support, it can now manage animations, interactions, and UI components that previously mandated JavaScript. This means we no longer always require JavaScript for certain effects, contributing to faster and more maintainable websites.
In this article, we'll explore common UI components that traditionally relied on JavaScript and demonstrate how you can now build them using modern CSS.
Why Replace JavaScript with CSS?
Replacing JavaScript with CSS, whenever feasible, offers several advantages:
- Better performance: CSS is processed by the browser's rendering engine, which is highly optimized for visual changes. This ensures animations and transitions run smoothly, even on older devices.
- Faster load times: Reducing JavaScript means fewer scripts for browsers to download, parse, and execute, which significantly decreases page load time.
- Improved maintainability: Styling and visual effects are confined to the stylesheet, resulting in cleaner and more manageable code.
- Fewer dependencies: You can avoid relying on third-party libraries or frameworks for effects that CSS can handle natively.
- Progressive enhancement: Features can gracefully degrade in older browsers without disrupting your site’s core functionality.
Having understood the benefits of utilizing CSS (where and when possible) over JavaScript, let's delve into scenarios where CSS can fully replace JavaScript, starting with animations and transitions.
Accordion
An accordion is a ubiquitous website component, frequently found in FAQs, menus, and settings panels. It consists of a stack of sections, each capable of expanding or collapsing to reveal content. Rather than overwhelming users by displaying everything at once, accordions help manage content by keeping it hidden until opened.
JavaScript version
The JavaScript implementation of an accordion utilizes event listeners on each header. When a user clicks a header, JavaScript checks its current state and toggles an "active" CSS class. This class dictates whether the accordion expands to show content or collapses to hide it. Each click dynamically updates the state, allowing users to open and close sections.
CSS version
The CSS-only accordion leverages hidden checkboxes and the :has() selector for interactivity. The checkbox functions as the “state manager”: when checked, the accordion expands; when unchecked, it collapses.
The checkbox's label serves as the clickable element, and the ::after pseudo-element creates the plus sign that rotates when the section opens.
Tooltips and popovers
Tooltips are small text bubbles that appear when you hover over or focus on an element, such as when an icon reveals a brief description.
Popovers are larger, similar to tooltips but capable of holding more content, including buttons or links. Both provide extra context to users without cluttering the screen.
JavaScript version
Instead of relying on pseudo-elements or :hover, the JavaScript version uses scripts to dynamically create, attach, and control tooltip elements for each trigger on the page.
CSS version
The tooltip is powered by the ::before and ::after pseudo-elements. The ::before element contains the text, retrieved from a data-tooltip attribute, while the ::after element renders the small arrow pointing back to the trigger.
By default, both are invisible. Upon hovering over any button, the hover state activates, making the tooltip text appear.
CSS also handles positioning: .top, .bottom, .left, and .right classes adjust the tooltip's placement relative to the trigger, with the arrow automatically adapting.
Modals
A modal is a pop-up window that overlays the main content, typically to draw attention to something important. They are commonly used for action confirmation, logins, or displaying supplementary information before proceeding.
JavaScript version
This JavaScript code includes functions to open and close modals by toggling an "active" class, while also disabling page scrolling when a modal is open. Modals can be dismissed by clicking the overlay background, pressing the Escape key, or directly calling the closeModal function.
CSS version
This CSS-only modal setup uses a hidden checkbox and the :checked pseudo-class to control modal visibility. When the checkbox is checked, the overlay becomes visible, and the modal scales into view with an animation.
Dialogs
A dialog is similar to a modal, also appearing atop a webpage or application to capture attention and prompt interaction.
The key distinction is that while a modal often blocks interaction with the rest of the page until closed, a dialog can be either modal (blocking) or non-modal (allowing interaction with the page behind it). Dialogs are frequently used for alerts, confirmations, or gathering user input.
JavaScript version
This JavaScript dialog system utilizes the native <dialog> element, which provides built-in modal functionality in modern browsers. The code defines reusable openDialog and closeDialog functions, enabling dialogs to be shown or hidden by their ID.
CSS version
This CSS-only dialog relies on selectors like :checked and :target to control its display. A hidden checkbox triggers the dialog's appearance. The .dialog-overlay darkens and blurs the background, while the .dialog container transitions into view.
Carousels
Carousels are rotating banners that cycle through content slides, which can include images, text, or both. They are often used to highlight promotions, products, or featured content and are commonly seen in hero sections and other parts of a website.
JavaScript version
This JavaScript carousel tracks the current slide and moves the slides container using transform: translateX(). It sets up buttons for navigation, clickable indicators for jumping to specific slides, and a counter to display the current slide number.
The nextSlide and prevSlide methods update the index, while updateCarousel handles slide movement, indicator updates, and button enabling/disabling.
CSS version
The carousel employs CSS features like :has() and :target. Each slide is linked to a hidden anchor (#slide1, #slide2, etc.), and when one is targeted, transform: translateX() shifts the slides to reveal the correct one.
Dropdown menus
Dropdown menus are another prevalent website element, typically found in dashboards, navigation bars, or settings menus. A dropdown conceals multiple options under a single label, conserving space and maintaining a clean interface. When clicked or hovered over, the list expands, allowing users to select an item.
JavaScript version
The JavaScript dropdown menu uses a class-based setup to manage its behavior. A button acts as the toggle; when clicked, it opens or closes the menu by adding or removing a CSS class.
CSS version
The CSS-only dropdown operates by using either a hidden checkbox or the :hover state to control menu visibility.
In the checkbox version, the input acts as the toggle. When checked, CSS selectors (:checked ~ .dropdown-menu) apply styles to make the menu visible, and the arrow icon rotates to indicate the open state.
In the hover version, the menu appears when the user hovers over the button, with the arrow rotating simultaneously.
đź‘‹ First time here? Discover what Prismic can do!
Meet Prismic, your solution for creating performant websites! Developers, build with your preferred tech stack and deliver a visual page builder to marketers so they can quickly create on-brand pages independently!
Dark mode switcher
Theme switchers are an optional yet beneficial control for your website. They allow users to customize the interface's color scheme by toggling between light and dark mode. This small feature can enhance accessibility, reduce eye strain, and personalize the user experience. While not essential for functionality, it adds a thoughtful touch that users often appreciate.
JavaScript version
The JavaScript dark mode switcher first checks for a saved preference in localStorage. If none exists, it defaults to the system’s color scheme preference.
When the user clicks the main switch or an alternative toggle, it changes the theme, updates the page with a data-theme attribute, and saves the preference for future visits.
CSS version
The CSS dark mode switcher utilizes CSS variables for colors and themes, and a hidden checkbox to control light or dark mode activation.
By default, :root variables define the light theme, while a @media (prefers-color-scheme: dark) rule applies the dark theme if the system is configured for it.
The hidden checkbox (.theme-switcher-checkbox) allows users to manually override this preference. When unchecked, light theme variables are applied; when checked, dark theme variables take over.
Custom form inputs
Default form inputs often appear plain and may not align with your brand's style. This is where custom inputs become valuable. By styling inputs yourself, you can add a personal touch that matches your brand guidelines, whether modifying colors, shapes, or interactions. This ensures your forms integrate seamlessly with your website's overall design.
JavaScript version
The state of custom inputs (checkboxes, radios, and toggles) is stored in a Map, simplifying updates and tracking. When a user clicks one of these inputs, the JavaScript code updates both the stored state and the visual styles.
CSS version
This CSS version of custom form inputs hides the browser’s default checkboxes and radio buttons (opacity: 0; position: absolute;) and replaces them with styled elements (.custom-checkbox and .custom-radio).
Speed up component development with Figma to Prismic slice
Building custom UI components—whether with CSS or JavaScript—takes time. What if you could accelerate the process from design to development?
Prismic's Figma to Prismic slice plugin transforms Figma frames into structured, ready-to-code components in seconds. Select a frame in Figma, export it with the plugin, and Prismic generates a structured slice model with a starter React or Vue component, complete with mapped fields.
This eliminates manual setup work and provides a clean starting point, allowing you to focus on creative coding rather than repetitive configuration.
Try the Figma to Prismic plugin
Animations and transitions
Text animations
Text doesn't have to be static. You can animate it with various effects like fade-ins, slide-ins, bounces, color changes, and typewriter effects.
JavaScript version
The JavaScript code first selects text elements and buttons from the DOM, then defines the string for animation. When the typewriter effect starts, it resets any previous animation, disables the start button, and applies a blinking cursor effect to the right of the text.
CSS version
This CSS-only setup uses keyframes and other selectors to create the typewriter text animation. The .typewriter-text element starts with a hidden width and gradually reveals the text using the typing animation, which expands the width step-by-step while displaying a blue border on the right as a cursor. After typing finishes, the blink animation creates a blinking cursor effect.
Scroll animations
Scroll animations activate as the user navigates the page. Instead of everything loading simultaneously, elements animate into view as they become visible. This creates a more dynamic experience and encourages scrolling, making the page feel responsive to user interaction.
JavaScript version
This JavaScript setup employs the Intersection Observer API to monitor content sections. It applies a visible class when elements enter the viewport, enabling them to fade in smoothly, and removes the class when they exit.
There's also a scroll event listener that calculates the user's scroll distance within the container, then updates a progress bar's width and a text indicator to show the scroll percentage.
CSS version
This design utilizes CSS scroll-linked animations to track user scroll progress and trigger visual effects without JavaScript.
At the top, a fixed progress bar gradually fills as the user scrolls down, powered by a progressFill animation linked to the scroll timeline. In the corner, a circular progress indicator rotates its border to dynamically show progress.
Alongside it, a percentage indicator updates its number using a counter that increments with scroll, providing a precise percentage readout.
Note: CSS excels at simple animations, but for physics-based movement, timelines, or fine-grained animation control, JavaScript libraries like GSAP are more suitable.
Check out the following resources to see great examples of CSS animations:
- CSS Text Animations: 40 Creative Examples to Try
- CSS Hover Effects: 40 Engaging Animations To Try
- CSS Button Animations: 40 Ideas to Inspire You + Code Examples
- 39 Awesome CSS Animation Examples with Demos + Live Code
- Tailwind CSS Animations: Tutorial and 40+ Examples
- 40 CSS Background Effects to Enhance Your Website
- 50 Creative CSS Image Effects for Engaging Websites
- CSS Scroll Effects: 50 Interactive Animations to Try
Best Practices for Using CSS Instead of JavaScript
If you're opting for CSS over JavaScript, here are some best practices to ensure a robust implementation:
- Use semantic HTML + CSS for the base UI: Build the core layout and interactions with semantic HTML and CSS before introducing JavaScript. This ensures your site remains usable and visually consistent even if scripts fail to load.
- Always check browser support: Not all CSS features are universally supported across browsers. Before using new features like advanced selectors, scroll snapping, or container queries, consult Can I Use. This prevents layout issues in older browsers.
- Think about accessibility from the start: Don't replace JavaScript with CSS solely to avoid it. Ensure interactions are accessible with a keyboard, screen readers, or other assistive technology. For instance, CSS-only dropdowns might not always be fully accessible without ARIA attributes or JavaScript support.
- Use progressive enhancement: Start with a functional CSS solution, then layer on JavaScript if more complex functionality is required. For example, use CSS for hover effects or transitions, then add JavaScript for event tracking or dynamic updates.
- Keep it maintainable: Just because CSS can do something doesn't always mean it should. Avoid overly complicated CSS hacks purely to circumvent JavaScript. Keep your styles clean and easily maintainable for future developers.
- Test across devices: A pure CSS solution might work flawlessly on desktop but behave unexpectedly on mobile (e.g., hover-only menus). Always test your implementation across various screen sizes and devices.
CSS vs JavaScript: Choosing the Right Approach
Ultimately, neither CSS nor JavaScript is inherently “better” across the board; the choice depends entirely on your specific project. CSS excels when you need something lightweight, fast, and easy to maintain. It avoids loading extra scripts, allowing the browser to handle much of the heavy lifting. CSS is the ideal choice for simple animations, styling changes, or toggling states, especially when combined with appropriate HTML elements.
However, there are instances where CSS alone is insufficient. You might require logic, intricate user interactions, or more complex animations that depend on specific conditions. This is where JavaScript truly shines, offering flexibility and control that CSS cannot provide.
The real art lies in knowing when to use which, or how to blend both effectively. Consider CSS your first line of defense; if it can do the job, use it. If not, JavaScript is there to fill the gap. A balanced approach using both technologies results in solutions that are both visually appealing and functionally robust.
FAQs
How can I check which CSS features are supported by different browsers?
You can use websites like Can I Use. It provides detailed, up-to-date information on browser support for CSS features across all major browsers.
What are the newest CSS features available today?
How does using CSS instead of JavaScript impact my website’s accessibility?
Article written by
Alison Brunk
Alison is a technical content strategist at Prismic. She is passionate about design and web development and loves learning new tools and frameworks. In her free time, she loves playing golf and painting.

1 comments
DevM
I greatly appreciate you publishing this list. This is absolutely great.
Reply · 1 month ago
Hit your website goals
Websites success stories from the Prismic Community
How Arcadia is Telling a Consistent Brand Story

How Evri Cut their Time to Ship

How Pallyy Grew Daily Visitors from 500 to 10,000

From Powder to Pixels - Perfectly Planned Ski Vacations, Now Perfectly Digital
