Modern Web Weekly #35
Modern Web Weekly #35
content-visibility is now supported in all browsers
With Safari 18 joining the party, all major browsers now support the CSS content-visibility
property.
This property controls whether or not a DOM element is rendered, allowing the browser to skip rendering it if, for example, the element is not visible in the viewport. It enables browsers to skip rendering elements until they're needed, which can result in great performance improvements.
A typical use case for this is a page that has a lot of big images on it. Normally, all images would be rendered by the browser which can result in a slow initial load. If you apply content-visibility: auto
to it, the browser can skip rendering the images that are off-screen and only render them when they're almost scrolled into the viewport. This not only improves the loading time of the document but it also allows for faster interaction with the page.
It also works in the other direction. If an element that was previously rendered is scrolled out of the viewport the browser can decide to not render it anymore. If you have a very long page that is slow, you can improve its performance dramatically because adding content-visibility: auto
allows the browser to skip rendering any off-screen elements.
You can also use the values visible
and hidden
for content-visibility
. visible
has no effect and hidden
means that the contents of the element will not be rendered, similar to when visibility: hidden
is set on it.
In practice, you will usually only use auto
and let the browser decide when the element should be rendered.
Demo
Here's a Codepen that demonstrates how content-visibility
works. It contains 7 images with a lot of text between them. In the console you can see per image if the rendering of that image is skipped. Depending on your screen size, you will notice that only the first or the first two images are rendered and the rest is not.
As you scroll down, you will notice that other images will be rendered as they approach the viewport and that other images that are scrolled away from the viewport are no longer rendered.
Retry requests with Basic Service Worker
I created a basic Service Worker that you can use to implement offline support for your web app. It caches all assets like images, CSS and scripts locally as well as responses to routes. The Service Worker intercepts all requests and when there is no network, it serves all responses from that cache to make sure your web app can work, even without a network.
You can find it here on Github:
Like I wrote in the previous edition of Modern Web Weekly, offline support makes sense for all web apps, even if your web app needs a network to function.
Does your email app show you a useless white screen with a dinosaur when you're offline? Of course not.
It just shows you your inbox and any messages that you send while offline will be saved in the outbox and sent when the app is back online. Email apps don't treat offline as an error but as a common state that your app can be in and that it should be able to handle.
In the new version I just released, I added support for retrying requests.
The Service Worker stores all POST, PUT, DELETE and other explicitly listed requests that are made while the app is offline and retries these when the app is back online. You can adapt this to your own needs in the isRequestEligibleForRetry
function.
In supporting browsers, it uses the Background Sync API and in other browsers it posts a message to the Service Worker when the app comes back online. The latter offers less granular control than the Background Sync API but suffices for this use-case.
If you have implemented the Service Worker in your web app, share the result on X using #ProjectServiceWorker.
Invalid form control not focusable in Safari
I was pointed to a bug in my form-element-mixin repo on Github which prevented a custom form validation error message being shown. The bug appeared when the native validation error message was shown for a form control inside a web component.
In case you missed it, web components can now be full-fledged form controls that participate in form submission and validation just like native form controls. The form-element-mixin repo provides a mixin that you can use to turn any web component into a form control that behaves just like a native one.
This mixin uses the ElementInternals
interface that can be used to set the validity of a web component form control through the setValidity
method. It usually only takes two arguments with the first one indicating the validation error (for example, valueMissing
, patternMismatch
, rangeOverflow
etc.) and the error message to be shown.
The method also takes an optional third parameter which is the HTML element the message should be anchored to. This is always the form control itself but in Safari this would throw the error "An invalid form control with name='...' is not focusable".
After some digging, I found out that it would work again in Safari if I would pass the form control itself as the third parameter. This seems redundant but hey, it now works in Safari as well ;-)
Remote debugging a PWA on iOS
If you build PWAs, you probably already noticed that remotely debugging a PWA running on an iPhone or iPad is a pain in the neck. You can't inspect the Service Worker because it simple doesn't show up in the Develop menu in Safari and console logs coming from the Service Worker are not shown.
Strangely enough, Service Workers are shown for not installed web apps running in Safari on iOS but as soon as the web app is added to the Home Screen, the Service Worker entry disappears into Apple's infamous web app Black Hole...
Your best bet is to run Simulator on iOS when you want to debug a PWA running on iOS. Not perfect, but until Apple finally decides to fix this, it's all we have...