Contents
- Customizable Select
- Animations
- CSS
- Scroll Anchoring
- HTML
- JavaScript
- WebAssembly
- MathML
- Spatial Web
- WebGPU
- Media
- Web API
- Rendering
- WebRTC
- Web Extensions
- Networking
- Storage
- Editing
- SVG
- WKWebView
- Web Inspector
- Accessibility
- Forms
- Printing
- Updating to Safari 27
- Feedback
Safari 27 beta is here. Don’t miss our WWDC26 sessions on web technology, including What’s new in WebKit for Safari 27, to go deeper on our work in this release. Now, let’s dig into this beta, packed with 58 new features, 525 fixes and 4 deprecations that will hopefully make your work as a web developer a little easier.
Here’s a sneak peek of the highlights:
- After years of anticipation, you can now use customizable
<select>to style your form elements to match the rest of your site or app without rebuilding it in JavaScript or sacrificing accessibility. - Scroll anchoring prevents those visual jumps when content loads above the viewport.
- WebAssembly JavaScript Promise Integration (JSPI) lets Wasm code participate in the async world of JavaScript.
- Transform-aware anchor positioning closes out a major gap in the anchor positioning story.
- The
:headingpseudo-class, therevert-rulekeyword, and thestretchkeyword for box sizing all land in CSS. - Subpixel inline layout makes text rendering more precise.
And that’s just the start.
If you look through the lists of features and fixes in Safari 27, you’ll notice that, although there are 58 brand-new features and 525 fixes — the largest pile of fixes in any Safari release in recent memory — most of what is released is not about new things.
Most of this work has been about existing features behaving more correctly, handling more edge cases, and fitting together with other features the way you’d expect. We committed our time to increasing quality — that’s the story of this release and the year that led to it.
A lot of this work was also about aligning to web standards. When we found a spec that was unclear or incomplete, we helped update it, and then updated WebKit to match.
For example, Safari 27 contains 30 SVG fixes, including updates based on recent decisions in SVG 2 where we revived the Working Group. SVG is used on 67% of webpages, making this work very impactful. Anchor positioning continues to get refined as the CSS specification settles. And in more subtle places throughout the release — URL parsing details, event listener options, timezone identifier handling, innerText edge cases — features that look unchanged on the surface now behave the same way in Safari as they do in Chrome, Firefox, and Edge.
We also spent time making sure features still work across different contexts. A :has() selector invalidating properly when siblings change. An aspect-ratio resolving correctly against a percentage height. box-shadow rendering correctly on table-row elements. background-clip: text working on table header elements. Bugs that appear when combining features are among the hardest to find and the most frustrating, but we’ve made significant progress in hunting them down.
If something has been bothering you, test it in Safari 27 beta. You might be pleasantly surprised. And if it hasn’t been fixed yet, file a bug report, or add a comment to an existing issue with a concrete scenario, a link to a real site, or a reduced test case. The more concrete the problem, the more helpful it is.
This work goes beyond the Safari browser. When your customers open their news app, their banking app, their shopping app, there’s a good chance the interface they interact with is powered by the HTML, CSS, and JavaScript that’s rendered by WebKit and JavaScriptCore — the same engines inside Safari. Every fix in this release isn’t just for the browser — it benefits everything the web platform touches.
Let’s dive in.
Customizable Select
Safari 27 beta adds support for customizable <select> , which transforms the <select> element. You can now build a fully custom form element that matches the look and feel of your website or web app, without reaching for a JavaScript library or sacrificing the accessibility, reliability, and native platform integration of a real HTML form control.
Use the new appearance: base-select to clear the native styling and start with a clean palette. Then insert any additional CSS you want to create your custom design. Customizable <select> comes with new pseudo-elements for more granular control, like ::picker-icon to target the disclosure indicator and ::checkmark to target the checkmark that appears next to the selected <option>. Both can be fully customized.
Use the new <selectedcontent> element inside the button to display the currently selected option’s content and style <selectedcontent> directly to get it to look exactly how you want in the closed state.
And because you’re still working with a real <select>, everything that comes with a native form control still works: keyboard navigation, screen reader support, form submission, validation, change events. You get the styling freedom of a custom widget with the power of a native HTML element.
Customizable <select> is a multi-vendor effort. The same syntax is coming to other browsers. Use progressive enhancement and style your <select> with appearance: base-select for a great experience in browsers that support it, and let browsers that don’t fall back to their built-in rendering.
Learn more in the WWDC26 session Rediscover the HTML Select Element, where Tim walks through the full API and how to build layouts inside options with Grid and Flexbox.
Additional bug fixes:
- Fixed an issue where
<select multiple>did not always fireonchangewhen the mouse button was released far outside the element. (173882861) - Fixed an issue where
<select>control rendering was broken in vertical writing mode. (174068353) - Fixed a performance issue where parsing
<select>elements with thousands of<option>children viainnerHTMLcaused O(n²) overhead due to repeated list recalculation. (174244946) - Fixed
<option>elements to correctly implement the HTML specification’s dirtiness concept for tracking user-modifiedselectedstate. (175306111) - Fixed the select picker appearing at an incorrect position when the
<select>element is anchor positioned. (175454476) - Fixed the default
displayvalue for<optgroup>and<option>elements toblock, matching the behavior of other browsers. (175473184) - Fixed
<option>and<optgroup>elements to match the:disabledpseudo-class when inside a disabled<select>. (176559708)
Animations
Safari 27 beta adds the animation property to the AnimationEvent and TransitionEvent interfaces, letting event handlers directly access the Animation object associated with the event.
Additional bug fixes:
- Fixed an issue where
animation-fill-modedid not correctly apply viewport-based units after the viewport was resized. (80075191) - Fixed an issue where
!importantdeclarations did not override CSS animation values when CSS transitions were also running on the same property. (174367827) - Fixed an issue where identity matrix decomposition generated invalid quaternions, resulting in incorrect transform animations. (174813328)
CSS
Transform-aware anchor positioning
Safari 27 beta adds support for transform-aware anchor positioning. Now, when an anchor element has a CSS transform applied — scale, rotate, translate, or any combination — elements positioned relative to that anchor follow its transformed position instead of its pre-transform layout position. This works for transforms applied via the transform property as well as through the individual translate, rotate, and scale properties.
This closes a long-standing gap in the anchor positioning story. If you use anchor positioning to attach a tooltip, popover, or annotation to a transformed element, it now tracks correctly, even with animated transforms.
:heading pseudo-class
Safari 27 beta adds support for the :heading pseudo-class, which matches any heading element — <h1> through <h6>.
Instead of writing h1, h2, h3, h4, h5, h6 in your selector list, you can just write :heading. And :heading can also be combined with functional selectors to target headings at specific levels:
revert-rule keyword
The revert-rule keyword is now supported in Safari 27 beta. Like revert and revert-layer, revert-rule rolls back the cascade — but specifically to the state as if the current style rule had not been present.
It gives you a more precise tool for working with overrides, especially in component libraries and design systems where you want to selectively undo declarations within a rule without losing the rest.
stretch keyword for box sizing
Safari 27 beta adds support for the stretch keyword in box sizing properties like width, height, min-width, and so on. stretch tells an element to fill the available space in the relevant axis, accounting for margins.
.card {
width: stretch;
}
Previously, the common way to achieve this was width: 100% — which doesn’t account for margins and can cause overflow when margins are applied. The stretch keyword does the right thing. If you’ve been using -webkit-fill-available as a workaround for the same behavior, now is a good time to switch.
Dutch IJ digraph in text-transform: capitalize and ::first-letter
The Dutch IJ digraph is now available in Safari 27 beta. When the content language is Dutch (lang="nl"), text-transform: capitalize and ::first-letter now correctly titlecase “ij” to “IJ” at the start of words.
A small but genuine improvement for anyone writing Dutch text on the web.
position-anchor: normal and none
Safari 27 beta adds support for position-anchor: normal and position-anchor: none. Before, position-anchor defaults to auto, which makes every element use the implicit anchor element as its default anchor, if one exists. This has a side effect of changing an element’s positioning behavior, whether it uses anchor positioning or not. This may result in compatibility problems.
To fix this, the CSS Working Group has added two values to position-anchor to allow opting out of the new behavior:
none: an element does not have a default anchor, and its positioning behavior is unchanged.normal:autoif an element usesposition-area, otherwisenone.
position-anchor: normal is the new default value, replacing auto. This means elements will only have a default anchor and get anchor positioning behavior if it uses position-area, otherwise its behavior remains unchanged.
anchor-valid and anchor-visible
Safari 27 beta adds support for anchor-valid and anchor-visible . Originally, position-visibility: anchors-valid hides an element if any of its required anchor references can’t be resolved. However, it was not clear what constitutes “required anchor references”. The CSS Working Group has since then changed its behavior to only look at the default anchor box. To match the new behavior, some keywords also got renamed to drop the plurality:
anchors-validis renamed toanchor-validanchors-visibleis renamed toanchor-visible
Safari 27 beta aligns with the new behavior but also still supports the old keywords for compatibility.
Style containment for quotes
Safari 27 beta adds support for contain: style applying to CSS quotes. This allows you to scope effects of quotes to a certain subtree.
insert keyword for text-autospace
Safari 18.4 added support for text-autospace to control spacing between Chinese/Japanese/Korean (CJK) and non-CJK characters. Safari 27 beta now adds the insert keyword, making the following syntaxes equivalent:
text-autospace: ideograph-alpha ideograph-numeric inserttext-autospace: ideograph-alpha ideograph-numeric
Additional Bug Fixes:
- Fixed an issue where
-webkit-text-fill-colorincorrectly overrodetext-decoration-color. (47010945) - Fixed
shape-outsidecomputing incorrect text wrapping in RTL writing modes. (56890238) - Fixed flex layout to use the used
flex-basisinstead of the specified value for definiteness evaluation. (85707621) - Fixed an issue where the outline offset was too large for
outline: autoon macOS. (94116168) - Fixed an issue where element positioning was incorrect when the containing block was an anonymous block. (96548847)
- Fixed an issue where
box-shadowdid not work ondisplay: table-rowelements. (96914376) - Fixed
text-indentwithcalc()containing percentages to correctly treat percentage components as zero for intrinsic size contributions. (97025949) - Fixed an issue where out-of-flow content had an incorrect height when set to
fit-content. (97492632) - Fixed an issue with percentage size resolution in flex items in quirks mode. (100183902)
- Fixed an issue where
clip-path: inset()border-radius values did not render correctly at certain element and clip-path sizes. (110847266) - Fixed
-webkit-boxflexbox emulation not sizing children correctly inside<fieldset>elements. (114094538) - Fixed: Improved performance on pages using
:whereand:isselectors. (114904007) - Fixed an issue where elements with
display: tablecould have incorrect layout when borders were present. (116110440) - Fixed
font-familyserialization to preserve quotes around family names that match CSS-wide keywords or generic families. (125334960) - Fixed an issue where elements with
border,position: absolute, andaspect-ratio: 1were not rendered as squares. (126292577) - Fixed an issue where
perspective-originfailed to resolvevar()references when used as the second value, preventing animations from being applied. (131288246) - Fixed
:focus-visibleincorrectly matching after a programmaticfocus()call triggered by clicking a button with child elements. (134337357) - Fixed an issue where the bottom margin of a last child element collapsed out of a parent with
min-height. (134356544) - Fixed a performance issue where pages with many DOM manipulations and complex
:has()selectors could freeze. (138431700) - Fixed an issue where a font was downloaded despite no characters in the document falling within its
unicode-range. (140674753) - Fixed an issue where
@media (prefers-color-scheme: dark)inside an iframe did not match when the iframe’scolor-schemewas set todark. (142072593) - Fixed an issue where
background-clip: textdid not work on table header elements. (142812484) - Fixed an issue where
width: 0did not collapse a table cell to its minimum size. (142814603) - Fixed an issue where
:has(:empty)continued to match after the targeted element’s content was dynamically changed to no longer be empty. (143864358) - Fixed an issue where floats and out-of-flow objects could be incorrectly adjacent to anonymous blocks. (144481961)
- Fixed an issue where text gradually disappeared when toggling
text-transformon elements with::first-letterstyling. (145550507) - Fixed an issue where
height: max-contentresolved to zero on absolutely positioned elements when a child hadmax-height: 100%. (147333178) - Fixed an issue where tables with collapsed borders incorrectly calculated the first row width, causing excess border width to spill into the table’s margin area. (149675907)
- Fixed an issue where an
inline-flexcontainer withflex-direction: columndid not update its width to match the intrinsic size of a child image when the image was not cached. (150260401) - Fixed CSS
zoominteracting incorrectly withfont-weight,font-style, andfont-varianton iPad. (152173269) - Fixed an issue where non-replaced elements with
aspect-ratioenforced the automatic minimum size even whenmin-widthwas explicitly set to0. (156837730) - Fixed an issue where an element can’t anchor to its previous sibling. (162903640)
- Fixed
:has()style invalidation performance for selectors where:has()is in non-subject position. (163512170) - Fixed an issue where RTL grid scrollable areas did not correctly account for grid layout and scrollbars. (167792896)
- Fixed pixel snapping to be applied consistently for all
border-widthvalue types. (168240347) - Fixed rendering of linear gradients when all color stops are at the same position. (169063497)
- Fixed an issue where
insetbox-shadowwas incorrectly positioned on table cells with collapsed borders. (169254286) - Fixed
position-try-orderto interpret logical axis values using the containing block’s writing mode instead of the element’s own writing mode. (169501069) - Fixed an issue where children with percentage heights inside absolutely positioned elements using intrinsic height values (
fit-content,min-content,max-content) incorrectly resolved against the containing block’s height instead of being treated asauto. (171179193) - Fixed an issue where percent-height replaced elements computed stale preferred widths in shrink-to-fit containers. (171184282)
- Fixed a regression where
@scopestyles did not apply to slotted elements in web components. (171383788) - Fixed an issue where the table cell
nowrapminimum width calculation quirk was applied outside of quirks mode. (171410252) - Fixed a performance issue where
contain: layoutcaused significantly slower forced layouts when all siblings created their own formatting context. (171545381) - Fixed an issue where dynamically inserting text before existing content did not update
::first-letterstyling. (171649994) - Fixed an issue where underlines were split when a ruby base was expanded due to long ruby text. (171653095)
- Fixed an issue where changing
color-schemedid not repaint iframe background. (171658244) - Fixed an issue where nested children of a popover element failed to render when using
position: absolute. (171735933) - Fixed an issue where
color: initialresolved to the wrong color when the system is in dark mode. (172320282) - Fixed an issue where an element with
display: contentsdid not establish an anchor scope when usinganchor-scope. (172355302) - Fixed an issue where ordered list numbers with large starting values were clipped off-screen. (172515216)
- Fixed
<general-enclosed>in media queries to reject content with unmatched close brackets per the<any-value>grammar. (172575115) - Fixed an issue where the
rlhunit was double-zoomed with evaluation-time CSS zoom. (172798163) - Fixed an issue where anchor-positioned elements anchored to children of sticky-positioned boxes did not stick correctly. (172884148)
- Fixed an issue where pseudo-elements were not sorted correctly when sorting anchor elements by tree order. (173032203)
- Fixed
outline: autoto correctly respect zoom. (173068660) - Fixed
outline-offsetto work correctly withoutline: autoon iOS. (173130230) - Fixed
:active,:focus-within, and:hoverpseudo-classes to correctly account for elements in the top layer. (173145294) - Fixed a regression where the
iclength unit was incorrectly affected by page scaling. (173198587) - Fixed the
shape()function to omit default control point anchors in computed value serialization per the CSS Shapes specification. (173233716) - Fixed: Updated SVG and MathML user agent style sheets to use
:focus-visibleinstead of:focus. (173321368) - Fixed an issue where
lhandrlhunits resolved with double-zoom whenline-heightwas a number value. (173448638) - Fixed
outline-widthto be ignored whenoutline-styleisauto, matching the specification. (173567890) - Fixed
:in-rangeand:out-of-rangepseudo-classes for time inputs with reversed ranges. (173589851) - Fixed
:placeholder-shownto correctly match input elements that have an emptyplaceholderattribute. (173604635) - Fixed an issue where ligatures caused a non-zero layout width for text with
font-size: 0. (173840866) - Fixed computed value of auto insets or margins as returned by
getComputedStyle()to be zero, if the element usesposition-areaoranchor-center. (173885561) - Fixed
position-areanot being able to anchor to an element positioned using anchor functions. (173964030) - Fixed
:in-rangeand:out-of-rangepseudo-classes to correctly update when thereadonlyattribute changes. (173978657) - Fixed an issue where
view-timeline-insetserialization failed to coalesce identical values. (174096313) - Fixed CSS variable cycle detection to match the CSS Values Level 5 specification. (174105259)
- Fixed
url()token serialization in CSS custom properties. (174144616) - Fixed
text-autospaceto correctly handle supplementary Unicode characters. (174148315) - Fixed an issue where flex items with different
ordervalues caused incorrect baseline alignment. (174241817) - Fixed an issue where hovering over
::first-lettertext showed a pointer cursor instead of the expected I-beam cursor. (174258447) - Fixed an issue where
display: gridon a<fieldset>element added extra unnecessary space below its content. (174301311) - Fixed outline radii rendering for elements with a non-auto
outline-style. (174328839) - Fixed an issue where
aspect-ratiowas not honored when the page was zoomed in. (174361289) - Fixed replaced elements to use the transferred size through intrinsic aspect ratio for min-content and max-content sizing. (174386310)
- Fixed an issue where
height: 100%on a child element altered the layout when the parent’s height was defined viaaspect-ratio. (174448267) - Fixed margin collapse to be allowed when the preferred block size behaves as auto, per the CSS Sizing specification. (174547610)
- Fixed an issue where
document.styleSheetsandshadowRoot.styleSheetsincorrectly included adopted style sheets, which per the CSSOM specification should only appear in the final CSS style sheets list used for style resolution. (174583340) - Fixed the CSSOM preferred style sheet set name to be established at sheet creation time based on insertion order rather than tree order. (174586058)
- Fixed highlight pseudo-elements such as
::selectionand::highlightto disallow vendor-prefixed properties, aligning with the CSS Pseudo-Elements specification. (174590593) - Fixed cycle detection and nested function call handling in CSS custom functions. (174609179)
- Fixed
FontFace.loadedto reject when alocal()font source fails to load. (174631384) - Fixed an issue where
word-break: break-allincorrectly allowed CJK close punctuation to appear at the start of a line. (174656971) - Fixed an issue where
word-break: keep-allincorrectly suppressed line break opportunities at CJK punctuation characters. (174658701) - Fixed the
FontFaceconstructor to reject with aSyntaxErrorinstead of aNetworkErrorwhen aBufferSourcefails to parse, per the CSS Font Loading specification. (174669738) - Fixed the
FontFacefamilyattribute to return the serialization of the parsed value. (174698351) - Fixed grid layout to correctly handle percentage and
calc()values for the specified size suggestion. (174863227) - Fixed
:has()sibling invalidation issues related to relation forwarding. (175006235) - Fixed an issue where
min-width: autowas not correctly computed for flex items. (175157619) - Fixed an issue where percentage heights inside flex items did not resolve correctly in quirks mode. (175158571)
- Fixed an issue where
margin-trim: block-startdid not apply to blocks nested inside inline boxes. (175162899) - Fixed an issue where dynamically changing
display: contentson a<fieldset>legend caused incorrect rendering. (175163337) - Fixed: Improved
:has()invalidation performance by including the full selector context in invalidation selectors. (175177078) - Fixed the CSS preload scanner to resolve relative
@importURLs against the<base>element URL. (175305190) - Fixed
-webkit-boxflex distribution for children with orthogonal writing modes. (175323734) - Fixed
calc(infinity)as aflex-growfactor not stretching a flex item to 100% width. (175431146) - Fixed
:has()sibling invalidation failing due to an internal bitfield overflow, causing stale styles when siblings are added or removed. (175433733) - Fixed
:has()invalidation for sibling combinators when elements are inserted or removed from the DOM. (175441568) - Fixed
transition-propertynot preserving the specified case of<custom-ident>values during serialization. (175467206) - Fixed the
will-changeproperty not serializing correctly when used with non-property identifiers or identifiers in a non-standard case. (175482352) - Fixed percentage
topandbottomvalues on relatively positioned elements not resolving when the containing block hasaspect-ratio. (175502356) - Fixed: Updated the enhanced
<select>element to useself-keywords for anchor positioning. (175505107) Fixedtext-indentcomputation when tab stop positions are involved. (175529961) - Fixed
calc()margin computations in flex layout. (175532405) - Fixed
calc()margin computations for block, fieldset, and table caption layouts. (175548980) - Fixed handling of
<li>valueattributes in reversed ordered lists. (175558324) - Fixed CSS trigonometric functions to correctly convert degrees to radians. (175575617)
- Fixed
sibling-index()andsibling-count()inside calc() functions to be correctly simplified. (175590806) - Fixed
sibling-index()andsibling-count()to correctly return 0 when used in cross-tree::part()styling. (175592607) - Fixed the CSS
resizehandle not working on an element when the handle overlaps a child iframe. (175621855) - Fixed flex container baseline alignment being incorrectly computed for scroll containers by clamping to the border edge. (175631095)
- Fixed an issue where inline-level boxes with
calc()margins or padding lost the fixed component during intrinsic width computation. (175669222) - Fixed floats with
margin-startincorrectly overlapping adjacent floats. (175669464) - Fixed
aspect-ratiocalculations for block-level elements with size constraints. (175669713) - Fixed
aspect-ratiocalculations for flex items with percentage cross-size constraints. (175669774) - Fixed
aspect-ratiocalculations for flex items with definite cross-size values. (175690028) - Fixed
revert-layercomputing incorrectly when there is a leading empty or space substitution value. (175729680) - Fixed
:has()invalidation incorrectly resetting sibling relation bits, causing style invalidation failures for first-in-sibling-chain elements. (175738008) - Fixed an issue where flex items with explicit
min-height: min-contentwere incorrectly treated as scrollable, zeroing out their minimum size. (176173688) - Fixed
:has()invalidation performance when used inside nested:is()selectors. (176354723) - Fixed
sibling-count()&sibling-index()used in@keyframesto re-resolve when siblings change. (176531901) - Fixed an issue with a collapsed border color mismatch when the table cell has a different writing-mode. (173655092)
Scroll Anchoring
Scroll anchoring is now supported in Safari 27 beta. When content is inserted or removed above the current viewport position — an image loads, an ad injects, a comment appears — the browser automatically adjusts the scroll position so the content you’re reading stays put instead of jumping.
This is an improvement you’ll feel on many sites, especially ones with lazy-loaded images, infinite-scroll feeds, or dynamically injected content. Most sites get this for free — no opt-in required.
Scroll anchoring is controlled by the overflow-anchor CSS property, which defaults to auto. If you have a specific element where you need to opt out of scroll anchoring, set overflow-anchor: none.
Additional bug fixes:
- Fixed an issue on iOS where calling
scrollToduring a momentum scroll incorrectly interrupted the scroll, ensuring that momentum scrolling continues as expected and smooth scrolling behaves properly. (41949531) - Fixed an issue on iOS where programmatic smooth scrolling with
scroll-snap-type: mandatoryfailed after the browser chrome was hidden. (100727098) - Fixed an issue where interrupting scroll momentum caused the scrolling container to stop rendering and hit-testing to be misplaced. (116205365)
- Fixed an issue on iOS where restored scroll position was incorrect after relaunching Safari. (127308062)
- Fixed an issue where tabbing in a scroll container with
scroll-paddingdid not scroll the focused element into view. (147513379) - Fixed an issue on macOS where custom CSS scrollbars could be cut off and the scrollbar corner rect was sized incorrectly. (168566468)
- Fixed rubberbanding behaving incorrectly when a site triggers a smooth scroll to the top during a rubberband. (170705188)
- Fixed an issue where pages could become blank and jump to the top after dynamically loading new content when scroll anchoring was enabled. (170889205)
- Fixed an issue where scroll anchoring could cause pages to scroll to negative offsets. (171221075)
- Fixed an issue where pages using the Navigation API could have offset hit test locations, making elements unclickable. (171752650)
- Fixed an issue on iOS where composited layers would briefly flash blank when
window.scrollTo()was called synchronously with a DOM layout change. (173197381) - Fixed an issue where sticky-positioned elements could flicker rapidly after scrolling. (173680821)
- Fixed an issue where scroll anchoring could cause a page to scroll to the top or bottom automatically. (173885027)
- Fixed an issue where calling
scrollIntoView()on a scrollable element incorrectly scrolled the element’s own contents. (174173683) - Fixed scroll anchoring interfering with rubberbanding on some websites. (175195943)
- Fixed an issue on iOS where scroll position was not preserved correctly when rotating the device on right-to-left pages. (175910769)
HTML
sizes=”auto” on img
The auto keyword in the sizes attribute on <img> elements is now supported in Safari 27 beta.
<img src="photo.jpg"
srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1200.jpg 1200w"
sizes="auto"
loading="lazy"
alt="A mountain landscape">
When an image uses loading="lazy" and you don’t know its rendered layout width ahead of time, sizes="auto" tells the browser to calculate the size automatically based on the actual layout width once it’s known. This makes responsive images work correctly for images inside layout containers with dynamic widths.
shadowrootslotassignment attribute
Safari 27 beta adds support for the shadowrootslotassignment attribute on declarative shadow roots. This lets you configure the slot assignment mode (named or manual) directly in HTML when defining a shadow root declaratively, matching the JavaScript attachShadow({ slotAssignment: "manual" }) option.
Additional bug fixes:
- Fixed an issue where an HTML
mapelement without anameattribute did not match its associated image using theidattribute. (12359382) - Fixed sequential focus navigation to skip elements that do not meet the specification’s focusability requirements. (103370883)
- Fixed viewport
<meta>parsing to correctly treat form feed as ASCII whitespace per the HTML specification. (108440799) - Fixed parsing of
javascript:URLs to align with the specification. (147612682) - Fixed an issue where a third nested
<iframe>using thesrcdocattribute did not render. (167917471) - Fixed incorrect parsing of pixel-length margin attributes on
<body>,<iframe>, and<frame>elements. (171240848) - Fixed an issue where
replaceWith()stopped processing remaining nodes if a script in the replacement removed a sibling. (172753019) - Fixed an issue where HEIC images were incorrectly converted to JPEG when uploaded via drag-and-drop or file input. (173206598)
- Fixed the HTML preload scanner to skip preloading stylesheets that have the
disabledattribute. (173378582) - Fixed an issue where setting the
relattribute on an<a>element multiple times did not clear prior link relations. (173567839) - Fixed the HTML parser fast path to correctly process escaped attribute values longer than one character. (173673581)
- Fixed the HTML parser fast path to correctly detect nested
<li>elements. (173983892) - Fixed the HTML parser fast path to use the adjusted current node for MathML and SVG integration point checks. (174096305)
- Fixed document named item collection to include all
<object>elements, aligning with other browser engines. (174537345) - Fixed
window.open()to correctly consume user activation when creating a new browsing context, aligning with the HTML specification. (174587258) - Fixed remaining issues with
<img sizes="auto">to fully align with the specification. (174684058) - Fixed an issue where
dir=autoon<slot>elements did not update when slotted content changed. (174871706) - Fixed an issue where
<option>elements rendered incorrectly when thelabelattribute was empty. (174979446) - Fixed an issue where the preload scanner incorrectly skipped
<source>elements with an emptytypeattribute inside<picture>. (175094037) - Fixed
innerTextto emit a newline for empty<option>or<optgroup>inside<select>. (175245381) - Fixed HTML floating-point number parsing to correctly handle values with a leading
+sign. (175300431) - Fixed
innerTextto no longer emit newlines forvisibility: hiddenblock elements. (175569426) - Fixed
innerTextto correctly emit blank lines around<p>elements regardless of their CSSdisplayvalue. (175729427) - Fixed the speculative preload scanner to no longer incorrectly preload scripts inside SVG elements. (175800116)
- Fixed
innerTexton tables to no longer emit spurious trailing newlines and to preserve row-exit newlines after empty rows. (176635985) - Fixed an issue where inserting an image with a
srcsetattribute into a dynamically created iframe resulted in an invisible image. (66849050) - Fixed
naturalWidthandnaturalHeightreturning incorrect values for SVG images without intrinsic dimensions. (141196049) - Fixed an issue where HDR images would flicker and lose their HDR appearance when overlapping layers animate. (163382580)
- Fixed an issue where adopting a standalone
imgelement did not update its image data. (172856773)
JavaScript
Top-Level Await
Safari 27 beta includes a complete standards-compliant rewrite of the ECMAScript module (ESM) loader. The new loader is implemented in native C++ and conforms directly to the ECMAScript specification’s module loading algorithms, replacing an earlier implementation based on an abandoned 2016 WHATWG Loader proposal that predated top-level await entirely.
The rewrite fixes module execution ordering and initialization issues that could cause imports to access exports before they were fully evaluated. It was validated against test262, the Web Platform Tests, and additional test cases.
Top-level await is a foundational feature of modern JavaScript module authoring, and it’s been a real pain point in Safari for a while — a known source of cross-browser bugs that developers building module-based apps had to work around. This fix closes that gap.
Additional bug fixes:
- Fixed multiple top-level await correctness bugs with a rewrite of the ES module loader for standards compliance. (97370038)
- Fixed regular expressions in Unicode mode to not count non-capturing groups and modifiers toward the number of available backreferences. (167746769)
- Fixed
%TypedArray%.prototype.subarrayto calculatebeginByteOffsetcorrectly to align with ECMA-262. (168143600) - Fixed the trace behavior of
RegExp.prototype[Symbol.split]to align with ECMA-262. (168288878) - Fixed
Array.prototype.concatto correctly handle arrays with indexed accessors, preventing getter reentry from bypassingSymbol.isConcatSpreadablechecks. (172237596) - Fixed an issue where a greedy or non-greedy non-BMP character class in a regular expression could advance the index past the end of input. (172978772)
- Fixed an issue where class instance field initializers did not have the correct evaluation context when used inside arrow functions and nested scopes. (173296563)
- Fixed TypedArray
[[Set]]to check the receiver before writing to the typed array. (173386404) - Fixed
%ArrayIteratorPrototype%.next()to return{ done: true }instead of throwing aTypeErrorwhen the source TypedArray is detached and the iterator has already completed. (173759106) - Fixed an issue where a fixed-count mixed-width character class in a regular expression did not correctly restore the index on backtrack. (173972458)
- Fixed an issue where regular expressions with non-BMP characters could skip valid match positions when alternating between patterns. (174200307)
- Fixed an issue where regular expression captures were not properly cleared when backtracking out of fixed-count parenthesized groups and negative lookaheads. (174201284)
- Fixed an issue where
import { "*" as x }was incorrectly treated as a namespace import instead of a named import using the string“"as a ModuleExportName. (174314099) - Fixed an issue where
RegExp.prototype.execandRegExp.prototype.testcould match against a stale pattern iflastIndexhas avalueOfthat callsRegExp.prototype.compile. (174461752) - Fixed an issue where async functions using module-scoped variables could fail when the DFG JIT optimized scope resolution. (174626957)
- Fixed an issue where
Intl.Segmenterwithgranularity: "word"incorrectly reportedisWordLike: falsefor numeric segments. (175057894) - Fixed
Object.definePropertiesto call Proxy traps in the correct order. (175068687) - Fixed an issue where
Intl.Localedid not canonicalize before overriding the language. (175092327) - Fixed time zone identifiers to return primary IANA time zone IDs instead of legacy ICU identifiers. (175098682)
- Fixed
Intl.DateTimeFormatto preserve the original legacy timezone identifier instead of replacing it with the primary IANA ID. (175206605) - Fixed
Promise.prototype.finallyto throw aTypeErrorwhen@@speciesis not a constructor, matching the behavior of other browsers. (175290627) - Fixed the regular expression engine to reject dangling hyphens in character class syntax when using the
/vflag. (175559808) - Fixed a performance issue with module resolution by limiting cache population to star-resolution and indirect-resolution cases. (175826413)
- Fixed a performance issue with
TypedArray.prototype.lastIndexOfby adding SIMD-accelerated reverse search for numeric types. (175904377) - Fixed a performance issue where building a module namespace with many
exportstatements was significantly slower than necessary. (175949532) FixedDataViewconstructor to match specification-defined argument validation order and error throwing behavior. (176110210) - Fixed an issue where
Array.prototype.concatcould produce incorrect results when combining arrays with incompatible indexing types. (176219964)
WebAssembly
JavaScript Promise Integration (JSPI)
Safari 27 beta adds support for WebAssembly JavaScript Promise Integration (JSPI). JSPI lets synchronous-looking WebAssembly code suspend and wait for JavaScript Promises, making it much easier to port existing C, C++, Rust, and other language code to the web where that code expects synchronous I/O.
Before JSPI, porting code that called synchronous APIs to Wasm required rewriting everything on top of a callback or async state machine. With JSPI, the Wasm module can suspend at a call site and resume when the Promise resolves — the rest of the module sees straight-line synchronous code. This is a significant capability for the Wasm ecosystem.
Additional bug fixes:
- Fixed
WebAssembly.SuspendingandWebAssembly.SuspendErrorto be data properties instead of getter functions, aligning with other WebAssembly attributes likeWebAssembly.Module. (170155726) - Fixed incorrect
IntegerOverflowexceptions thrown byi32.rem_s,i64.rem_s,i32.div_u,i64.div_u,i32.rem_u, andi64.rem_uwhen both operands are constants. (175122462) - Fixed a regression where
RegisterSet::normalizeWidths()lost vector-width information, causing v128 argument corruption in WebAssembly SIMD thunks. (176035764)
MathML
Multiple-character operators in MathML
Safari 27 beta now supports multiple-character operators in MathML, improving the rendering of complex mathematical notation that uses operators like ++, :=, /=, and similar. We also updated operator dictionary to MathML Core, so that we also support multi-character, combining character, and updated operator dictionary.
tabindex, focus(), blur(), and autofocus on MathML
Safari 27 beta now supports tabindex, focus(), blur(), and autofocus on MathML elements, improving MathML feature parity’s with HTML. This makes math content fully participate in keyboard navigation and focus management, which supports interactive educational content and accessibility.
Additional bug fixes:
- Fixed an issue where symmetric non-stretchy large operators were not centered around the math axis. (170905663)
- Fixed an issue where dynamic changes to
<mo>element attributes did not trigger a relayout. (170907029) - Fixed an issue where
minsizeandmaxsizedefaults and percentages did not use the unstretched size as specified. (170908253) - Fixed positioning of the
<mprescripts>element within<mmultiscripts>layout. (170909975) - Fixed an issue where the MathML fraction bar was not painted when its thickness was equal to its width. (170934351)
- Fixed an issue where
<none>and<mprescripts>elements were not laid out as<mrow>elements in MathML. (170940035) - Fixed an issue where MathML token elements ignored
-webkit-text-fill-colorwhen painting math variant glyphs. (172020318) - Fixed
paddingandborderrendering on<msqrt>and<mroot>elements and corrected token sizing formathvariant. (173081436) - Fixed absolute positioning of elements inside MathML by ensuring logical height is updated. (173088146)
- Fixed
tabIndexvalues not being set correctly for MathML elements. (174734133)
Spatial Web
Immersive website environments in visionOS

