WebKit Features for Safari 26.5

Safari 26.5 is here, delivering the :open pseudo-class, the element-scoped keyword for random(), color-interpolation for SVG gradients, the ToggleEvent.source property for popovers, and the Origin API.

Alongside new features, this release continues our ongoing efforts to greatly improve the quality of WebKit. There are 63 bug fixes in total — making this the biggest May release of WebKit yet. The improvements span SVG, WebRTC, networking, editing, and more. Scroll-driven animations and Anchor Positioning both get multiple fixes. Rendering at different zoom levels works better. And work continues improving the handling layout whenever a block-level element lives inside an inline element.

CSS

The :open pseudo-class

The new :open pseudo-class in CSS provides a clean way to style the open state of elements like <details>, <dialog>, <select>, and <input>.

Previously, you might have used the [open] attribute selector for <details> and <dialog>. It works on those elements, but doesn’t work on <select> or <input>. Plus, it’s an attribute selector doing the job better handled by a pseudo-class. Now :open provides a single, consistent pattern that works across all of these element types.

For <dialog>, it now matches when the dialog is showing — whether opened with showModal() or show(). And for <input>, it applies when an associated picker is displayed, like a date or color picker.

For <select>, :open matches when the drop-down is expanded.

select:open {
  border: 1px solid skyblue;
}

This is a practical improvement to everyday CSS. The progressive enhancement is straightforward — browsers that don’t yet support :open simply won’t apply those rules, and the underlying elements still function normally.

Improvements to CSS random()

We were proud to be the first browser to ship the new CSS random() function last December, in Safari 26.2. Since then, the CSS Working Group adjusted how named random values work. Using a named value in the syntax, like random(--size, 100px, 200px), now creates a global result, instead of something scoped to each individual element. Safari 26.5 implements these changes, including a new element-scoped keyword for when you need per-element behavior.

For example, imagine you have eight instances of <div class="box"> and apply the following CSS.

.box {
  width: random(100px, 200px); 
  height: random(100px, 200px);
  border: 2px solid black;
}

You get eight completely differently sized rectangles. This is because each time the random function is used, it generates a brand new number, in this case between 100px and 200px. This is how random() has worked since Safari 26.2.

If, instead, you want all eight boxes to be the same size with the same randomly generated height and width, you can write:

.box {
  width: random(--w, 100px, 200px); 
  height: random(--h, 100px, 200px);
}

This chooses a random number, names it (as --w or separately --h), and reuses the named number on each box. (Before Safari 26.5, a cache name was scoped to the individual element, each single box. Now it is global.)

If you want all eight boxes to be square, you can use:

.box {
  width: random(--s, 100px, 200px); 
  height: random(--s, 100px, 200px);
}

The --s ties the two sizes together. The height and width is random, but it’s the same number. Before Safari 26.5, this would give you eight differently-sized squares. Now it will give you a single random size for all eight squares.

If you want eight differently sized squares, you can now use the element-scoped keyword to scope the name to the element, like this:

.box {
  width: random(--s element-scoped, 100px, 200px); 
  height: random(--s element-scoped, 100px, 200px);
}

Now the name applies only to a single element. You can put element-scoped before or after the name, meaning this works too: random(element-scoped --s, 100px, 200px). Lastly, the element-shared keyword has been removed from Safari 26.5, since the new default behavior covers this use case and the CSS Working Group removed it from the specification.

Improvements to Anchor Positioning

CSS anchor positioning continues to mature in this release, with several fixes addressing real-world usage patterns.

  • Fixed an issue where media queries failed to re-evaluate during viewport resizing when CSS anchor positioning and viewport units were both in use. (172864699)
  • Fixed an issue where chains of three or more anchor-positioned elements didn’t resolve correctly. (173357622)
  • Fixed an issue where anchor() fallback values did not accept unitless zero. (173554237)
  • Fixed an issue where an element with display: contents did not establish an anchor scope when using anchor-scope. (173718365)
  • Fixed an issue where fixed-position boxes anchored to children of sticky-positioned boxes did not stick correctly. (173722628)

Improvements to Hanging Punctuation

This release includes two fixes for hanging-punctuation.

  • Fixed hanging-punctuation to correctly treat U+0027 (apostrophe) and U+0022 (quotation mark) as hangable quote characters. (172668971)
  • Fixed an issue where ideographic space did not hang when using hanging-punctuation: first. (172669250)

Improvements to Scroll-Driven Animations

Scroll-driven animations are a powerful recent addition to CSS, and this release includes four fixes that improve their reliability.

  • Fixed support for the scroll animation timeline range name in scroll-driven animations. (171630023)
  • Fixed an issue where scroll-driven animations were not properly paused when animation-play-state was dynamically set to paused. (171630127)
  • Fixed an issue where view timeline animations near the 0% and 100% thresholds reported incorrect progress values. (171630157)
  • Fixed an issue where animation timelines could fail to restore correctly after navigating back to a page from the back-forward cache. (174561577)

Improvements to Block-in-Inline Layout

Work continues on the layout engine rewrite for block-in-inline contexts, with several fixes in this release.

  • Fixed an issue where content inside inline elements with block-level children and rendering layers was not displayed correctly. (171101386)
  • Fixed an issue where getClientRects() could return rects with zero width and height for spans in multi-column layouts. (171101490)
  • Fixed an issue where an empty <span> with decoration was incorrectly positioned when a sibling block margin was present inside a block-in-inline context. (171101555)
  • Fixed an issue where a <br> element was incorrectly positioned inside a block-in-inline context when a block margin was present. (171101748)
  • Fixed a layout regression where absolutely positioned elements inside block-in-inline containers were incorrectly overlapping adjacent content. (171732203)

Improvements to Grid, Flexbox, Tables, Multicolumn

  • Fixed an issue where a display: grid subgrid inside a grid-lanes container incorrectly contributed its items’ intrinsic sizes to the parent’s track sizing algorithm. (171230544)
  • Fixed an issue in collapsed border tables where the border style of a cell adjacent to a rowspan cell was incorrectly applied across the full length of the spanning cell’s border. (171634786)
  • Fixed an issue where images could appear stretched inside certain flex and grid layout configurations. (172224411)
  • Fixed a regression where content with column-count: 1 could fail to display text. (172306151)

Improvements to zoom

This release includes a focused quality pass on rendering behavior at different zoom levels.

  • Fixed an issue where grid and flex layout could cause elements to shift position at certain zoom levels. (172118478)
  • Fixed an issue where text content could get cut off inside overflow containers when the page was zoomed in. (172118721)
  • Fixed an issue where pinch-to-zoom could cause web content to jump or disappear on some websites. (172507916)
  • Fixed an issue where lh and rlh units resolved with double-zoom when line-height is a number. (173515568)
  • Fixed an issue where the rlh unit was double-zoomed when resolving with evaluation-time zoom for unzoomed properties. (173518838)
  • Fixed an issue where aspect-ratio was not honored correctly when the page was zoomed in. (174498486)

Even more improvements to CSS

  • Fixed an issue where @font-face rules with different styles could incorrectly fall back to glyphs from other faces in the same family, rather than proceeding to the next family as specified by the font matching algorithm. (172390840)
  • Fixed an issue where images inside transformed containers were not properly centered. (172475726)
  • Fixed an issue where user-installed font variants could interfere with system font matching, causing incorrect fonts to be selected. (173345107)
  • Fixed a regression where animating to an implicit value for individual transform properties failed to animate. (173717819)
  • Fixed an issue where :has(:empty) was not invalidated when the content of a child element changed from empty to non-empty. (174501418)

SVG

WebKit for Safari 26.5 adds support for the color-interpolation attribute on SVG gradients, enabling linearRGB color space interpolation.

<linearGradient color-interpolation="linearRGB">
  <stop offset="0%" stop-color="red" />
  <stop offset="100%" stop-color="blue" />
</linearGradient>

By default, SVG gradients interpolate colors in the sRGB color space. Setting color-interpolation="linearRGB" on a gradient element now produces more perceptually even color transitions, especially noticeable in gradients between saturated colors, where sRGB interpolation can produce a darker or muddier midpoint than expected.

Improvements to SVG

The work continues making significant improvements to SVG.

  • Fixed an issue where removeAttribute for width or height on an SVG root element did not reset to the initial default values. (172132798)
  • Fixed event name mapping for onbegin, onend, and onrepeat on SVGAnimationElement and added the missing onend event handler. (172581017)
  • Fixed an issue where an SVG <image> element was not repainted when its href attribute was removed. (172875166)
  • Fixed an issue where UI events such as wheel failed to fire for inner SVG elements. (173009454)
  • Fixed an issue where SVG cursors set via cursor: url() appeared blurry on high DPI displays. (173950927)

Web API

ToggleEvent.source

Safari 26.5 adds support for the source property on ToggleEvent. Now, when a popover or other toggleable element is toggled, the event includes a reference to the element that triggered the action, such as the invoker button that opened a popover. This makes it straightforward to coordinate behavior between a trigger and its target without manually tracking that relationship in your own code.

popover.addEventListener("toggle", (e) => {                                                                           
  if (e.newState === "open") {                                                                                        
    console.log("Opened by:", e.source);                                                                              
  }                                                                                                                   
}); 

Origin API

Safari 26.5 also adds support for the Origin API, which exposes origin information as a structured Origin object rather than requiring string parsing. This also enables you to perform same-site comparisons between origins without having to pull in the Public Suffix List. Origin.from(value) allows you to construct an Origin object from a string or built-in object, such as MessageEvent. When the origins from built-in objects are opaque, you can still compare them. This wasn’t possible before as you only had access to the serialized origin, which is “null” for opaque origins.

const messageOrigin = Origin.from(messageEvent);
const localOrigin = Origin.from("https://social.example");
if (messageOrigin.isSameSite(localOrigin))
    grantAccess();

Improvements to Web API

  • Fixed an issue where DecompressionStream discarded valid decompressed output when extra trailing bytes were present after the compressed stream, instead of enqueuing the output before throwing. (171020155)
  • Fixed an issue where calling preventDefault() on pointerdown events did not prevent page scrolling when only passive touch event listeners are installed. (173988278)

Additional Resolved Issues

In addition to all the fixes described above, WebKit for Safari 26.5 also includes the following improvements:

Accessibility

  • Fixed an issue where the accessibility tree could permanently be empty if built during early page load when only a scroll area and web area were present. (174244620)

Editing

  • Fixed an issue where pressing backspace on a line below an image in a contenteditable region could place the cursor in the wrong position. (171850465)
  • Fixed an issue where emoji images copied from websites and pasted into other sites appeared broken due to cross-origin resource policy blocking the SVG image sources. (172775070)
  • Fixed an issue where pasting text into an empty list item created an extra blank bullet. (173275372)

Forms

  • Fixed an issue where a readonly date <input> could still be edited via keyboard using the date picker. (171535893)
  • Fixed an issue on iOS and iPadOS where datalist suggestions were presented directly over the associated input, obscuring it. (174264299)

HTML

  • Fixed dragenter and dragleave events to include relatedTarget in the event object. (172048448)
  • Fixed an issue on iOS where the drag thumbnail could show an incorrect image after long-pressing an image with an embedded link. (172293971)

Images

  • Fixed a regression where images with srcset and sizes attributes containing calc() expressions with division by zero were not displayed. (173954748)

JavaScript

  • Fixed TypedArray.prototype.sort() failing when the comparison function accesses the .buffer property of the typed array. (172516044)

Media

  • Fixed an issue where the media controls volume button was mispositioned and overlapped with other controls in right-to-left locales. (171182590)
  • Fixed an issue where MediaCapabilities.decodingInfo() always returned false for spatialRendering. (172689752)

Networking

  • Fixed an issue where downloaded files used the file extension from the URL path instead of the HTTP Content-Type header. (173705083)
  • Fixed an issue where downloaded files were saved with incorrect or missing file extensions when the URL path extension did not match the HTTP Content-Type header. (173945210)

Scrolling

  • Fixed an issue where scroll-snap re-snapping after layout changes could cause incorrect scroll positions, resulting in the wrong content being shown. (171541221)

Storage

  • Fixed an issue where IndexedDB connections could become permanently broken until the page was reloaded. (172247569)
  • Fixed an issue where document.hasStorageAccess() could return a Promise that never resolves. (172424614)

Web Extensions

  • Fixed an issue where extensions with a trailing comma in manifest.json failed to load in Safari. (172120877)

WebGL

  • Fixed WebGL shader compilation to properly handle NaN and infinity values. (166699074)

WebRTC

  • Fixed RTCIceCandidate.toJSON() to include the usernameFragment property in its serialized output. (172689343)
  • Fixed RTCRtpSender to allow a maxFramerate value of 0. (172689374)
  • Fixed RTCRtpSynchronizationSource.timestamp to use the correct time base. (172689387)
  • Fixed an issue where remote audio and video track IDs were incorrectly derived from SDP. (172689452)
  • Fixed RTCRtpTransceiver.setCodecPreferences() to accept codecs with case-insensitive mimeType matching. (172689477)
  • Fixed an issue where the camera did not turn on automatically in Google Meet when media permissions were set to “Allow”. (174023905)

Updating to Safari 26.5

Safari 26.5 is available on iOS 26.5, iPadOS 26.5, visionOS 26.5, macOS Tahoe 26.5, plus macOS Sequoia, and macOS Sonoma. On iOS, iPadOS, and visionOS, you can update to Safari 26.5 as part of the OS update in Settings > General > Software Update. On macOS, Safari updates are delivered through System Settings > General > Software Update.

Feedback

We love hearing from you. To share your thoughts, find us online: Jen Simmons on Bluesky / Mastodon, Saron Yitbarek on BlueSky / Mastodon, and Jon Davis on Bluesky / Mastodon. You can follow WebKit on LinkedIn.

If you run into any issues, we welcome your bug report. Filing issues really does make a difference.

You can also find this information in the Safari release notes.