Skip to content

Replace node-sass with sass, keeping extend - #12510

Closed
sabernhardt wants to merge 33 commits into
WordPress:trunkfrom
sabernhardt:replace-node-sass
Closed

sabernhardt wants to merge 33 commits into
WordPress:trunkfrom
sabernhardt:replace-node-sass

Conversation

@sabernhardt

Copy link
Copy Markdown

Co-authored by @desrosj

  • Replaces node-sass with sass in package, and updates the build scripts.
  • Replaces lighten(), darken(), and mix() with the previously computed color values.
  • Creates a new mixin for non-latin fonts so the Sass can still use @extend for 76 of the 81 selectors in style.css (and style-rtl.css) and 30 of 33 selectors in style-editor.css.
  • Adds the remaining selectors below their related rulesets with the new mixin.
  • Moves comments—or changes their syntax to //—so they do not print in an unrelated place, such as
    .main-navigation {
      /* Un-style buttons */
    }
    

Trac 63013

Use of AI Tools

This is built on #12156, which involved Claude and Copilot, but I did not use AI in addition to that.


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

desrosj and others added 29 commits June 11, 2026 11:25
@github-actions

github-actions Bot commented Jul 14, 2026 •

Copy link
Copy Markdown

The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props desrosj, sabernhardt, wildworks, rejaulalomkhan.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

@sabernhardt

Copy link
Copy Markdown
Author

GitHub Desktop told me the compiled stylesheets changed line endings to CRLF, but I saw them as LF in my file editor. I edited the .scss files in the browser, so they should have the correct line endings.