Safari 27 beta in visionOS 27 adds support for immersive website environments. Developers can now provide incredible immersive experiences with a simple <model> element and one JavaScript API call. The Immersive API on the model element works similarly to how the Fullscreen API does on video elements. Learn more in the WWDC26 session Explore immersive website environments in visionOS.
Consider what this makes possible in a browser: a ticketing site where you can see the view from your seat before you buy, or a hotel that lets you walk the room, all built with standard web technology, no app required.

img controls on spatial and panorama photos
Safari 27 beta in visionOS 27 adds support for the controls attribute on <img> elements displaying spatial and panorama photos. When applied, the image gets native interactive controls appropriate for the content type, allowing the image to be viewed spatially or immersively wrapped around the user.

model on iOS, iPadOS, and macOS
The <model> HTML element is now available in Safari on iOS, iPadOS, and macOS, joining its existing availability in visionOS. Web developers can now embed interactive 3D content using standard HTML across Apple platforms.
<model src="teapot.usdz"></model>
Learn more in the WWDC26 session Get started with the HTML Model Element.

dynamic-range-limit on model
Safari 27 beta adds support for dynamic-range-limit on the <model> element, giving you control over the HDR rendering range for 3D content in iOS and macOS.
Additional bug fixes:
- Fixed spatial and panoramic image controls to support RTL language layout and localization of type labels. (161690817)
- Fixed
<model>elements displaying at 100x the expected size for assets authored in tools that use centimeter units. (167805672) - Fixed an issue where WebXR viewports did not get an initial value until
getViewport()was called. (168125694) - Fixed an issue where the
<model>element stagemode orbit physics behaved differently between iOS and visionOS. (172189776) - Fixed an issue on visionOS where fullscreen video would sometimes jump when exiting fullscreen if the browser window was narrower than the video. (174454557)
WebGPU
Safari 27 beta now supports the clip_distances built-in value in WGSL shaders. Clip distances are a WebGPU feature that allows vertex shaders to define custom clipping planes, enabling you to discard geometry on one side of an arbitrary plane before rasterization occurs.
Additional bug fixes:
- Fixed
compressedTexImagenot validating whether the compressed texture format extension has been enabled. (175652171) - Fixed some
texImagefunctions reporting errors with incorrect function names. (175652807) - Fixed some WebGL context state properties not being correctly reset on context loss. (176190808)
- Fixed
GPUDevice.onuncapturederrorevent handler attribute not working. (149577124) - Fixed: Restored
maxStorageBuffersInFragmentStageand related WebGPU limits. (160800947) - Fixed rendering failing when using direct
GPUTextureobjects instead ofGPUTextureViewwith multisampled resolve targets in render passes. (175452924)
Media
TextTrackCue.endTime = Infinity
Safari 27 beta supports setting TextTrackCue.endTime to Infinity to represent an unbounded cue duration. It’s useful for captions or data cues of live streams.
Additional bug fixes:
- Fixed an issue where decoding WebM audio files with more than two channels would fail. (82160691)
- Fixed an issue where
preservesPitchandplaybackRatewere not correctly handled on anHTMLMediaElementconnected to anAudioContextviacreateMediaElementSource. (93275149) - Fixed
MediaCapabilities.decodingInfo()incorrectly reporting VP8 in WebM as not supported. (127339546) - Fixed an issue on iPad where exiting fullscreen on a media document incorrectly navigated back to the previous page instead of returning to the inline view. (137220651)
- Fixed an issue where the WebCodecs
VideoDecoderAPI output frames in an incorrect order for videos containing B-frames. (145093697) - Fixed an issue where the darkening overlay on inline video controls made accurate scrubbing difficult and displayed video content incorrectly on macOS. (161271114)
- Fixed an issue where WebM with VP9/Vorbis fallback would not play. (164053503)
- Fixed video playback failing when the declared MIME type in a
<source>element does not match the actual content type served by the server. (166181001) - Fixed an issue where text selection was broken after pausing a video when the media player ran in the content process. (167727538)
- Fixed
HTMLMediaElement.currentTimeto report smoothly progressing values instead of updating only at fixed intervals. (170115677) - Fixed an issue where MP4 files containing Opus audio tracks could not be decoded with
decodeAudioData. (170196423) - Fixed an issue where the
VideoFrameconstructor did not handle the video color range correctly for NV12 (I420 BT601) video frames. (170299037) - Fixed an issue where Live Text selection was unavailable on paused fullscreen videos. (170817667)
- Fixed an issue where FairPlay-protected VP9 content failed to play via
MediaSource. (171210968) - Fixed an issue where autoplay would proceed before default text tracks finished loading. (171699293)
- Fixed the
currentTimegetter to returndefaultPlaybackStartPositionwhen no media player exists. (171722368) - Fixed
HTMLMediaElementto fire atimeupdateevent when resetting the playback position during media load as required by the specification. (171785463) - Fixed an issue where the media player
preloadattribute was not properly updated when theautoplayattribute was set. (171883159) - Fixed an issue where seeking in a WebM video did not work correctly while content was still loading. (172473039)
- Fixed an issue where media playback could not move to the next item in a playlist when the tab was in the background. (172676372)
- Fixed an issue where scrubbing a video in full-screen mode could cause it to exit full-screen. (172682230)
- Fixed an issue where HDR video content appeared washed out due to colorspace information being lost during processing. (172721079)
- Fixed Encrypted Media Extensions to check support for the full content type including codecs, rather than only the MIME type. (173852931)
- Fixed an issue where setting
HTMLMediaElement.volumehad no effect when the element was connected to anAudioContext. (174278899) - Fixed
ImageCaptureto correctly queuetakePhoto()andapplyConstraints()requests to avoid concurrent capture session reconfiguration. (174950018) - Fixed a regression where videos would stop playing and lose audio after a few seconds on some websites. (174966899)
- Fixed an issue where U+0000 (NULL) characters were not allowed in
VTTCuetext content. (175084171) - Fixed video content disappearing after switching to another tab and back. (175257980)
- Fixed WebVTT cue set
0 Comments
Log in to join the conversation.No comments yet. Be the first to share your thoughts.