WebKit Features in Safari 17.5

Happy May! It’s time for another release of Safari — our third significant update of 2024. With just a month untilWWDC24and the unveiling of what’s coming later this year, we are happy to get these 7 features and 22 bug fixes into the hands of your users today.

CSS

There are several exciting new CSS features in Safari 17.5, includingtext-wrap: balance,thelight-dark()color function, and@starting-style,plus the ability to use feature queries with@importrules. Let’s look at how you can put each one to use.

Text wrap balance

On the web, with its flexible container widths, inconsistent lengths of content, and variation between browsers, it can feel impossible to avoid having text wrap in such a way that too few words end up all by themselves on a very short last line.

Very long text headline wrapping using the normal algorithm — which leaves a single word on the last line, all by itself

When type was set by hand, typographers would painstakingly avoid this undesirable result by manually moving content around. Over the decades, web developers have tried a series of different tricks to avoid orphans in CSS, in HTML, in JavaScript, and in content management systems. None work very well. The attempts usually feel hacky, laborious, and fragile.

To solve this and other frustrations, the CSS Working Group hasdefinedthree new options that you can use to change how text will wrap. You can switch from default wrapping to another style withtext-wrap.WebKit for Safari 17.5 adds support for the first of these new options — balancing.

Thetext-wrap: balancerule asks the browser to “balance” the lines of text and make them all about the same length.

A very long headline wrapped using text-wrap: balance, so each of the three lines are the same length as each other — and none of them fill all the horizontal space available

You can see how now the text no longer fills the containing block — there’s a large amount of space on the right of the words. This is expected, and something you’ll want to think about as you decide when to usetext-wrap: balance.

Whereexactlyeach line of text will break when usingtext-wrap: balancemay be slightly different in each browser. TheCSS Text level 4web standard leaves it up to each browser engine team to decide which algorithm they want to use in determining how exactly to wrap balanced text.

It can be computationally expensive for the browser to count characters and balance multiple lines of text, so the standard allows browsers to limit the number of lines that are balanced. Chromium browsers balance 6 or fewer lines, Firefox balances 10 or fewer, while Safari/WebKit balances an unlimited numbers of lines.

For now, Safari does not balance text if it’s surrounding a float or initial letter. And Safari disables the balancer if the content contains preserved tabs or soft hyphens.

Text wrap shorthands and longhands

Thetext-wrapproperty is actually a shorthand for two longhand properties:text-wrap-styleandtext-wrap-mode.

Thetext-wrap-modeproperty provides a mechanism for expressing whether or not text should wrap.

text-wrap-mode:wrap;/* initial value */
text-wrap-mode:nowrap;

Thewrapvalue turns it on, and thenowrapvalue turns it off, just like the values forwhite-space.(In fact,text-wrap-modeis the newly introduced longhand ofwhite-space.) WebKit added support fortext-wrap-mode: wrapandnowrapinSafari 17.4.

Thetext-wrap-styleproperty selectshowto wrap. The initial value isauto— asking text to wrap in the way it has for decades. Or, you can choose a value to switch to another “style” of wrapping.

WebKit for Safari 17.5 adds support fortext-wrap-style: balance,stable,andauto.

text-wrap-style:auto;/* initial value */
text-wrap-style:balance;
text-wrap-style:stable;

Of course, thetext-wrapshorthand is a way to combinetext-wrap-modeandtext-wrap-styleand declare them together. If you writetext-wrap: balanceit’s the same astext-wrap: wrap balance,meaning: “yes, please wrap, and when you do, please balance the text”.

Full support will eventually include three properties and six values. No browser supports everything yet, so be sure to look up support for thetext-wrap,text-wrap-mode,andtext-wrap-styleproperties, as well as thebalance,pretty,stable,auto,wrap,andnowrapvalues.

Thebalance,pretty,andstablevalues will simply fall back toautoin browsers without support, so progressive enhancement is easy. You can use these values today, no matter how many of your users don’t yet have a browser with support. They will simply getauto-wrapped text, just like they would if you didn’t usetext-wrap.Meanwhile, those users with support will get an extra boost of polish.

Dark mode and thelight-dark()color function

More and more, users expect websites and web apps tosupport dark mode.SinceSafari 12.1,theprefers-color-schememedia query has given you the ability to write code like this:

body{
background:white;
color:black;
}
@media(prefers-color-scheme:dark) {
body{
background:darkslategray;
color:white;
}
}

Or perhaps you’ve used variables to define colors for both light and dark mode at once, making it easier to use them everywhere.

:root{
--background:white;
--text:black;
}
@media(prefers-color-scheme:dark) {
:root{
--background:darkslategray;
--text:white;
}
}
body{
background:var(--background);
color:var(--text);
}

Well, now there’s a new option — thelight-dark()function. It makes defining colors for dark mode even easier.

First, inform the browser you are providing a design for both light and dark modes with thecolor-schemeproperty. This prompts the browser to switch the default user agent styles when in dark mode, ensuring the form controls appear in dark mode, for example. It’s also required forlight-dark()to work correctly.

:root{
color-scheme:lightdark;
}

Then, any time you define a color, you can use thelight-dark()function to define the first color for light mode, and the second color for dark mode.

color:light-dark(black,white);
background-color:light-dark(white,darkslategray);

You can still use variables, if you’d like. Perhaps you want to structure your code like this.

:root{
color-scheme:lightdark;
--background:light-dark(black,white);
--text:light-dark(white,darkslategray);
}
body{
background:var(--background);
color:var(--text);
}

