A consistent goal for all web devs should be to do more with less. Especially if we can reduce, or completely remove, any JavaScript from a page!
Not only does JS need to be downloaded, but then decompressed, evaluated and processed. And after all of that, it consumes browser resources by monitoring the page and user activities.
This article focuses on documenting ways in which we can replace JS with no-JS (or at least lo-JS) options. An easy example would be when we replaced things like a JS onmouseover
event with a CSS :hover
.
As is the case with the above example, we tend to use JS initially because that is the only way we can do something. If plain HTML and/or CSS had limitations, we figured out some way to do something and went with that.
But when HTML/CSS finally implement methods that allow us to do things without JS, it can be difficult tracking the new methods and getting the time to update our code bases.
Hopefully this article can help with tracking the new methods and, ideally, reduce the time required to update your code bases!
- 3D Card Hover Effect
- 3D Image Hover Effect
- Accordion / Expanding content
- Flip Gallery / Carousel
- Hover Gallery / Carousel
- Modal / Popover
- Nav Offscreen Push
- Pulsing animation
- Scroll-based Animation
- Search with autosearch and suggestions
- Shrinking fixed header
- Tooltip
- View Transitions API
3D Card Hover Effect
No JS
Description:
Initially appearing as small thumbnails, when hovered they grow and expand with movement and animation:
Use cases:
- Product grid, product showcase, hero sections, content blocks
Resources:
Browser compatibility:
- Uses grid, object-fit and object-position, transition and transform.
3D Image Hover Effect
No JS
Description:
Image turns when hovered, giving the appearance of 3D animation:
Use cases:
- Product grid, product showcase, hero sections, content blocks
Basic implementation:
Resources:
Browser compatibility:
- Uses calc, var, aspect-ratio, grid, clip-path, object-fit and object-position, transition and transform.
Accordion / Expanding content
No JS
Description:
The details
and summary
HTML elements provide an HTML-only replacement to the typical JS accordion:
Use cases:
- Hiding/showing content
- Expanding content sections
Basic implementation:
<details> <summary>Title of Accordion</summary> Content that is initially hidden, but revealed when clicking the summary. </details>
Resources:
- https://developer.mozilla.org/en-US/docs/Web/HTML/Element/details
- https://www.codewithshripal.com/playground/html/details-element
Browser compatibility:
Flip Gallery / Carousel
No JS
Description:
Create a clickable or keyboard-navigable gallery:
Use cases:
- Product gallery
- Product carousel
Resources:
Browser compatibility:
- CSS
:has
could be the only blocker: https://caniuse.com/css-has
Hover Gallery / Carousel
No JS
Description:
Create an expandable gallery on hover:
Use cases:
- Product gallery
- Product carousel
Resources:
- https://twitter.com/davidm_ml/status/1673258441266036736
- https://github.com/atherosai/ui/tree/main/gallery-01
- https://codepen.io/ahmadghoniem/pen/QWJdMMe
Browser compatibility:
- CSS
display: flex
andtransition
, should be no issues.
Modal / Popover
No JS
Description:
Replaces the traditional modal/popover/overlay.
Use cases:
- Hiding/showing navigation menus
- Hiding/showing side panels / additional information
Basic implementation:
<a href="#modal">Open modal</a> <dialog id="modal"> <a href="#">Close modal</a> Modal content... </dialog> <style> /* The dialog element is innately display: none, and position: absolute */ dialog:target { display: block; z-index: 11; } /* Give the dialog a background blocker when it is open */ body:has(dialog:target)::before { content: ''; position: fixed; inset: 0; z-index: 10; background: rgba(0, 0, 0, .5); } </style>
Future implementation:
<button popovertarget="pop"> Toggle Popup! </button> <dialog popover id="pop"> I'm a Popover! </dialog>
Resources:
- https://codepen.io/jh3y/pen/XWPBmmo
- https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/popover
- https://mdn.github.io/dom-examples/popover-api/
- https://developer.chrome.com/blog/introducing-popover-api/
Browser compatibility:
Nav Offscreen Push
No JS
Description:
This offscreen navigation menu pushes the onscreen content aside, and can even push the body aside.
Use cases:
- Hiding/showing navigation menus
- Hiding/showing side panels / additional information
Basic implementation:
<button popovertarget="menu"> Toggle Menu </button> <nav popover id="menu" role="menu"> <!-- Nav Content --> </nav> <style> [popover] { overflow: hidden; } body:has(#menu:open) { translate: calc(var(--menu-width) * -1) 0; } </style>
Resources:
- https://codepen.io/jh3y/pen/VwGGqmm
- https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/popover
- https://developer.chrome.com/blog/introducing-popover-api/
Browser compatibility:
Pulsing animation
No JS
Description:
Use CSS only to create a pulsing animation.
Use cases:
- Draw attention to an icon or badge
- Could be used on initial state or applied via
:hover
Basic implementation:
<div class="blob"></div> <style> .blob { background: white; border-radius: 50%; height: 5rem; width: 5rem; animation: pulse 2s infinite; } @keyframes pulse { 0% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.7); } 70% { transform: scale(1); box-shadow: 0 0 0 2rem rgba(255, 255, 255, 0); } 100% { transform: scale(0.95); box-shadow: 0 0 0 0 rgba(255, 255, 255, 0); } } </style>
Resources:
Browser compatibility:
- All modern browsers
Scroll-based Animation
No JS (though many demos have “JS versions” which could be used as unsupported fallbacks)
Description:
As the user scrolls, either the page or within a component, pure CSS animation can create enticing interactions.
Use cases:
- Product gallery
- Product carousel
- Product carousel progress indicator
- Product or Content Image Reveal
- Stacked Product Grid (could reverse below effect, so products are initially stacked, and expand on scroll)
Resources:
- https://developer.chrome.com/articles/scroll-driven-animations/
- https://github.com/w3c/csswg-drafts/blob/main/scroll-animations-1/EXPLAINER.md
- https://scroll-driven-animations.style/
- https://scroll-driven-animations.style/#demos
- https://scroll-driven-animations.style/#tools
- https://codepen.io/jh3y/pen/zYmVobx
- https://codepen.io/jh3y/pen/ZEqNVxx
Browser compatibility:
Search with autosearch and suggestions
No JS
Description:
The HTML search input type is not exactly new, but offering a dropdown of search results that autofilter as the user types has always been a JS solution.
Use cases:
- Site search
- Product search or filter
Basic implementation:
<label for="country">Country</label> <input type="text" list="countrydata" id="country" name="country" size="50" autocomplete="off" /> <datalist id="countrydata"> <option>Afghanistan</option> <option>Åland Islands</option> <option>Albania</option> <option>Algeria</option> <option>American Samoa</option> <option>Andorra</option> <option>Angola</option> <option>Anguilla</option> <option>Antarctica</option> ...etc... </datalist>
Resources:
- https://www.sitepoint.com/html5-datalist-autocomplete/
- https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist
Browser compatibility:
Shrinking Fixed Header
Description:
A fixed header has been easy for some time, using position: fixed
. But the shrinking fixed header has always required JS.
Well not for long…
Use cases:
- Website header
Basic implementation:
header { animation: shrink; animation-timeline: scroll(); animation-range: 0 90vh; }
Resources:
Browser compatibility:
Tooltip
No JS
Description:
This tooltip allows you to add basic text on hover.
Use cases:
- Instructions
- Additional information
Basic implementation:
<a href="https://www.example.com" class="tooltip" aria-label="This is the tooltip text.">tooltip</a> <style> .tooltip { position: relative; } .tooltip::after { content: attr(aria-label); display: none; position: absolute; left: -50%; bottom: 100%; text-align: center; width: 50vw; background: #444; color: white; } .tooltip:hover::after { display: block; } </style>
Resources:
Browser compatibility:
- All modern browsers.
View Transitions API
No JS / Lo JS
Description:
The View Transitions API provides a mechanism for easily creating animated transitions between different DOM states, while also updating the DOM contents in a single step.
– https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API
Page transitions not only look great, they also communicate direction of flow, and make it clear which elements are related from page to page. They can even happen during data fetching, leading to a faster perception of performance.
– https://developer.chrome.com/docs/web-platform/view-transitions/
Examples:
(The code for all of these is a bit much to include below, please consult each example.)
- Grid-to-overlay transition; requires some JS: https://bentogrids.com/
- This example is more like the old masonry layout, expanding and contracting clicked images within the grid, and is CSS only: https://www.bram.us/2023/05/09/rearrange-animate-css-grid-layouts-with-the-view-transition-api/
- While this does still require some JS, the real power comes from the CSS, which provides an animation during transition: https://http203-playlist.netlify.app/with-paul/
Note the transitioning elements can be different elements, even across different pages.
Use cases:
- Zoom for images or videos
- Direct focus on section of page
- Open/close modals
- Transition from PLP to PDP, retaining product focus
Resources:
- https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API
- https://developer.chrome.com/docs/web-platform/view-transitions/
- https://daverupert.com/2023/05/getting-started-view-transitions/
Browser compatibility: