Today’s the day for Safari 17.0. It’s now available for iOS 17 and iPadOS 17.
[Update September 26th] And now, Safari 17.0 is available for macOS Ventura, and macOS Monterey, and macOS Sonoma. Safari 17.0 is also available in the vision OS Simulator, where you can test your website by downloading the latest beta of Xcode 15, which supports the visionOS SDK.
If you are running macOS Ventura or macOS Monterey, you can update Safari by going to Software Update and clicking “More info”. On macOS Ventura, that’s > System Settings > General > Software Update > More info, and choose to update Safari. To get Safari 17.0 on your iPhone or iPad, go to Settings > General > Software Update and tap to update to iOS 17 or iPadOS 17.
HTML The new search elementWhile new web technology is defined in web standards all the time, it’s rare for a brand-new HTML element to come along. It only happens when something meets very high expectations of utility. Search is a key function for most websites, so now, there’s a new element — <search>
.
Up until now, search boxes were often constructed in markup like this:
<div class="search-box" role="search">
<form action="/search">
<p><input type="search" name="q"> <input type="submit" value="Search!"></p>
</form>
</div>
Notice the presence of ARIA role="search"
on the first line of code above. Without the ARIA search role, search functionality is not made properly accessible to all users — a problem that’s far too easy to create.
The <search>
element automatically provides the correct accessibility semantics for the search section of a website or web app. This aligns with the principles of HTML, making the default accessible, instead of requiring you to remember to take an action to add accessibility. The <search>
element also supplies the semantic markup for communicating the inherent meaning of a search form to a wide range of computing contexts, from translation algorithms to machine learning.
We are excited to be the first browser to ship this new <search>
element, now supported in Safari 17.0.
<search>
<form action="/search">
<p><input type="search" name="q"> <input type="submit" value="Search!"></p>
</form>
</search>
Browsers without support for the search element will recognize there is an element present, and they will recognize any attributes it has — including roles, IDs, and classes. It will simply behave like a generic element, as if it were a <div>
. Because of this, we recommend you include an ARIA search role on the <search>
element for now. By using <search role="search">
, you will ensure every user has the intended experience. And in the future, when all browsers have support, you can drop the ARIA search role.
In the meantime, you can start using <search>
today with confidence, long before a significant percent of your audience use browsers with support.
Safari 17.0 adds support for the popover attribute. It provides a framework built into the web for displaying overlays, popups, popovers, and dialogs.
There are two types of popovers, which can be used as values for the popover
attribute:
auto
popovers, which automatically close when you click outside of the popover; andmanual
popovers, which don’t have this automatic closing behavior.Start with a button (either <button>
or <input type="button">
) to create the UI for opening and closing the popover. Then, add the appropriate HTML attributes to create the desired result.
The popovertarget
attribute connects the button to the popover content through an ID. The optional popovertargetaction
attribute takes show
, hide
, or toggle
as values. By default, toggle
is used.
<button popovertarget="info-box" popovertargetaction="show">More info</button>
<article id="info-box" popover="auto">
<h2>Additional Information</h2>
<p>Here’s something I wanted to tell you.</p>
<button popovertarget="info-box" popovertargetaction="hide">Close</button>
</article>
This is just one UI pattern you might find useful. There are many possible combinations. Having a popover mechanism in HTML makes for quick work, while ensuring great usability and full accessibility.
To go beyond a simple button trigger, a JavaScript API opens up more powerful possibilities through showPopover()
, hidePopover()
, and togglePopover()
.
Safari 17.0 on macOS also adds support for <hr>
inside of <select>
, a feature the WebKit team added to the HTML web standard. This makes it easier to create a visual separator between items without requiring the use of JavaScript.
<select>
<option value="pizza">Pizza</option>
<option value="hamburger">Hamburger</option>
<hr>
<option value="sushi">Ice cream</option>
<option value="pasta">Cake</option>
</select>
CSS Font size adjust
In Safari 16.4, we shipped initial support for font-size-adjust
, which allows you to easily make the visual size of different fonts consistent — even across all possible combinations of fallback fonts.
The basic version of font-size-adjust
lets you tell the browser to resize letters so that their x-height is a specific ratio of the font-size
. In Safari 17.0, we’re expanding support to include more advance capabilities of font-size-adjust
, including the from-font
value and the two-value syntax.
The two-value syntax lets you to switch from adjusting ex-height
to adjusting cap-height
, ch-width
, ic-width
, or ic-height
— providing support for a broader range of writing systems and design choices.
Instead of declaring a ratio with a number value, the from-font
value allows you to ask the browser to pull the sizing metric from the primary font being specified, and apply that ratio to all fonts.
Let’s look at an example. Here, font-size-adjust
tells the browser to make all of the fonts inside article
match the size of the x-height of the main font being used. This means all of the text in paragraphs and code will visually appear to be the same size, no matter which font is applied from either stack, or how different the paragraph and code fonts appear in actual size.
article {
font-family: "Iowan Old Style", "Palatino Linotype", "URW Palladio L", P052, serif;
font-size: 1.4rem;
font-size-adjust: from-font;
}
article code {
font-family: "Courier New", monospace;
}
Safari 17.0 also adds support for @font-face size-adjust
, providing a way for you to normalize visual size when defining a font’s use.
Safari 17.0 adds support for text-transform: full-width
and text-transform: full-size-kana
.
The full-width
value transforms all the characters in your text to be “full-width” — to match the width of characters defined in an East Asian script like Chinese, Japanese, or Korean (CJK). It’s especially useful when typesetting vertical text or wanting to provide consistency in sizing when mixing CJK with Latin or other scripts.
The full-size-kana
value transforms the size of small Kana characters in Japanese to look like their full-size counterparts — a technique sometimes used to make ruby
text more legible at small sizes.
Safari 17.0 also adds support for declaring more than one text-transform
value, so that these values can be combined. For example text-transform: uppercase full-width
will transform characters in a Latin script to be both all capital letters and the same width as the CJK characters in the font.
To expand what’s possible with web typography, Safari 17.0 adds two feature queries for conditionally applying CSS depending on the presence or absence of browser support for a particular font format or technology: @supports font-format()
and @supports font-tech()
.
The font format feature query tests for support of specific font formats, like opentype
and woff2
. The font tech feature query lets you test for support of specific OpenType technologies, like COLRv0
.
@supports not (font-tech(color-COLRv0) or font-tech(color-COLRv1)) {
h1 {
color: --text-color-for-non-color-fonts;
}
}
Safari 17.0 also adds support for @font-face { src: url() tech() }
, making it easy to tell the browser to download and use a font only if its underlying technology is supported, while providing alternative font files as fallbacks.
@font-face {
font-family: "My Cool Font";
src: url("mycoolfont-COLRv0.otf") format(opentype) tech(color-COLRv0),
url("mycoolfont-COLRv1.otf") format(opentype) tech(color-COLRv1),
url("mycoolfont-outline.otf") format(opentype);
}
Hyphenation
Supported in Safari with -webkit-
prefixes since 2011, the hyphens
and hyphenate-character
properties are now supported in their unprefixed form.
The hyphens
property lets you specify whether or not words should be hyphenated when text wraps onto multiple lines. The default, hyphens:manual
, causes the browser to hyphenate only at manually-specified points. You can instead ask the browser to insert hyphens automatically according to an algorithm. Be sure to use the lang
attribute to identify the langauge being used, so the browser can reference the correct hyphenation dictionary.
<html lang="en-US">
<p>Content that will be hyphenated according to
the grammatical rules of U.S. English.<p>
</html>
article {
hyphens: auto;
}
The hyphenate-character
property lets you specify which character (or string) to use when breaking words. By default, it’s set to the content language’s typographic conventions. In English, for example, it’s set to -
. But if you need to change it, you can.
Safari 17.0 adds support for @counter-style
.
CSS Counter Styles provide a mechanism for changing a counter’s language or character set in CSS — both for ordered/unordered lists (with list-style-type
) and for CSS Counters.
For example, I can define a counting system for Serbian, and use it to number ordered lists.
@counter-style upper-serbian {
system: alphabetic;
symbols: 'А' 'Б' 'В' 'Г' 'Д' 'Ђ' 'Е' 'Ж' 'З' 'И' 'Ј' 'К' 'Л' 'Љ' 'М' 'Н' 'Њ' 'О' 'П' 'Р' 'С' 'Т' 'Ћ' 'У' 'Ф' 'Х' 'Ц' 'Ч' 'Џ' 'Ш';
}
ol {
list-style: upper-serbian;
}
Display contents
WebKit for Safari 17.0 fixes our remaining accessibility issues with display:contents
.
Improvements in the experience of elements which are styled display:contents
include:
grid
, treegrid
, table
, row
, gridcell
, cell
, columnheader
, tree
and treeitem
are properly exposed in the accessibility tree.aria-checked
works for elements with the ARIA roles tree
and treeitem
.directory
.display:contents
list items.aria-checked
work for role="treeitem"
.aria-activedescendant
work.aria-grabbed
and aria-dropeffect
work.aria-flowto
work.speak-as
, AXAccessKey, aria-owns
, and URL AX APIs work.Safari 17.0 also fixes accessibility issues with HTML tables and table components that have display: flex
, grid
, block
, or inline-block
applied.
Safari 17.0 completes WebKit’s support for the Media Queries level 4 web standard, adding support for four new media queries.
Like other media queries, overflow-block
and overflow-inline
provide a way to conditionally apply CSS depending on the qualities of a user’s device — in this case, how a device handles overflow. For example, can it scroll the page like a typical browser on a computer? Does it page the content, like an e-book reader? Or does it have no mechanism for handling overflow, like a digital billboard?
The update
media query provides a way to apply CSS depending on the refresh rate of the device. For instance, e-book reader screens often have slower refresh rates. A printed page has no refresh rate at all.
We’ve also added support for thescripting
media query. It allows you to conditionally apply CSS based on whether or not JavaScript support is enabled in the user’s browser.
Safari 17.0 also improves our implementation of image-set()
, increasing interoperability with other browsers as part of our commitment to Interop 2023.
The image-set()
function lets you list a set of images in CSS, with information about each, and have the browser pick the most appropriate image to use from that set. Safari 17.0 now supports the optional resolution
and type
arguments.
The resolution
argument provides a way to declare information about the resolution of each image: 1x
, 2x
, 600dpi
, etc.
The type
argument provides a means to offer multiple file types — including the JPEG XL and HEIC formats newly supported in Safari 17.0. The browser will download and use the first one it supports.
main {
background-image: image-set(
url("images/trees.jxl") type("image/jxl"),
url("images/trees.avif") type("image/avif"),
url("images/trees.jpeg") type("image/jpeg")
);
}
Container Queries
To keep up with the most recent changes to the web standard for Container Queries, Safari 17.0 adds support in CSSOM for containerName
and containerQuery
, and updates conditionText
to be the concatenation of the first two in CSSContainerRule
.
Safari 17.0 also adds support for contain-intrinsic-size
, providing the means for setting the size of an element, when that element is subject to size containment.
To increase the usefulness of :has()
, WebKit now supports :has(:buffering)
and :has(:stalled)
. These expand the ability to apply CSS conditionally based on the state of media playback. Safari 17.0 also supports :has(:defined)
letting you apply styling in the presence of a custom element that’s been defined.
Safari 17.0 and WebKit for iOS 17, iPadOS 17, and macOS now fully support the Storage API.
WebKit is also updating the storage quota policy. Previously, an origin had a starting storage limit of 1 GB. When exceeding that limit, the subsequent storage operation would fail in Home Screen web apps or prompt the user to give permission to increase the quota in Safari.
Now, the origin quota is calculated based on total disk space. This means an origin generally gets a much higher limit, and users will no longer receive permission prompts in Safari. You can use StorageManager.estimate()
to get estimated usage and quota values per origin.
With each origin getting a higher storage limit by default, WebKit will evict data by origin when the total usage of all origins together is bigger than a certain value — the “overall quota”, calculated based on total disk space.
An origin is exempt from eviction when its storage mode is persistent. To check the storage mode of your origin, you can use navigator.storage.persisted()
. To request the mode be changed to persistent, you can use navigator.storage.persist()
. Critical bugs have been fixed to ensure the storage mode value is remembered across sessions.
Read Updates to Storage Policy for many more details, along with example code.
Offscreen CanvasWhen using Canvas, the rendering, animation, and user interaction usually happens on the main execution thread of a web application. Offscreen Canvas provides a canvas that can be rendered off-screen, decoupling the DOM and the Canvas API so that the <canvas>
element is no longer entirely dependent on the DOM. Rendering can be transferred to a worker context, allowing you to run tasks in a separate thread and avoid heavy work on the main thread that can negatively impact the user experience. The combination of DOM-independent operations and rendering of the main thread can provide a significantly better experience for users, especially on low-power devices.
Support for Offscreen Canvas 2D operations shipped in Safari 16.4. Now, Safari 17.0 for macOS Sonoma, iPadOS 17 and iOS 17 adds support for WebGL in Offscreen Canvas, bringing these benefits to 3D.
CanvasThe CanvasRenderingContext2D.drawImage()
method of the Canvas 2D API supports different sources of an image to be drawn onto the canvas. Safari 17.0 adds support for SVG by allowing SVGImageElement
as an image source to drawImage()
.
Safari 17.0 adds JavaScript support for two new features for Regular Expressions: RegExp v flag with set notation + properties of strings and RegExp duplicate named capture groups.
RegExp v flag allows for the creation of regular expressions containing Unicode properties, including some multi-character Emoji sequences. It also allows for creating regular expressions with union, intersection, and subtraction set operations on character classes and collections of strings.
Duplicate named capture group enables the creation of regular expressions with named captures where more than one capture group uses the same name. This allows you to create regular expressions with intuitive group names where there is more than a one-way pattern to search. An example is creating one regular expression that can search data strings written in multiple ways, e.g. M/D/Y versus D-M-Y, while extracting the matched results with captured group names month, day, and year regardless of which string format was matched.
Set OperationsAnother new JavaScript feature adds seven Set
operation methods, including intersection()
and union()
, as well the comparison methods difference()
, isSubsetOf()
and isSuperSetOf()
. Together these new methods make Sets
powerful first class objects.
const setA = new Set(["apples", "oranges", "grapes"]);
const setB = new Set(["bananas", "grapes", "apples"]);
const union = setA.union(setB);
const intersect = setA.intersection(setB);
const diff = setA.difference(setB);
Also check out the new .symmetricDifference()
and .isDisjointFrom()
methods, which open up some interesting comparison possibilities.
WebKit for Safari 17.0 adds support for Gamepad.prototype.vibrationActuator.
It enables “dual-rumble” haptic feedback on gamepads. The API allows you to check if “dual-rumble” is supported by the gamepad, as well as control the duration and magnitude of the haptic effect.
const [gamepad] = navigator.getGamepads();
if (gamepad?.vibrationActuator?.canPlayEffectType("dual-rumble")) {
const options = {
duration: 1000, startDelay: 0, strongMagnitude: 0.5, weakMagnitude: 0.2, };
gamepad.vibrationActuator.playEffect("dual-rumble", options);
}
URL API
Traditionally, to ensure you could parse a URL, you needed to use a try
sequence. Now, you can directly detect if an URL input can be parsed with URL.canParse(tentativeURL, optionalBase)
. The method will return true
or false
.
In addition, the has()
and delete()
methods on URLSearchParams
have been extended. The has()
method makes it possible to detect if a parameter has been set. And the delete()
method can delete a parameter. Until now, you could only check for and delete by name alone. Now, the methods have been extended so that you can check for and delete specific name-value pairs.
For example, on an URL with duplicate key such as https://example.com/?currency=USD¤cy=JPY
, before you could only check params.has('currency').
Now, it’s possible to do params.has('currency', 'JPY')
.
Be mindful that with this update, method signatures are not directly feature detectable, so they can return false positives. Until all browsers support these updates, be sure to run a test to confirm support. For example:
function supportsUpdatedURLHasMethod() {
const param = new URLSearchParams({ key: "value" });
return param.has("key", "does not exist") === false;
}
function supportsUpdatedURLDeleteMethod() {
const param = new URLSearchParams({ key: "value" });
param.delete("key", "does not exist");
return param.has("key");
}
Web Sockets
You can now use relative URLs (as well as HTTP(S) URLs) in the WebSocket
constructor — this makes it a lot easier to point to WebSocket endpoints without hard-coding URLs into your web application. For example, new WebSocket('/updates')
.
<link rel="modulepreload">
.customElements.getName
method.Intl.Locale
getter method names to be prefixed with “get”.move()
method of FileSystemHandle starting to overwrite target by default.Safari 17.0 adds support for JPEG XL. The new image format provides another modern option for finding the right balance between visual quality and file size.
JPEG XL uses a new compression algorithm called “Modular Entropy Coding” that allows for greater flexibility in adjusting the compression ratio. Similar to JPEG, it has support for progressive loading, making it well-suited for images served over slow connections, since users start to see the image before the whole file is downloaded. And you can recompress existing JPEG files into JPEG XL without any loss of quality or data, while reducing their size by an average of 20%. Or compress from the original image file to create a file that’s up to 60% smaller compared to JPEG.
Use the <picture>
element to provide JPEG XL files to browsers that have support, while easily providing a fallback format to browsers that don’t.
<picture>
<source srcset="images/sophie.jxl" type="image/jxl">
<img src="images/sophie.jpg" alt="tiny brown puppy sleeping in the sun">
</picture>
JPEG XL is supported by WebKit for Safari 17.0, Safari View Controller and WKWebView on iOS 17, iPadOS 17, watchOS 10, macOS Sonoma, macOS Ventura and macOS Monterey.
HEICSafari 17.0 also adds support for HEIC images. A HEIC photo can take up about half the space of an equivalent-quality JPEG file.
HEIC is the image format used across Apple devices to store photos captured by the cameras, as well as in iCloud Photos. With support for HEIC in Safari, Safari View Controller, and WKWebView, you can now support importing and editing such photos right in the browser, without needing to convert them into another format. HEIC is also ideal for displaying images when using WKWebView inside an app.
Learn more about JPEG XL and HEIC by watching Explore media formats for the web at WWDC23.
AV1Safari 17.0 adds support for AV1 video on devices with hardware decoding support, like iPhone 15 Pro and iPhone 15 Pro Max.
The AV1 video codec adds another option for delivering video across the web, while finding the right balance between gorgeous quality and smaller file sizes. Hardware encoding/decoding provides an efficient way support the video codec without an undesired impact on battery life.
The progressively-enhanced nature of the web makes it easy to provide files in a variety of options, and let the user’s browser choose the one that’s best for them.
<video controls>
<source src='dogs-in-AV1.mp4'
type='video/mp4 codecs="av01.0.19M.10.0.110.09.16.09.0, mp4a.40.5" '>
<source src='dogs-in-HEVC.mp4'
type='video/mp4 codecs="hev1.2.4.L120.B0", mp4a.40.2" '>
<source src='dogs-in-VP9.webm'
type='video/webm codecs="vp9, vorbis" '>
</video>
In this example, the three options are compressed using AV1, HEVC (H.265), and VP9 video codecs, while being delivered in two video file formats: MP4 and WebM. That’s because compressed videos are delivered across the web inside a media container that has its own file format, like MPEG-4, WebM, Ogg, or QuickTime MOV. That container holds both the video stream, compressed in a particular codec, and the audio stream, compressed in another codec.
As a developer, you use the source
element to link to each file, list the type of file, and specify the codecs being offered — providing the browser with the information it needs to decide which file to start streaming. The type
attribute specifies the MIME type of the container, along with codec
information about how the video and audio are each compressed. The browser will use the first file that it fully supports.
The AV1 codecs parameter string can communicate not only that the video is compressed with AV1, but other characteristics of the video, including the color space and dynamic range. For example, you could use av01.0.19M.10.0.110.09.16.09.0
for a video compressed with AV1 Main Profile, level 6.2, Main tier, 10-bit HDR. That’s basically asking the browser “do you support AV1 with a 10-bits-per-color and HDR colorspace? If so, here’s a file for you.” You could instead use a simpler version, codecs="av01"
, to ask only “hey, do you support AV1?”
Watching streaming video is an amazing thing we all do with our devices. But to get the highest-possible quality of video, without downloading any unnecessary data and without killing the battery — it takes a complicated stack of technology working under the hood every time you hit the play button.
Adaptive bitrate streaming is a technique for switching between media data formats on the fly, to ensure delivery of the best-possible video quality based on the speed of the internet connection and capabilities of the device, even as those conditions change. For example, adaptive streaming can be configured to switch from 4k to HD resolution when the network slows, to prioritize playback-without-lag over higher-visual-quality.
For years, many websites have used Media Source Extensions (MSE) to handle adaptive bitrate streaming. It’s a low-level toolkit that gives the web page more control and more responsibility for managing buffering and resolution. But MSE isn’t particularly good at managing buffer levels, network access, and media variant selection. Plus, it uses a lot of power, which can be especially painful on mobile devices with smaller batteries.
Managed Media Source is a brand-new, power-efficient solution that fulfills advanced needs for streaming video. It supports the flexibility and capabilities of MSE, without any of the drawbacks.
WebKit for Safari 17.0 brings the new Managed Media Source API to iPad and Mac, with iPadOS 17, macOS Sonoma, macOS Ventura, and macOS Monterey. Managed Media Source is also available on iPhone with iOS 17.1 beta.
Note that support for Managed Media Source is only available when an AirPlay source alternative is present or remote playback is explicitly disabled.
const videoSource1 = document.createElement('source');
videoSource1. type = 'video/mp4' ;
videoSource1.src = URL.createObjectURL(mediasource);
video.appendChild(videoSource1) ;
const videoSource2 = document.createElement('source');
videoSource2. type = 'application/x-mpegURL' ;
videoSource2.src = "http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8";
video.appendChild(videoSource2);
Learn all about Managed Media Source API by watching Explore media formats for the web at WWDC23.
Media player stats overlayIf you’ve enabled Developer Features, Safari now provides a media player stats overlay where you can see technical details about a video — its source type, size, performance metrics, resolution, codec string, and color configuration. To show the overlay, use the context menu on any <video>
element and select “Show Media Stats”. Now you can tell at a glance the exact codec and configuration used by media on your page and use that information to help you write your code, including craft accurate queries in MediaCapabilities
.
Safari 17.0 on macOS Sonoma adds support for one or two channel Opus audio in WebM and MPEG-4 containers.
WebKit now supports USB cameras on iPadOS 17. When a USB camera is attached to an iPad, it’s included in the output of enumerateDevices and is selectable with getUserMedia along with the built-in cameras.
Improvements to WebRTC add support for InputDeviceInfo
, the inbound rtp trackIdentifier
stat field, exposing zoom
in MediaTrackCapabilities
, and getDisplayMedia
video track clone resizing.
WebKit for Safari 17.0 adds additional support for low-power mode and optimizing video streaming by tone mapping HDR video to SDR.
And Safari 17.0 adds support for WebCodecs temporal scalabilityMode
for software codecs, including parsing and error handling.
Safari 17.0 for macOS Sonoma is now available. And with it, web apps come to Mac.
You can add a website — any website — to your Dock. In Safari, go to File > Add to Dock, adjust the name and icon if desired, and the web app icon appears in your Dock.
Web apps on Mac let you focus on the websites you use all the time, separate from the rest of your browsing. Like all Mac apps, web apps work great with Stage Manager, Mission Control, and keyboard shortcuts like Command + Tab. Web apps can be opened from the Dock, Launchpad, and Spotlight Search. Web apps work with AutoFill credentials from iCloud Keychain and from third-party apps that have adopted the Credential Provider Extension API. And users can grant permission to a web app to use their camera, microphone and location in the same way they grant such permissions to other Mac apps through system prompts and the Privacy & Security section of System Settings. Web apps on Mac support web push, badging, service workers, web app manifests, and all the usual web standards implemented by WebKit, just like web apps on iOS and iPadOS.
When a user clicks on a web app icon, the website always opens in its own window as a web app, even if the site does not have a manifest file (or legacy meta
tags). This expands the usefulness of web apps, putting users in charge of determining what becomes a web app and giving them the confidence it’s always something they can choose.
While the default web app experience on Mac is great, as a web app developer you can use web technologies like Service Workers to make it even better. By providing a web app manifest, you can customize the presentation of your web app, including the display mode, name, theme color, and start URL. Learn about the details by watching What’s new in Web Apps at WWDC23.
When a user adds a website to their Dock, Safari will copy the website’s cookies to the web app. That way, if someone is logged into their account in Safari, they will remain logged in within the web app. This will only work if the authentication state is stored within cookies. Safari does not copy over any other kind of local storage. After a user adds a web app to the Dock, no other website data is shared, which is great for privacy.
Add to Home Screen from Safari View ControllerAdd to Home Screen is now available from Safari View Controller on iOS 17 and iPadOS 17. Tapping a link within an app that uses Safari View Controller as the in-app browser allows the user to add the open website to their Home Screen right from there. Just like Add to Home Screen from Safari on iOS and iPadOS (or any other browser that implemented support), if the website has a manifest file with a display
mode of standalone
or fullscreen
, it will open as a Home Screen web app.
Safari 17.0 brings significant changes to the experience of our web developer tools. Be sure to enable Developer Features to gain access to the Web Inspector, Develop Menu, Feature Flags, Responsive Design Mode, the ability to connect to iOS / iPadOS / visionOS Simulators, and much more.
Redesigned Develop MenuIn Safari 17.0 on macOS Sonoma, macOS Ventura and macOS Monterey, a completely redesigned Develop menu makes it easier to find the key tools available to help you create websites, web apps, web content inside other apps, web extensions, and more.
Devices and simulators are now more prominent in the Develop menu, making them easier to identify at a glance. Inside the menu for each iOS or iPadOS device, app icons make it easier to find the application or web content you want to inspect. On macOS Sonoma, you can pair with Apple TV and Vision Pro directly from Safari to inspect those platforms.
Rethought Feature FlagsThe new Feature Flags panel replaces the previous Experimental Features section of the Develop menu, allowing you to search for specific features and to easily see bolded features toggled from their default state. Feature flags are now organized by topic: Animation, CSS, HTML, JavaScript, Media and more. And each feature is clearly categorized into one of four statuses: Stable, Testable, Preview, and Developer.
Stable represents features that have recently shipped in Safari, on by default. These features can be turned off to help you debug an issue or test progressive enhancements. Stable features will eventually be removed from the list.
Testable features are disabled by default. These features might be in the process of being implemented, or they might be waiting for changes to the web standards. They have a ways to go, but still could be interesting enough to test out.
Preview is for features that have not yet shipped in Safari, but are closer to being complete. These features are on by default in Safari Technology Preview, and are ready for developers to try out. They may still have bugs, or may even undergo significant change as their web standards evolve. This is a great time to help find bugs and file issues, and to comment on whether the web standard for a new technologies solves your needs.
Developer features are not as common. This category is for miscellaneous features added to the list of feature flags so developers can toggle them on and off for testing. New developer tools may appear here, for example.
New Developer settings panelThe new Developer panel in Safari 17’s Settings let you toggle developer features that apply across all websites open in Safari, like Allow remote automation (which enables automating Safari with WebDriver) and other features that were previously in the Develop menu.
New tab-specific setting overlaySome previously-global settings from the Develop menu, like disabling JavaScript or changing WebRTC behavior, have moved to Web Inspector where they are now scoped to the inspected tab, allowing you to use other tabs and windows normally.
Redesigned Responsive Web Design ModeResponsive Design Mode has also been refreshed to focus on the responsiveness of a page’s design at any width or height on your Mac. You can type in a specific viewport size at the top of Responsive Design Mode in addition to dragging the resize handles around the view.
Also new is the ability to open the page in a Simulator right from Responsive Design Mode.
SimulatorsYou can also open any page from Safari in a Simulator directly from the Develop > Open Page With menu, even when you are not using Responsive Design Mode.
Using a Simulator is a great way to test the experiences you’re making on iOS, iPadOS, and visionOS — including device-specific behaviors, like the rendered size of type, the effects of the viewport
meta tag, double-tap to zoom, and even Home Screen web apps on iOS and iPadOS. Simulators are free, and come included with Xcode from the Mac App Store.
If you don’t have Xcode installed, a link to documentation is conveniently available in the Develop > Open Page With menu to help you get started, or to add more devices and OS versions.
Learn all about the new Develop menu, redesigned Responsive Web Design mode, how to easily connect to directly to a real device, how to install and use a Simulator, and much more in Rediscover Safari developer features at WWDC23.
Web InspectorWe’ve also made improvements to Web Inspector. When working with minified sources, pretty printing in Web Inspector can help make the code easier to read, set breakpoints in, and debug. New in Safari 17.0, more JavaScript syntax is supported for pretty printing minified scripts, including template strings, optional chaining, private variables and functions in classes, and static variables and functions.
Changes to Web Inspector in Safari 17.0 also include:
WeakRef
.Learn more by watching What’s new in Web Inspector at WWDC23.
Security GPU ProcessLast year brought GPU process support to WebKit on iOS, iPadOS and watchOS. This year we’re adding support on macOS Sonoma. The change moves all drawing (including the drawing of page content, 2D Canvas and WebGL rendering) so it occurs in the “GPU Process”. This new architecture allows WebKit to isolate powerful graphics hardware and driver access away from the WebContent process, which is the process that interacts with untrusted content from the internet. The new design also allows the WebContent process sandbox to completely block IOKit access, resulting in improved security.
WebKit APINew interfaces are added to WKWebsiteDataStore
and related classes to further unlock potential of your WebKit apps. The new capabilities include creating persistent website data stores, configuring cookie policy, customizing proxy settings, requesting HTTPS upgrade for all navigations, and controlling state of inline prediction for autocomplete.
Safari 17.0 adds support for profiles. History, favorites, Tab Groups and website data such as cookies, caches, service workers, and Web Push subscriptions are scoped per-profile. Users can manage each profile’s data individually.
Safari Private BrowsingIn Safari 17.0, Private Browsing gets even more private with added protection against some of the most advanced techniques used to track you. Technical changes include:
iOS 17, iPadOS 17, and macOS Sonoma feature a redesigned experience of editing text, with even more accurate autocorrect and predictions inline as you type. In Safari 17.0 on macOS Sonoma, the redesigned text cursor now uses the system accent color, just like iOS. CJK marked text also has a new appearance and matches the system accent color.
Safari 17.0 also improves the interoperability of the Range API and Selection API. And it adds Live Text support for vertical text recognition in images and videos.
Apple Pay via Payment Request APIYou can now enable Apple Pay to be used in third-party iframes by setting the allow="payment"
attribute. This “permissions policy” enables the Payment Request API on an iframe, allowing you to embed third-party payment handlers. If using this feature, be sure you also use the X-Frames-Options HTTP header to prevent your site from being embedded by malicious websites.
Safari 17.0 adds support for largeBlob
extension for passkeys. Websites can use the additional storage to save data that can later be retrieved when signing in with a passkey. These saved blobs are synced and shared along with passkeys.
We also are adding support for enterprise
WebAuthn attestation for passkeys in iCloud Keychain. Managed devices can provide an attestation statement when creating passkeys, using a certificate provisioned through MDM.
Safari 17.0 adds support for HTTP Early Hints and preconnect
.
Lockdown mode now:
<embed>
element.Lockdown Mode is also now supported in WebKit on watchOS.
Safari ExtensionsSafari 17.0 now lets you customize where extensions run with even more granularity.
First, Safari App Extensions now have the same per-site permissions model as Safari Web Extensions. It puts users in control over the browsing data they share with every extension they use in Safari.
Second, as an additional layer of control, Safari Extensions can be turned off in Private Browsing. Extensions that access browsing data, like browsing history or webpage contents, will be off by default in Private Browsing but can be allowed with a single toggle in Safari Settings.
Third, all Safari Extensions can be turned on or off per Safari Profile. You can imagine this being useful for turning on an extension used only for school or work in a relevant profile, but keeping it off everywhere else. Each profile runs a separate instance of the extension — meaning there are unique storage areas, background pages, service workers, and more. However, per-site permissions are shared across profiles, so an extension only needs to be granted once. If your extension leverages native messaging capabilities to communicate with a host app, it’s possible to distinguish between profiles to ensure your extension behaves correctly across profiles.
Learn more by watching What’s new in Safari extensions at WWDC23.
Bug Fixes and moreIn addition to the over 65 new features, WebKit for Safari 17.0 includes an incredible amount work polishing existing features.
Accessibilityaria-owns
attribute for the radio
role. (23630121)<label>
elements. (24033482)role=list
. (55145117)aria-activedescendant
to set the active cell within a grid. (84439987)input
in Web Inspector. (103907008)input[type=date]
individual fields getting announced as “group”. (104928713)popovertarget
attribute to expose expanded state to assistive technologies. (105425310)aria-errormessage
to not be exposed when aria-invalid
is false
. (105813974)aria-labelledby
. (107570512)aria-describedby
to be equivalent to aria-description
and override it when both are present. (108386295)<dialog>
or aria-modal
. (108704582)required
attribute over aria-required
when both are present. (111370591)createImageBitmap
using ImageData
to respect the premultiply flag. (89382358)@imports
in HTML missing quote marks getting mistakenly hidden from the Preload Scanner. (46031271)@supports selector()
fails for all -webkit-
prefixed pseudo elements. (95683424)background-size
to not accept unitless lengths. (97039770)text-shadow
and box-shadow
with currentcolor
. (102542182)color()
function incorrectly parsing missing components. (104679823)text-emphasis
marks to not be rendered if there is no emphasized character. (104688963)image-set
compatibility. (105097744)mask
and background
shorthands to not serialize as “initial”. (105114588):has()
to support invalidation of :buffering
and :stalled
pseudo-classes. (105163364)cssText
to follow CSS OM specifications. (105235157)font-feature-settings
and font-variation-settings
to sort their tags alphabetically. (105483635)transition-property: all
to include custom properties. (105556538)#x
, such as 1x
, to be recognized a resolution calc unit category. (105700660)@font-face
. (106635029)image-set
to accept zero resolution and clamp negative resolutions used in calc expressions. (107167273)@supports
rule. (107397723)cursor: pointer
on unclickable <area>
. (107591470)CSSStyleValue.parse
to accept properties from the document-derived context. (108249093):dir()
pseudo-class after removing the :dir
content attribute from the document element. (108480507)type()
function for image-set()
to only take one string. (108909363):has()
to support invalidation of the :defined
pseudo-class. (109896689)cjk-earthly-branch
and cjk-heavenly-stem
counter styles to have fixed
system. (110796633)<ray-size>
to be optional in ray()
for CSS Motion Path. (110818689)text-overflow: ellipsis
so it works with overflow: clip
. (111182654)cjk-earthly-branch
and cjk-heavenly-stem
counter styles to fallback to cjk-decimal
. (111208503)inline-flex
and inline-grid boxes
to stop propagating underlines to align with other browsers. (111228920)@font-face { src: format() }
to parse valid unsupported keywords. (112135869)-webkit-box-decoration-break: clone
with left and right padding causes unexpected wrapping of inline content. (112197978)xmlns
attributes first and use lowercase “ns” when generating prefixes. (103234827)getRangeAt
and throw errors as specified. (69015762)<br>
when the root editable element is phrasing content. (105438898)input.validity
reporting valid: true
for partially completed dates and times. (102984901)AbortController.abort()
. (104485543)<input pattern>
to use the regular expression v
flag rather than u
. (105268069)<input type="search">
using the name
attribute. (105369635)maxlength
attribute treating emoji of string length 11 as length 1. (105926915)HTMLOptionsCollection.length
setter to use a limit of 100,000. (105988871)<select>
to single. (106264081)<summary>
element with a tabindex
. (106550778)overflow: hidden
rendering too many columns. (109343502)sizes
attribute. (107509739)vary
header behavior for opaque responses. (107769146)Object.entries()
by 1.5×. (100783096)/p{Number}--]/v;
to be a syntax error. (109400589)String#charAt
to support out-of-bounds handling in DFG. (111421698)top
CSS added to audio controls when the height of an <audio>
element is adjusted on iOS. (99548840)SourceBuffer.timestampOffset
behavior with WebM content. (105801920)bufferedchange
event to fire whenever an eviction occurs. (106168510)playing
event to fire earlier. (107041118)border-image-repeat: round
. (28213711)text-overflow: ellipsis
incorrectly truncating text in right-to-left mode. (29464657)label
attribute for the <option>
element on iOS. (53989128)background-clip: text
and transform: rotate(…)
. (54325642)overflow: hidden
and text-overflow: ellipsis
are set. (94330690)translate
property animation. (102064448)block
to inline-block
. (103637239)<details>
marker maintain the same margin in right-to-left as in left-to-right. (104275835)preserve-3d
to apply to pseudo-element children. (105474987)clear
. (105775276)<body>
to root propagation when content: paint
is set on the <body>
or the root. (105850374)margin-trim: block-end
. (106524654)calc()
values on <colgroup>
elements. (106692191)flex-item
inside inline-flex
with column flex-direction
. (107029563)display: inline
content when text-align
is not start
. (107271178)display: inline
content when text-indent
is present. (107280354)display: inline
content when a float is present. (107294351)text-align
. (107321638)transform-style: preserve-3d
preventing links when :after
has a negative z-index
. (107671388)display: flex
on content change. (107694159)line-height
to not affect the enclosing height. (107832246)contenteditable
. (107996603)-webkit-line-clamp
overlapping blocks even with overflow: hidden
, when mixing <span>
and <div>
. (108116069)letter-spacing
breaking -webkit-box-decoration-break: clone
. (108701795)decoding="async"
flickering while zooming in. (108930635)line-height: 0
. (108988226)alt
text rendering horizontally in vertical writing mode. (109004347)align="abscenter"
to vertical-align: middle
(109081191)overflow: clip
when an intrusive float is present. (109293228)overflow: auto
. (109384976)bordercolor
attribute on table elements to not create a visible border. (109436009)CanvasRenderingContext2D.putImageData
until a forced re-render. (112901862)func
parameter is used. (100034937)scripting.executeScript
return types. (107044691)textLength
behavior. (32066826)overflow="visible"
having no effect on the dimension of a <use>
element unless its dimensions are specified. (98577733)<marker orient="-1">
to orient correctly. (109312083)animateMotion
to accumulate properly with rotate: auto
or rotate: auto-reverse
. (109489241)display
property for SVG elements. (109928375)begin-value-list
doesn’t have a matching value in end-value-list
. (109935392)textLength
whitespace and chunk handling for <tspan>
elements. (109981392)<text>
element. (110119702)feMorphology
. (110504653)table-layout: fixed
not getting applied when the width is max-content
. (105627723)transition-property: all
to distinguish matching any CSS property or Animation object. (87785199)bolder
or lighter
is used on a font-weight
property. (105098349)inherit
. (105099874)all
value for the transition-property
to parse as a keyword, not a CSS property. (105556116)CSSKeyFramesRule.length
. (105565920)mousemove
event when a modifier key is pressed. (81287778)<body>
to not be included in document.body.innerHTML
. (95557786)screen.colorDepth
reporting the incorrect value on iOS. (99871925)as
property in <link rel="preload">
. (100161255)fetch()
. (101171705)scrollWidth
and scrollHeight
to include padding and any whitespace added by decorations. (104332108)focus()
method with delegatesFocus
in Shadow DOM. (104927020)GamepadHapticActuator.playEffect()
. (105175808)Gamepad.vibrationActuator.type
to be dual-rumble
. (105175859)location.href
to throw a SyntaxError on a URL parser failure. (105631453)postMessage
for cross-origin iframes. (106439413)Worklet.prototype.constructor
. (106533500)innertHTML
serialization to not have special handling for javascript:
URLs. (107362610)<
, >
, &
, and non-breaking space characters inside <noembed>
, <noframes>
, and <plaintext>
elements when scripting is enabled. (107381507)contentScriptType
, contentStyleType
, and externalResourcesRequired
attributes, and the XML xml:base
attribute. (107428878)document.applets
to no longer return any elements. (107926196)data:
URLs to behave the same everywhere. (107982669)movementX
and movementY
in pointermove
events. (108112600)visibilitychange
. (108279602)<frameset>
inside <template>
to be ignored. (109081113)binaryType
setter to not throw. (109192086)DeviceMotionEvent
and DeviceOrientationEvent
on the global Window
object on macOS. (109580299)dir
attribute of documentElement
not updating a child element matching the :dir
pseudo-class. (109976294)window.stop()
to fire abort events on XMLHttpRequest asynchronously. (110086856)<select>
with multiple enabled not consistently firing the onchange
event. (110274850):nth-child
and :nth-last-child
. (110451692)XMLHttpRequest.responseXML.characterSet
. (110863647)mousemove
events to one per rendering. (110921187)HTMLTableSectionElement.insertRow(0)
and HTMLTableRowElement.insertCell(0)
. (111791597)<command>
as if it has no end tag. (107416609)<layer>
and <nolayer>
from the HTML parser. (107554605)NotificationOptions.silent
. (107424158)activate
event. (109411104)postMessage
. (109561888)controllerchange
event when a service worker gets deleted. (109567316)margin-trim
. (103374677)color-mix
CSS in the Styles sidebar of the Elements tab. (105732322)new URL("/")
to be more explicit. (109253920)groupIds
. (109355290)We love hearing from you. Send a reply on X to @webkit to share your thoughts on Safari 17.0. You can find us on Mastodon at @jensimmons@front-end.social and @jondavis@mastodon.social. If you run into any issues, we welcome your feedback on Safari UI, or your WebKit bug report about web technologies or Web Inspector. Filing issues really does make a difference.
Download the latest Safari Technology Preview to stay at the forefront of the web platform and to use the latest Web Inspector features. You can also read the Safari 17.0 release notes.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.3