Chromium 147 → 154 — What BlinkGTK Gained

Version: 1.2.5-build5 / Language: English | 日本語

BlinkGTK embeds Chromium's rendering engine, Blink, as-is. When Chromium gains a new
web capability, moving BlinkGTK to a newer base gives you that capability directly.
This document walks through what changed across Chromium 147, 148, 149, 150, 151, 152, 153 and 154 —
the versions BlinkGTK has been built on — from the side of what you can actually do.

It is not a digest of specifications. We diffed the engine source trees themselves,
version against version, and selected what matters to you. The exact method is at the end.


How to read this — "landed" is not "usable"

Web features do not reach every user the moment they are written. In Blink, each feature
carries a runtime flag, and its state decides whether the feature is on by default.
This document distinguishes three states. Mixing them up produces the worst kind of
documentation bug — "it's written here but it doesn't work" — so let us be explicit.

Label Flag state Meaning
On by default stable Works with no action. Available in BlinkGTK as-is
Experimental experimental Off by default; enable explicitly with a launch flag
In development test Test runs only. The property may parse, but rendering is unaffected

The third one is the trap. hanging-punctuation — hanging punctuation at line edges,
long awaited in Japanese typography — landed as a CSS property in 149. It parses,
and getComputedStyle() returns a value. But its implementation flag is still test
as of 151, so it does not affect line layout. "The property exists" and
"the typesetting changes" are two different events.

Measured, this mismatch shows up in a way that lies to feature detection
(BlinkGTK v1.2.0 / Chromium 151):

without the flag                                   -> CSS.supports(...) = false
with --enable-blink-features=CSSHangingPunctuation -> CSS.supports(...) = true
                                                      getComputedStyle = "allow-end"

CSS.supports() returns true, yet line layout does not change by a single pixel.
With a container exactly eight characters wide holding "eight characters + a full stop",
hanging would keep it on one line — but both none and allow-end produce two lines.

So CSS.supports('hanging-punctuation', ...) is not a usable feature check here.
Design your pages as if the feature does not exist yet.


The shape of it

Across eight versions, the engine's feature flags went from 1,103 to 1,222. They peaked at 1,240 in 152; 153 brought the number down by clearing out switches for behaviour that had settled.

Chromium Feature flags Newly on by default Added Removed CSS properties BlinkGTK
147 1,103 — — — 800 v1.0.6 – v1.0.10-build16
148 1,116 34 47 34 800 v1.0.11-dev
149 1,140 39 52 28 803 (tracked only)
150 1,172 48 51 19 820 v1.1.0-build1 – build6
151 1,214 44 64 22 822 v1.2.0-build1 – build9
152 1,240 41 56 29 820 v1.2.1-build1 – build3
153 1,220 28 39 59 824 v1.2.2-build1 – build6
154 1,222 16 27 25 824 v1.2.3-build1 –

Each version turns on 16–48 features by default and removes 19–59. The 59 removals in 153 stand out; 48 of them were switches for behaviour that was already on by default. Removals are easy
to overlook, yet they are the more likely reason an upgrade breaks something. That is why
every section below ends with migration notes.


147 → 148 — Underlines and container queries settle down

In one line: fewer headline features, more CSS details brought into agreement.

Text

Underlines now skip descenders (wider application of text-decoration-skip-ink).
When an underline crosses the tail of a g or p — or a Japanese ぎ — legibility
drops visibly. This was experimental in 147 and became the default in 148.

Variable-font avar2 support also landed: the newer table format for varying weight and
width continuously within a single font file.

CSS

Elsewhere

Migration notes

Remnants of the <command> element were removed. Most applications are unaffected,
but check if you carry old code forward.


148 → 149 — Column rules, and a vessel for hanging punctuation

In one line: multi-column layout gained expressiveness, and Japanese typography
gained one container.

For Japanese typography

hanging-punctuation landed as a CSS property — hanging punctuation and brackets
outside the text block at line start or end (none / first / last / allow-end).
It maps directly onto what JIS X 4051 and JLReq require. Values parse, and
getComputedStyle() reports them.

But as noted above, the implementation flag is still test as of 151. You can write
it; it does not yet take effect. This is one to watch upstream, and BlinkGTK is
tracking it.

Caret movement across lines containing ruby was fixed. Pressing up/down in ruby-annotated
body text no longer behaves differently depending on whether ruby is present. Editors
benefit directly.

text-decoration-skip-spaces was added, controlling whether underlines skip inter-word spaces.

Column rules

Rules drawn between columns and rows (column-rule / row-rule) were substantially
extended. Where a rule stops, and how it behaves at junctions, is now expressible through
the *-inset-cap and *-inset-junction families. Rules running past the end of a column
can be solved in CSS alone.

Note that in 148 these were named column-rule-edge-inset and column-rule-interior-inset;
149 renamed them to -inset-cap and -inset-junction as the specification settled.

Elsewhere

Migration notes

The column-rule renames above mean stylesheets written with the pre-149 names
stop working. Rewrite them if you use them.


149 → 150 — Tools for tightening the text block

In one line: the richest of these five versions, and the foundation of BlinkGTK v1.1.0.

For Japanese typography

text-box-trim now works inside nested lists. This trims the font-derived space
(half-leading) above and below a line so the text block is built from the intended glyph
height. In Japanese layout you need this to bring the gap between a heading and body text
down to the designed value.

Full-width space handling was fixed. Reusing the offset mapping between text and
layout no longer breaks on full-width spaces, so selection ranges and break positions stay
correct in text that mixes them in.

Grapheme cluster bounds checking landed, making it harder to split emoji ligatures
and combining sequences when moving the caret or deleting.

text-transform now applies to ::first-line, and line-breaker abort handling improved.

CSS

Elsewhere

Migration notes


150 → 151 — Ruby and emphasis marks come into their own

In one line: for Japanese typography, the most direct gain in these five versions.

For Japanese typography

Ruby overhang (ruby-overhang) is on by default. Experimental since 147, it finally
becomes the default in 151. It controls how far ruby text may extend over neighbouring
base characters when the annotation is longer than what it annotates. A none value
arrived alongside it. This is the engine meeting JLReq head-on on how ruby may be placed.

Emphasis marks (boten) are now processed through the ruby path. This sounds like an
internal detail, but the typeset result changes. Previously, adding emphasis marks
grew the line box itself; in 151 the line box stays at line-height and the outer
container grows instead.

We measured the effect on a 151 build: vertical writing mode, font-size: 16px,
text-emphasis-style: sesame, reading the actual paragraph pitch.

Leading available Without marks With marks Delta
Yes (line-height: 2.6 = 41.59px) 150 41.59 44.09 +2.50
151 41.59 41.59 0
No (line-height: 1.75 = 28px) 150 28.00 37.00 +9.00
151 28.00 30.00 +2.00

Given room in the leading, emphasis marks no longer grow the line pitch. Without
room, the growth shrinks from +9.00 in 150 to +2.00. In Japanese vertical documents that
use emphasis marks heavily, the line count of the text block can change, and total page
count can drop
. That is why we suggest verifying existing layouts — the change is for
the better, but it is still a change.

text-autospace now ignores ruby annotations, so automatic spacing between Latin and
Japanese is no longer perturbed by ruby text.

Line breaking is allowed after a space preceding an open tag, which reduces breaks
landing in unintended places in markup such as 日本語 <span>語</span>.

Experimentally, AnnotationSpaceOnStart (space on the start side of an annotation)
landed. It is off by default, but worth watching as it concerns spacing around ruby and
emphasis marks.

Editing and selection

Elsewhere

Migration notes — things may break here

Change Impact
Emphasis marks via ruby path Line height and total line count may change in documents using them
readyState of document.implementation.createHTMLDocument() The state right after creation now follows the specification
Nested popover hint Showing one nested now throws
getComputedStyle outside the flat tree Off by default
Sub Apps API Removed

151 → 152 — Ruby placement is rebuilt

In one line: the annotation space we flagged in 151 as "worth watching" is on
by default in 152, and the ruby placement computation itself has been rebuilt.

What this gave Japanese typography

Start-side annotation space (AnnotationSpaceOnStart) is now on by default.
It was experimental in 151. When a block has no border on its start side, a ruby
annotation may now overflow into that margin — a way of placing ruby without
inflating the line height.

There is a case where it does not apply. The implementation excludes balanced
columns. Do not rely on this path in multi-column vertical writing. The test
upstream added is horizontal (no writing-mode) and does not exercise page or
column fragmentation.

Ruby placement is now computed as a tree (TreeRubyPlacement). Instead of
laying annotation lines out flat, the engine builds a tree with parent/child
relationships and positions each line relative to the base. Annotations on both
sides, and nested ruby, now go through this path.

Tab stops inside a ruby base follow the specification (TabSizeInRubyBase).
CSS Text 3 defines tab stops as multiples measured from the content edge of the
nearest block container ancestor; 152 matches that definition.

Not measured: for all three of the above we have confirmed that the flag and
the code exist. We have not measured how the typeset result changes. There is
no measured table for 152 like the emphasis-mark one for 150 → 151. Check on
your own pages before relying on it.

CSS

Only two new properties, neither related to Japanese typography
(row-rule-visibility-items, window-drag).

Some features moved from experimental to on-by-default:

Feature 151 152
CSSAlphaColorFunction experimental default
CSSPseudoElementBackdrop (::backdrop) experimental default
CSSPseudoElementViewTransitions test default
CompositeClipPathAnimation experimental default

Also on by default

Shadow DOM (ShadowRootReferenceTarget, ShadowRootSlotAssignment), storage
access (RequestStorageAccessFor), the Range API (OpaqueRange,
LegacyAbstractRange, RangeBoundaryFastPath), audio selection in screen capture
(GetDisplayMediaAudioSelection), the streaming sanitizer, and others — 43 in
total
became default in 152.

Migration note — flags that disappeared

29 flags were removed in 152. 25 of them were already default in 151,
which means the behaviour became permanent and the switch is gone.

If you were using one as an escape hatch, it no longer works. Notable ones:

Removed flag State in 151
MulticolColumnWrapping default
OffMainThreadCSSPaint default
PageRevealEvent default
PaintTimingMixin default
SystemFallbackEmojiVSSupport default

The remaining four were not default (AudioContextPlayoutStats,
AutocorrectByDefault, HTMLImageElementActualNaturalSize,
WebAuthenticationImmediateGet), and ConnectionAllowlist was replaced by
ConnectionAllowlistEmbeddedEnforcement.

152 → 153 — Upstream reaches the end of the vertical line

The headline of this release is the fix for vertical lines that only filled part way.
We reported it upstream (crbug 542686223)
and Chromium fixed it.

The size of the diff: 39 additions (18 on by default, 14 experimental, 3 in development,
4 other), 59 removals, and 19 status changes, of which 10 were promoted to on by default.
CSS properties: 5 added, 1 removed.

Vertical lines now fill even when a closing bracket falls at the end (on by default)

In a vertical paragraph, a closing bracket at the end of a line could wrap the line at
roughly half its length
. A line with room for 35 characters held only 17, and with
text-align: justify the remainder was stretched, so the inter-character advance
doubled (16px to 33.5px)
. To a reader, that one line looks stretched out.

Chromium 153 introduces a feature named LineBreakerHanKerningEnd, and it is
on by default from the start. The name does not appear even once in the 152 tree.

Measured (one vertical paragraph of 35 characters, heights 544-564px in 1px steps,
software rendering):

Flag Characters on the first line (552-559px)
Default (nothing specified) 35
Explicitly enabled 35 (same as default)
Explicitly disabled 17

Disabling it explicitly brings back 17 characters. That is our evidence the feature
is what does the work. A control run with a non-existent flag name stayed at 35, which
shows the switch itself does not affect the result.

It does not happen in horizontal writing. It was specific to vertical writing, but
within vertical writing it was insensitive to conditions: changing the typeface
(serif, sans-serif, Noto Serif CJK JP, Noto Sans CJK JP), adding ruby, or using
line-height: normal all reproduced it. Of 13 configurations, 8 exhibited it, and all
are resolved in 153.

Hanging punctuation is still not usable in this release

hanging-punctuation, which hangs a period or comma past the end of a line, has had a
CSS property since 149, but its implementation flag has stayed at test through
149, 150, 151, 152 and 153 - five releases. CSS.supports() returns true while line
layout does not change. Using it for feature detection will mislead you. See
"How to read this document" at the top.

Ruby overhang (CSSRubyOverhang) and emphasis marks routed through ruby
(TextEmphasisAsRuby) remain on by default as they have been since 151. Nothing
changed for them in this release.

Autocorrection now follows what the HTML says (on by default)

The HTML autocorrect attribute is now reflected to the platform input method.
Autocorrection is on by default and is forced off for URL, email and password
inputs (and for controls belonging to a form owner with autocorrect=off). The
specification is in the
HTML Standard.

This does not change Japanese input itself. Read it as: for forms with fields where
autocorrection gets in the way, such as names and addresses, autocorrect=off now takes
effect.

Camera and microphone permission can sit inside the page (on by default)

Two HTML elements were added: <camera> and <microphone>. Controls that request
permission to use the camera or microphone can now be embedded directly in the page
rather than appearing only as a browser dialog.

XML parsing moved to a Rust implementation (on by default)

Parsing XML through the JavaScript DOMParser, and responseXML on XMLHttpRequest,
now use an XML parser written in Rust. The switch is limited to paths where XSLT
processing is known not to be required. For work that handles a lot of XML, such as
EPUB, this bears on the robustness of parsing.

CSS properties added

Property State Note
text-decoration-inset Experimental Insets the position of decorations such as underlines
overscroll-container-type Experimental Handling of scrolling past the edge
max-content-sizing In development The property parses, but it does not reach rendering

The two names beginning with -internal- are for browser internals and are not usable
from a page. -internal-overscroll-area was removed and replaced by
-internal-overscroll-container.

About the 59 removals

Most of the 59 removals (48 of them) are switches for behaviour that was already on by
default
. They read as clean-up of switches that were no longer needed once the
behaviour had settled. No functionality was lost.

The way this diff was taken, and how items were selected for inclusion, is described in
"Sources, and how this diff was taken" at the end. Guessing meaning from a feature name
introduces errors, so items whose implementation we could not confirm are not listed
here
. Of the 10 features promoted to on by default, 3 are covered above; the rest were
either unconfirmed or do not affect what a page displays.


154 → 155 — A fix for lines after ruby shifting up, and margin-trim

For Japanese typesetting, two upstream changes to the ruby annotation space (the room ruby needs
outside the line) arrived.
One works by default (the fix for lines after ruby shifting up); the
other, inside multi-column containers, is only behind an experimental flag.

Scale of the change: 25 Blink features became enabled by default (6 promoted from experimental and
similar, 19 newly added already enabled), 24 were removed (20 of them flags that were already enabled and
became permanent), 1 was taken out of the defaults, and 18 were newly added as experimental or similar.
No user-writable CSS property was added or removed (3 internal ones were added).

Lines after ruby no longer shift up (upstream fix)

When negative margins on the element, a preceding sibling or a child (for example from a
pseudo-element) collapsed to a negative value, the ruby annotation space could become negative, and
following lines without ruby then shifted up. The annotation space
is now never smaller than the padding (upstream commit 46d20dbfa5c05).

Ruby annotation space inside multi-column containers — only behind an experimental flag (no change by default)

A change that makes children of balanced multi-column containers (column-fill: balance) pass the
block-end ruby annotation space to the next block was added (upstream commit 4226ea59b9645). The
change is only behind the experimental flag AnnotationSpaceForMultiCol, which is off by default
in 155. BlinkGTK does not turn this flag on, so the default layout does not change.

The line height of ::first-line is computed as before the FirstLineTextMetrics flag

The calculation behind this flag, enabled by default up to 154, was turned off; the line height is
computed as in old Blink and WebKit. The CSS specification was
revised to match old Blink and WebKit, so this is not a regression (upstream commit d726ab7f7fc2d).

margin-trim and text-decoration-skip-spaces are available (enabled by default)

Features from 151 became permanent (no behavior change)

Placing emphasis marks with the same mechanism as ruby, and the fix for moving the caret up and down
in lines with ruby, were enabled by default since 151. In 155 their flags were removed and they became
permanent. The removal of flags such as text-indent and tab-size calculations is likewise the
permanent form of what was already enabled in 154.

Not measured

The vertical line-breaking measurement from the 154 chapter (42 points at heights 544-564px and 13
variants) was repeated on the released 1.2.4-build2, with results identical to 154 (1.2.3-build4)
(2026-10-11). The other items are based on the upstream commits and source, not on measurement.

153 → 154 — Vertical line breaking holds; XML parsing goes back to the older parser

For Japanese typesetting, the main news is what did not change. The line-end fix from
153 carries over, and ruby, emphasis marks and hanging punctuation are in the same state
as in 153.

In numbers: 27 features added (10 on by default / 10 experimental / 4 in development /
3 other), 25 removed, and 10 changed state (6 promoted to on by default, 3 no longer on by
default). The set of CSS properties is unchanged (824).

Vertical line breaking matches 153 (measured)

We measured 154 with the same harness used for 153: one vertical paragraph of 35
characters, heights 544–564px in 1px steps, software rendering.

What we measured 154 153
Characters on the first line at 544–551px (without / with an inline box) 33 33
Characters on the first line at 552–564px (without / with an inline box) 35 35
13 variants (ending in a full stop, text-spacing-trim, ruby, four typefaces, …) all match 153 (baseline)

All 42 points of the band sweep and all 13 variants match the 153 values. The line-end
problem fixed in 153 — a line stopping halfway because of a line-end prohibition — has not
come back in 154.

This covers what the harness measures. We did not run the engine's full layout test suite.

text-box-trim now works on inline elements (on by default)

text-box-trim removes the font-derived space above and below a line. Until now it only
applied to block elements. From 154, setting it on an inline element such as <span>
also trims that element's top and bottom.

If a page does not set text-box-trim on inline elements, nothing changes. Pages that
do will look different from 154.

XML parsing is back on the older parser

The Rust XML parser that 153 used for DOMParser and XMLHttpRequest's responseXML
is not used by default in 154 (its state went back from stable to experimental).
Parsing uses the same implementation as before 153.

A reader that loads an EPUB's OPF or table of contents through DOMParser therefore gets
a different parser in 153 and 154. If parsing results seemed to change in 153, they should
be back to the earlier behaviour in 154.

Popovers and dialogs close correctly on tap (on by default)

Closing a popover or dialog by tapping outside it (light dismiss) is now triggered by
click instead of pointerdown / pointerup. This addresses cases where touch input
failed to close them.

Video captions get a settings button (on by default)

The standard <video> controls gain a button that opens caption display settings. Caption
boxes are also sized and placed by the caption's own position alignment (WebVTT) rather
than by text-align.

Features that work only when a page asks for them (defaults unchanged)

Feature How it is triggered
Sizing an iframe to its content Only when the parent sets frame-sizing and the child page has <meta name="responsive-embedded-sizing">
Running scripts through setHTMLUnsafe() Only when runScripts: true is passed; otherwise scripts still do not run
Treating scroll markers as tabs or links Only when scroll-marker-group is followed by tabs or links (e.g. scroll-marker-group: after tabs)

Hanging punctuation is still not usable

The implementation flag for hanging-punctuation has been test for six versions in a
row, 149 through 154
. CSS.supports() returns true, but line layout does not change.