Comment on lines +127 to +133
@mixin non-latin-fonts() {
@each $lang, $font__fallback in $font__fallbacks {
&:lang(#{$lang}) {
font-family: unquote( $font__fallback );
}
}
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could still be replaced by the language simplification and grouping, but that would fit ticket 47925 better.

Suggested change
@mixin non-latin-fonts() {
@each $lang, $font__fallback in $font__fallbacks {
&:lang(#{$lang}) {
font-family: unquote( $font__fallback );
}
}
}
@mixin non-latin-fonts() {
// Arabic
&:is(:lang(ar),:lang(ary),:lang(azb),:lang(ckb),:lang(fa),:lang(haz),:lang(ps)) {
font-family: Tahoma, Arial, sans-serif;
}
// Cyrillic
&:is(:lang(be),:lang(bg),:lang(kk),:lang(mk),:lang(mn),:lang(ru),:lang(sah),:lang(sr),:lang(tt),:lang(uk)) {
font-family: "Helvetica Neue", Helvetica, "Segoe UI", Arial, sans-serif;
}
// Chinese (Hong Kong)
&:lang(zh-HK) {
font-family: -apple-system, BlinkMacSystemFont, "PingFang HK", "Helvetica Neue", "Microsoft YaHei New", STHeiti Light, sans-serif;
}
// Chinese (Taiwan)
&:lang(zh-TW) {
font-family: -apple-system, BlinkMacSystemFont, "PingFang TC", "Helvetica Neue", "Microsoft YaHei New", STHeiti Light, sans-serif;
}
// Chinese (China)
&:lang(zh-CN) {
font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", "Microsoft YaHei New", STHeiti Light, sans-serif;
}
// Devanagari and Gujarati
&:is(:lang(bn),:lang(gu),:lang(hi),:lang(mr),:lang(ne)) {
font-family: Arial, sans-serif;
}
// Greek
&:lang(el) {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
// Hebrew
&:lang(he) {
font-family: "Arial Hebrew", Arial, sans-serif;
}
// Japanese
&:lang(ja) {
font-family: -apple-system, BlinkMacSystemFont, "Hiragino Sans", Meiryo, "Helvetica Neue", sans-serif;
}
// Korean
&:lang(ko) {
font-family: "Apple SD Gothic Neo", "Malgun Gothic", "Nanum Gothic", Dotum, sans-serif;
}
// Thai
&:lang(th) {
font-family: "Sukhumvit Set", "Helvetica Neue", helvetica, arial, sans-serif;
}
// Vietnamese
&:lang(vi) {
font-family: "Libre Franklin", sans-serif;
}
}

}

h2 {
@include non-latin-fonts();

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The non-latin fonts do not work correctly in the editor since it started using the iframe, because the iframe lacks the lang attribute, but I added the mixin for H2 headings in Cover blocks as well as the citation in a floating Pullquote block anyway.

.site-header.featured-image .entry-meta,
.site-header.featured-image .entry-title,
.site-header.featured-image#masthead .site-title a {
.site-header.featured-image .entry-title, .site-header.featured-image#masthead .site-title a {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some selectors are not on their own line, but that is quite minor.

However, if it helps, the other PR has notes for changes to the postcss.config.js file.

@t-hamano

Copy link
Copy Markdown
Contributor

I've refreshed this PR and bumped the Node version to 24.

Co-Authored-By: Claude <noreply@anthropic.com>
@t-hamano

t-hamano commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

As a minor improvement, I added the devEngines field, similar to Twenty Twenty-One.

@t-hamano t-hamano left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ran a thorough visual regression test with the help of AI, comparing the front end with the current trunk CSS and this PR's CSS. All 310 screenshots matched pixel for pixel, so this PR should not introduce any visual regressions.

Test environment
  • WordPress 7.2-alpha-64309 (PHP 8.3 built-in server + SQLite Database Integration)
  • Chromium (Playwright), deviceScaleFactor: 1, transitions and animations disabled, full-page screenshots
  • Content: Theme Unit Test data (themeunittestdata.wordpress.xml)
  • Primary menu with a submenu, Social Links menu
  • Footer widgets: Search, Recent Posts, Recent Comments, Archives, Categories, Meta, Tag Cloud, Calendar, Pages
  • Local featured images (horizontal and vertical) on several posts
  • External requests were blocked, so remote images in the test data were not loaded
  • Comparison: exact pixel match (no threshold)
Pages (38 pages × 375px / 800px / 1200px = 114 screenshots)
  • / (blog home)
  • /page/2/
  • /hello-world/ (featured image header)
  • /template-featured-image-vertical/
  • /template-comments/
  • /template-sticky/
  • /template-password-protected/
  • /markup-html-tags-and-formatting/
  • /markup-image-alignment/
  • /markup-text-alignment/
  • /block-image/
  • /block-button/
  • /block-cover/
  • /block-gallery/
  • /column-blocks/
  • /block-quotes/
  • /blocks-formatting/
  • /blocks-layout-elements/
  • /blocks-widgets/
  • /text-category-blocks/
  • /design-category-blocks/
  • /media-category-blocks/
  • /widgets-block-category/
  • /theme-block-category/
  • /wp-6-1-font-size-scale/
  • /wp-6-1-spacing-presets/
  • /post-format-chat/
  • /post-format-quote/
  • /post-format-gallery/
  • /edge-case-nested-and-mixed-lists/
  • /edge-case-many-tags/
  • /title-should-not-overflow-the-content-area/
  • /page-with-comments/
  • /page-markup-and-formatting/
  • /level-1/
  • /category/6-1/ (category archive)
  • /?s=template (search results)
  • /?p=99999999 (404)
Non-latin languages (8 pages × 12 languages × 375px / 1200px = 192 screenshots)

The lang attribute of the <html> element was changed for each language. For RTL languages, the text direction was also switched to RTL, so style-rtl.css was loaded.

Languages:

  • ar (RTL)
  • he (RTL)
  • fa-IR (RTL)
  • ja
  • zh-CN
  • zh-TW
  • ko
  • ru-RU
  • el
  • hi
  • th
  • vi

Pages:

  • /
  • /hello-world/
  • /template-comments/
  • /block-quotes/
  • /text-category-blocks/
  • /page-with-comments/
  • /?s=template
  • /?p=99999999
Print (4 pages × 1200px = 4 screenshots)

Rendered with the print media type emulated, so print.css was applied.

  • /
  • /hello-world/
  • /markup-html-tags-and-formatting/
  • /template-comments/
Not covered
  • Editor styles (style-editor.css)
  • Hover and focus states
  • Remote images from the test data
  • Actual non-latin fallback fonts: fonts such as Tahoma and Hiragino Sans are not installed in the test environment, so a missing :lang() rule might not show up in screenshots. I separately compared the compiled CSS rule by rule and confirmed that every :lang() selector in trunk also exists in this PR.

I believe this PR is ready to merge, but any additional feedback is welcome. Please let us know if there are any issues.

@rejaulalomkhan

Copy link
Copy Markdown
Member

Thanks for refreshing this, @t-hamano and @sabernhardt! Building on @t-hamano's front-end screenshots, I tested the parts listed there as "Not covered": the editor styles and hover/focus states.

Patch Testing Report

Patch tested: #12510 (head 64c7e80)

Environment

  • WordPress: 7.2-alpha-63166-src (wordpress-develop Docker environment)
  • PHP: 8.3.35
  • Server: nginx (wordpress-develop Docker environment)
  • Database: MySQL 8.4.11
  • Browser: Chromium 149 headless (Playwright 1.61.1), deviceScaleFactor: 1, reduced motion
  • OS: macOS
  • Theme: Twenty Nineteen
  • Build: Node 24.18.1, sass 1.101.0
  • MU Plugins: None activated
  • Plugins: None activated

Steps taken

  1. Ran npm ci and npm run build in the PR's twentynineteen folder → style.css, style-rtl.css, style-editor.css, style-editor-customizer.css and print.css are byte-identical to the committed files, and stay identical over 3 more builds.
  2. Created a post with headings 1–6, drop cap, inline formatting, lists, quotes (default and large), pullquote, fill and outline buttons, table, code, preformatted, verse, separators, columns, group, cover, latest posts, archives, categories and search, plus a primary menu with a submenu.
  3. Took screenshots with trunk's compiled CSS and with the PR's compiled CSS, comparing exact pixels:
    • the full block editor canvas (style-editor.css), 1280px wide;
    • rest, hover and keyboard focus of a content link, both buttons, the search button, the site title and post navigation, at 1280px and 375px;
    • the open submenu on hover, and the first 8 Tab stops from the top of the page at both widths.
  4. Ran trunk twice to rule out noise (54/54 identical), then a control with three deliberate CSS changes (editor h2 color, menu hover color, link focus outline) → exactly those 4 screenshots changed, so the comparison catches small differences.
  5. ✅ Patch is solving the problem: with the PR's CSS, all 54 screenshots match trunk pixel for pixel, including the editor canvas and every hover and focus state tested.

Expected result

  • Switching from node-sass to sass causes no visual change in the editor or in interactive states.

Additional Notes

  • Not from this PR, but "build": "run-p \"build:*\"" runs build:rtl in parallel with build:style, so rtlcss can read the old style.css. After changing $color__background-body and running npm run build once, style.css had the new color and style-rtl.css did not; a second build fixed it. Trunk has the same run-p setup. Twenty Twenty-One uses run-s; with "build": "run-s \"build:*\"" one build updates both files (about 4s instead of 2s). Since the PR already touches these scripts, it could switch to run-s, or that could be a follow-up.
  • The build prints Sass deprecation warnings (@import, / division, global built-in functions; 20 shown, 38 more omitted). They don't affect the output today; the module system migration could be a follow-up.
  • AI assistance: Claude Code was used to run the build and the screenshot comparison; results reviewed by me.

@t-hamano

Copy link
Copy Markdown
Contributor

Since 7.2 Beta 1 is scheduled to be released next week, I will commit this beforehand. If anyone finds any issues, please feel free to report them.

wporg-sync pushed a commit that referenced this pull request Oct 16, 2026
Twenty Nineteen now compiles its stylesheets with the actively maintained `sass` package instead of the deprecated `node-sass`, which allows the theme to move to Node.js 24.x without changing the compiled CSS output.

Developed in: #12510

Props adrianduffell, cyrusblake89, debarghyabanerjee, desrosj, karmatosed, rejaulalomkhan, sabernhardt, sainathpoojary, wildworks.

Fixes #63013.

git-svn-id: https://develop.svn.wordpress.org/trunk@64387 602fd350-edb4-49c9-b593-d223f7449a82
@github-actions

Copy link
Copy Markdown

A commit was made that fixes the Trac ticket referenced in the description of this pull request.

SVN changeset: 64387
GitHub commit: 1d54e2a

This PR will be closed, but please confirm the accuracy of this and reopen if there is more work to be done.

@github-actions github-actions Bot closed this Oct 16, 2026
wporg-sync pushed a commit to WordPress/WordPress that referenced this pull request Oct 16, 2026
Twenty Nineteen now compiles its stylesheets with the actively maintained `sass` package instead of the deprecated `node-sass`, which allows the theme to move to Node.js 24.x without changing the compiled CSS output.

Developed in: WordPress/wordpress-develop#12510

Props adrianduffell, cyrusblake89, debarghyabanerjee, desrosj, karmatosed, rejaulalomkhan, sabernhardt, sainathpoojary, wildworks.

Fixes #63013.
Built from https://develop.svn.wordpress.org/trunk@64387


git-svn-id: http://core.svn.wordpress.org/trunk@63537 1a063a9b-81f0-0310-95a4-ce76da25c4cd
@sabernhardt
sabernhardt deleted the replace-node-sass branch October 17, 2026 02:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants