Modern Web Weekly #13
Staying up to date with the modern web
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 usage
properties 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.
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%
:
With shape-outside
, the text wraps nicely around the circle:
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>
:
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>
:
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
:
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:
In this case, we need to set the same shape on shape-outside
and then the text will wrap nicely around our shape again:
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
:
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):
Send me a DM on Twitter to let me know!