Modern Web Weekly #13

Modern Web Weekly #13

Staying up to date with the modern web

👋
Hello there! I'm Danny and this is Modern Web Weekly, your weekly update on what the modern web is capable of, Web Components, and Progressive Web Apps (PWA). I test modern web features and write about them in plain English to make sure you stay up to date.

Persistent storage for PWAs

Web apps can store data in the user's browsers in various ways. You're probably familiar with cookies that can store simple data, but web apps can also use IndexedDB and Cache Storage to store larger, structured data. These two mechanisms are part of the Storage API. In addition to these, there are also localStorage and sessionStorage that are part of the Web Storage API.

The problem is that the browser may delete this data when a user hasn't used the app for a certain time. This is especially important when the user's device runs low on disk space. In that case, data from web apps that the user hasn't used for the longest time will be removed first.

Safari is the only browser that proactively removes data when Intelligent Tracking Prevention (ITP) is turned on. When a web app hasn't been interacted with for seven days, the data it saved will be removed, however, installed PWAs are excluded from this.

Web apps can now also request persistent storage in all browsers. This means that the data saved by the app will not be removed unless the data is manually removed by the user or when the device runs low on disk space. When disk space runs low, the browser will notify the user and offer to delete specific data.

How to request persistent storage

In supporting browsers, web apps can request persistent storage through navigator.storage.persist(). This returns a Promise that resolves to true or false. Permission is granted by the browser based on how much the user has interacted with the app and if the app is installed as a PWA.

To check if an app already has persistent storage, use await navigator.storage.persisted() which returns a Promise that resolves to true or false.

If persistent storage is not granted, try interacting with the app more or install it as a PWA. Browsers don't show any dialogs to ask for permission so you could consider to request for persistent storage regularly.

How much storage does my web app use?

The available and used storage space can be obtained through navigator.storage.estimate() which returns a Promise that resolves to the quota and usageproperties that return the available and used storage space respectively in bytes.

In Chrome and Edge, an additional property usageDetails is returned that specifies the used space by storage type which may vary per browser.

Available and used storage in Safari on iOS
Available and used storage in Chrome on Android

Here's a live demo on What PWA Can Do Today.

Wrap text around (almost) any shape with shape-outside

I remember a looooooong time ago, before CSS even had stuff like border-radius when I found a cool demo that made text wrap around an image. This worked by setting the image as the background of a <div> and then putting a lot of thin <div>s inside that with float: left and clear: left that together would form the shape that the text needed to wrap around.

It worked quite nicely but of course, it was a crazy hack that fell apart whenever the screen was resized to a certain size and the <div>s no longer lined up correctly to form the wanted shape.

Luckily, those days are long gone and now we can make text wrap around almost any shape with shape-outside, a CSS property that until recently I hadn't even heard of before (hey, I'm not perfect!)

shape-outside defines a (non-rectangular) shape that adjacent content like text should wrap around. For example, you can create a circular <div> with
border-radius: 50% and make text wrap around it by setting float: left on it.

Without shape-outside, the text will just wrap around the box of the <div> that is still rectangular despite the fact it's circular because it has border-radius: 50%:

Text wrapping around <div> with float: left

With shape-outside, the text wraps nicely around the circle:

Text wrapping around <div> with float: left and shape-outside: border-box

In the above image, the <div> has shape-outside: border-box which means the text will wrap around the border of the <div>, following its circular shape.

Other possible values for shape-outside are content-box where the text wraps around the content of the <div>:

Text wrapping around <div> with float: left and shape-outside: content-box

Since the <div> has padding: 24px the text is "inside" the <div>, overlapping the padding area and the border. By setting shape-outside: padding-box we can make the text wrap around the padding area of the <div>:

Text wrapping around <div> with float: left and shape-outside: padding-box

Here the <div> has a 8px border so the text overlaps it.

When the <div> has margin we can make the text wrap around the margin area with shape-outside: margin-box. In the image below, the <div> has
margin: 24px:

Text wrapping around <div> with float: left and shape-outside: margin-box

An important thing to note is that when shape-outside has a value of
content-box, padding-box, or margin-box the text will wrap around the shape defined by border-radius, but this won't work when shape-outside has a shape that is not defined by border-radius.

For example, we can also define a shape with CSS functions like circle(), polygon(), inset() or ellipse(). If we define a triangular shape with
polygon(0 0, 100% 100%, 0 100%) and set shape-outside: margin-box the text will wrap around the rectangular box of the <div> again:

Ahhh.. crap!

In this case, we need to set the same shape on shape-outside and then the text will wrap nicely around our shape again:

Text wrapping around <div> with its shape and shape-outside defined with polygon()

In the above image, the <div> has the value polygon(0 0, 100% 100%, 0 100%) for its clip-path and shape-outside CSS properties.

Note that there is no margin between the shape and the content here and any margin applied to the <div> will not have any effect on the side of the shape, only at the left and the bottom.

To add margin, use the shape-margin property. In the image below, the <div> has shape-margin: 24px:

Text wrapping around <div> with shape-margin

You can also use shape-outside and shape-margin on images to make the text wrap nicely around it. Check the MDN page for more interesting examples. Here's a codepen to play around with (you may need to go to the browser version of this email to view it):

🔗
Got an interesting link for Modern Web Weekly?
Send me a DM on Twitter to let me know!