About the 25 removals

21 of the 25 removals are switches for behaviour that was already on by default.
Column rules (CSSGapDecoration) is one of them: the 31 places that checked the switch in
153 are gone in 154, and the feature is simply always on. No CSS properties were removed,
so nothing was lost.

Guessing meaning from a name introduces errors, so items whose implementation we could
not confirm are not listed here
. Of the 6 features promoted to on by default, 5 are
covered above.


Where Japanese typography stands — the eight versions at a glance

Given that BlinkGTK is used mainly for Japanese vertical-writing e-books, here are the
relevant items alone. A dash means the item did not exist in that version.

Item 147 148 149 150 151 152 153 154
Vertical lines fill at the line end — — — — — — default default
Ruby overhang (ruby-overhang) exp. exp. exp. exp. default default default default
Emphasis marks via ruby path — — — — default default default default
Ruby placement reimplemented — — — — — default default default
tab-size in a ruby base — — — — — default default default
text-autospace ignores ruby — — — — default default default default
Break after space before open tag — — — — default default default default
Annotation space on start — — — — exp. default default default
text-box-trim on inline elements — — — — — — — default
text-box-trim in nested lists — — — default default default default default
Full-width space offset mapping fix — — — default default default default default
Caret movement across ruby lines — — default default default default default default
Underlines skip descenders exp. default default default default default default default
Hanging punctuation — — property only (in dev.) same same same same same
Vertical multi-column fragmentation (BlinkGTK) — — — exp. exp. exp. exp. exp.

Two things follow.

First, ruby and emphasis marks advanced sharply in 151. ruby-overhang, held in
experimental status for four versions, became the default, and the emphasis mark
implementation was reorganised. If you are building a vertical-writing reader, a
151-based BlinkGTK is distinctly worth having.

Second, hanging punctuation has not arrived. The property was provided in 149, but the
implementation is still in development as of 154. Full JLReq conformance needs this one
move, and BlinkGTK continues to track it.

The last row is a feature upstream Chromium does not have — fragmentation for multi-column
layout in vertical writing mode, which BlinkGTK adds itself. Receiving from Chromium is
not the whole story; where something is missing, we fill it in.


Sources, and how this diff was taken

To keep speculation out, everything here was extracted mechanically from the engine source
trees. Anyone can reproduce it.

What we read File
Feature flags and their default state third_party/blink/renderer/platform/runtime_enabled_features.json5
The CSS property list third_party/blink/renderer/core/css/css_properties.json5

For 151 we went further and checked what a BlinkGTK build actually does. Upstream may
declare a feature stable while the final default still depends on build configuration.
The table below is read from the generated code (runtime_enabled_features.cc).

Feature Default in the BlinkGTK 151 build
Ruby overhang (CSSRubyOverhang) on
Emphasis marks via ruby path (TextEmphasisAsRuby) on
text-autospace ignores ruby annotations on
Break after space before open tag on
Hanging punctuation (CSSHangingPunctuation) off
Vertical multi-column fragmentation (BlinkGTK) off (opt-in)

We did the same for 153. LineBreakerHanKerningEnd is declared stable upstream, but
reading a declaration does not tell you whether it is doing any work. So we measured
again with the flag explicitly disabled at startup, and the count of characters on a
line fell from 35 back to 17. A control run with a non-existent flag name stayed at 35.
That is behaviour, not a declaration, showing this flag produces the result.

For 154 we re-measured line breaking with the same harness as 153. All 42 points of the
band sweep and all 13 variants match the 153 values; that measurement is the basis for
"vertical line breaking matches 153".

The prose above matches these measurements. We say hanging punctuation is unusable
because it is off in the actual build, not merely by upstream declaration.

For each version we parsed these two files into a feature-name → state map and diffed
adjacent versions. Every count quoted above — newly-default, added, removed — is an actual
figure from that diff.

Inferring meaning from a feature name invites error, so items we could not confirm are
not in this document
. That is why the counts exceed the number of items described.