An often-asked question when learning aboutlight-dark()is “does this only work for colors?” Yes, this function only works for colors. Use theprefers-color-schememedia query to define the rest of your color-scheme dependent styles.

Starting style

WebKit for Safari 17.5 adds support for@starting-style.It lets you define starting values for a particular element. This is needed to enable a transition when the element’s box is created (or re-created).

.alert{
transition:background-color2s;
background-color:green;
@starting-style{
background-color:transparent;
}
}

In the above example, thebackground-colorwill transition from transparent to green when the element is added to the document.

Many developers are excited to use@starting-stylealong withdisplay: noneinterpolation. To do so, WebKit also needs tosupportanimation of thedisplayproperty, which has not yet shipped in Safari. You can test this use case today inSafari Technology Preview.

Features queries for importing CSS

WebKit for Safari 17.5 adds thesupports()syntax to@importrules. Now you can conditionally import CSS files based on whether or not there’s support for a certain feature.

@import<url>supports(<feature>);

For example, you could load different stylesheets based on whether or notCSS Nestingissupported.

@import"nested-styles.css"supports(selector(&));
@import"unnested-styles.css"supports(notselector(&));

Or you could load certain CSS files when a browser does not havesupportforCascade Layers.(Note that any@importrules withlayer()will automatically be ignored in a browser without layer support.)

@importurl( "reset.css" )layer(reset);
@importurl( "framework.css" )layer(framework);
@importurl( "custom.css" )layer(custom);

@importurl( "unlayered-fallback-styles.css" )supports(notat-rule(@layer));

Or simply test for a feature. Here, these layout styles will only be loaded ifSubgridissupported.

@importurl( "layout.css" )supports(grid-template-columns:subgrid);

WebCodecs

WebKit for Safari 17.5 adds support for AV1 to WebCodecs when an AV1 hardware decoder is available.

WebGL

WebKit for Safari 17.5 adds WebGL support forEXT_conservative_depthandNV_shader_noperspective_interpolation.

WKWebView

WKWebView adds support for logging MarketplaceKit errors to the JavaScript console. This will make errors easier to debug.

Bug Fixes and more

In addition to these new features, WebKit for Safari 17.5 includes work polishing existing features.

Accessibility

  • Fixed a bug preventing VoiceOver word echoing in some text fields. (122451549) (FB13592798)

Animations

  • Fixed flickering with multiple accelerated animations and direction changes. (117815004)

Authentication

  • FixedexcludeCredentialsproperty being ignored during a passkey registration request. (124405037)

CSS

  • Fixed the proximity calculation for implicit@scope.(124640124)
  • Fixed the Grid track sizing algorithm logical height computation avoid unnecessary grid item updates. (124713418)
  • Fixed any@scopelimit making the element out of scope. (124956673)

Forms

  • Fixed native text fields becoming invisible in dark mode. (123658326)
  • Fixed fallback native<select>rendering in dark mode. (123845293)

Media

  • Fixed scrolling for an element when a video element withpointer-events: noneis placed over it. (118936715)
  • Fixed HTML5<audio>playback to continue to the next media activity when in the background. (121268089) (FB13551577)
  • Fixed AV1 to decode in hardware on iPhone 15 Pro. (121924090)
  • Fixed audio distortion over internal speakers when streaming content in web browsers. (122590884)
  • Fixed firingloadeddataevents for<audio>and<video>on page load. (124079735) (FB13675360)

Rendering

  • Fixed adjusting the size of the scrollable area when changing betwen non-overlay and overlay scrollbars. (117507268)
  • Fixed flickering when showing a layer on a painted background for the first time by avoiding async image decoding. (117533495)
  • Fixed line breaking before or between ruby sequences. (122663646)

Web API

  • Fixedmousemoveevents in aniframewhen the mouse is clicked from outside theiframeand then moves into it while the button is held down. (120540148) (FB13517196)

Web Apps

  • Fixed several issues that caused Web Push to not show notifications when the web app or Safari was not already running. (124075358)

Web Inspector

  • Fixed info and debug buttons not appearing in the Console Tab until new console messages are displayed. (122923625)

WebRTC

  • Fixed WebCodecs to correctly use the VP9 hardware decoder. (123475343)
  • Fixed no incoming video in Teams VA. (124406255)
  • Fixed the camera pausing occasionally when torch is enabled. (124434403)

Updating to Safari 17.5

Safari 17.5 is available oniOS 17.5,iPadOS 17.5,macOS Sonoma 14.5,macOS Ventura, macOS Monterey and in visionOS 1.2.

If you are running macOS Ventura or macOS Monterey, you can update Safari by itself, without updating macOS. On macOS Ventura, go to  > System Settings > General > Software Update and click “More info…” under Updates Available.

To get the latest version of Safari on iPhone, iPad, or Apple Vision Pro, go to Settings > General > Software Update, and tap to update.

Feedback

We love hearing from you. To share your thoughts on Safari 17.5, find us on Mastodon at@[email protected]and@[email protected].Or send a reply on X to@webkit.You can alsofollow WebKit on LinkedIn.If you run into any issues, we welcome yourfeedbackon Safari UI, or yourWebKit bug reportabout web technologies or Web Inspector. Filing issues really does make a difference.

Download the latestSafari Technology Previewon macOS to stay at the forefront of the web platform and to use the latest Web Inspector features.

You can also find this information in theSafari 17.5 release notes.