Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option for rendering SVG filters when the filter doesn't appear in block markup #53662

Open
ajlende opened this issue Aug 15, 2023 · 1 comment
Labels
Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json [Package] Block editor /packages/block-editor [Type] Enhancement A suggestion for improvement.

Comments

@ajlende
Copy link
Contributor

ajlende commented Aug 15, 2023

Problem

Trac: https://core.trac.wordpress.org/ticket/59017

Prior to WP 6.3 duotone filters from global styles were always rendered on every page that required global styles. In 6.3 optimizations were added to selectively render duotone filters that appeared in block markup to save a few kilobytes of SVGs that were often never used. This was one of the most asked for issues in Gutenberg, #38299.

However, some sites have already been relying on these default styles and SVG filters within their external CSS stylesheets for things that cannot be done in the editor or theme.json.

The "global styles" feature was, conceptually, just a global stylesheet integrated with editor settings for adjusting that stylesheet. It even included a set of default styles for patterns so that patterns could be used across themes. Using this conceptual framework, one would expect all styles to always be available.

Gutenberg is has been working towards removing CSS entirely from themes since the site editor was introduced. Twenty Twenty Three was the first core theme proving that a variety of themes could be built without additional CSS. And there are other efforts to do more conditional rendering of styles such as #45198 for block styles.

Existing Solutions

There are a couple different solutions for duotone filters at the time being that don't require a Gutenberg change. Each solution depends on how you've used the duotone filters on your page.

Add static SVGs to the page

<?php
function mytheme_render_duotone_svg_filters() {
	// Replace with the output from a page using the filters. SVGs for filters not used in the CSS can be removed.
	echo '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 0 0" width="0" height="0" focusable="false" role="none" style="visibility: hidden; position: absolute; left: -9999px; overflow: hidden;" ><defs><filter id="wp-duotone-dark-grayscale"><feColorMatrix color-interpolation-filters="sRGB" type="matrix" values=" .299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 " /><feComponentTransfer color-interpolation-filters="sRGB" ><feFuncR type="table" tableValues="0 0.49803921568627" /><feFuncG type="table" tableValues="0 0.49803921568627" /><feFuncB type="table" tableValues="0 0.49803921568627" /><feFuncA type="table" tableValues="1 1" /></feComponentTransfer><feComposite in2="SourceGraphic" operator="in" /></filter></defs></svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 0 0" width="0" height="0" focusable="false" role="none" style="visibility: hidden; position: absolute; left: -9999px; overflow: hidden;" ><defs><filter id="wp-duotone-grayscale"><feColorMatrix color-interpolation-filters="sRGB" type="matrix" values=" .299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 " /><feComponentTransfer color-interpolation-filters="sRGB" ><feFuncR type="table" tableValues="0 1" /><feFuncG type="table" tableValues="0 1" /><feFuncB type="table" tableValues="0 1" /><feFuncA type="table" tableValues="1 1" /></feComponentTransfer><feComposite in2="SourceGraphic" operator="in" /></filter></defs></svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 0 0" width="0" height="0" focusable="false" role="none" style="visibility: hidden; position: absolute; left: -9999px; overflow: hidden;" ><defs><filter id="wp-duotone-purple-yellow"><feColorMatrix color-interpolation-filters="sRGB" type="matrix" values=" .299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 " /><feComponentTransfer color-interpolation-filters="sRGB" ><feFuncR type="table" tableValues="0.54901960784314 0.98823529411765" /><feFuncG type="table" tableValues="0 1" /><feFuncB type="table" tableValues="0.71764705882353 0.25490196078431" /><feFuncA type="table" tableValues="1 1" /></feComponentTransfer><feComposite in2="SourceGraphic" operator="in" /></filter></defs></svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 0 0" width="0" height="0" focusable="false" role="none" style="visibility: hidden; position: absolute; left: -9999px; overflow: hidden;" ><defs><filter id="wp-duotone-blue-red"><feColorMatrix color-interpolation-filters="sRGB" type="matrix" values=" .299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 " /><feComponentTransfer color-interpolation-filters="sRGB" ><feFuncR type="table" tableValues="0 1" /><feFuncG type="table" tableValues="0 0.27843137254902" /><feFuncB type="table" tableValues="0.5921568627451 0.27843137254902" /><feFuncA type="table" tableValues="1 1" /></feComponentTransfer><feComposite in2="SourceGraphic" operator="in" /></filter></defs></svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 0 0" width="0" height="0" focusable="false" role="none" style="visibility: hidden; position: absolute; left: -9999px; overflow: hidden;" ><defs><filter id="wp-duotone-midnight"><feColorMatrix color-interpolation-filters="sRGB" type="matrix" values=" .299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 " /><feComponentTransfer color-interpolation-filters="sRGB" ><feFuncR type="table" tableValues="0 0" /><feFuncG type="table" tableValues="0 0.64705882352941" /><feFuncB type="table" tableValues="0 1" /><feFuncA type="table" tableValues="1 1" /></feComponentTransfer><feComposite in2="SourceGraphic" operator="in" /></filter></defs></svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 0 0" width="0" height="0" focusable="false" role="none" style="visibility: hidden; position: absolute; left: -9999px; overflow: hidden;" ><defs><filter id="wp-duotone-magenta-yellow"><feColorMatrix color-interpolation-filters="sRGB" type="matrix" values=" .299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 " /><feComponentTransfer color-interpolation-filters="sRGB" ><feFuncR type="table" tableValues="0.78039215686275 1" /><feFuncG type="table" tableValues="0 0.94901960784314" /><feFuncB type="table" tableValues="0.35294117647059 0.47058823529412" /><feFuncA type="table" tableValues="1 1" /></feComponentTransfer><feComposite in2="SourceGraphic" operator="in" /></filter></defs></svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 0 0" width="0" height="0" focusable="false" role="none" style="visibility: hidden; position: absolute; left: -9999px; overflow: hidden;" ><defs><filter id="wp-duotone-purple-green"><feColorMatrix color-interpolation-filters="sRGB" type="matrix" values=" .299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 " /><feComponentTransfer color-interpolation-filters="sRGB" ><feFuncR type="table" tableValues="0.65098039215686 0.40392156862745" /><feFuncG type="table" tableValues="0 1" /><feFuncB type="table" tableValues="0.44705882352941 0.4" /><feFuncA type="table" tableValues="1 1" /></feComponentTransfer><feComposite in2="SourceGraphic" operator="in" /></filter></defs></svg><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 0 0" width="0" height="0" focusable="false" role="none" style="visibility: hidden; position: absolute; left: -9999px; overflow: hidden;" ><defs><filter id="wp-duotone-blue-orange"><feColorMatrix color-interpolation-filters="sRGB" type="matrix" values=" .299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 .299 .587 .114 0 0 " /><feComponentTransfer color-interpolation-filters="sRGB" ><feFuncR type="table" tableValues="0.098039215686275 1" /><feFuncG type="table" tableValues="0 0.66274509803922" /><feFuncB type="table" tableValues="0.84705882352941 0.41960784313725" /><feFuncA type="table" tableValues="1 1" /></feComponentTransfer><feComposite in2="SourceGraphic" operator="in" /></filter></defs></svg>';
}
add_action( 'wp_body_open', 'mytheme_render_duotone_svg_filters' );
add_action( 'in_admin_header', 'mytheme_render_duotone_svg_filters' );

With this, all of the SVG filters can be accessed in CSS with using their SVG id as a url: filter: url('#wp-duotone-id');.

If you were using the CSS custom properties, those will need to be included in your stylesheet.

body {
	--wp--preset--duotone--dark-grayscale: url('#wp-duotone-dark-grayscale');
	--wp--preset--duotone--grayscale: url('#wp-duotone-grayscale');
	--wp--preset--duotone--purple-yellow: url('#wp-duotone-purple-yellow');
	--wp--preset--duotone--blue-red: url('#wp-duotone-blue-red');
	--wp--preset--duotone--midnight: url('#wp-duotone-midnight');
	--wp--preset--duotone--magenta-yellow: url('#wp-duotone-magenta-yellow');
	--wp--preset--duotone--purple-green: url('#wp-duotone-purple-green');
	--wp--preset--duotone--blue-orange: url('#wp-duotone-blue-orange');
}

Re-add the old deprecated duotone filter.

If you aren't concerned about deprecation warnings, instead of copying the filters to the page, you can just run the old duotone hooks directly. This has the benefit that updates to the theme.json will be reflected in the rendered output.

<?php
// Render all duotone SVG filters.
add_action( 'wp_body_open', 'wp_global_styles_render_svg_filters' );
add_action( 'in_admin_header', 'wp_global_styles_render_svg_filters' );

Possible Solutions

If global styles continues to remove styles unused by blocks, we may just want to document that and leave global styles out of custom stylesheets entirely instead of the solutions listed below.

The trac ticket mentions two possible solutions for forcing rendering SVG filters that I've tried to provide more concrete examples for here.

1. Add an option in theme.json to always render certain options

I think this option most closely matches how other global styles features work, and would most likely be the natural place to look for such a setting.

Depending on if other presets become optimized out for performance like duotone, this common interface could

The drawbacks of this approach is that you'll still have some pages that don't use SVG filters that have the global filters.

It could take on a number of shapes. Here are two possible examples.

Adding a property to each preset

{
	"settings": {
		"color": {
			"duotone": [
				{
					"name": "Grayscale",
					"colors": [ "#000", "#FFF" ],
					"slug": "grayscale",
					"includeForCSS": true
				}
			]
		}
	}
}

Adding an array of preset identifiers

{
	"settings": {
		"color": {
			"duotone": [
				{
					"name": "Grayscale",
					"colors": [ "#000", "#FFF" ],
					"slug": "grayscale"
				}
			],
			"duotoneForCSS": [ "grayscale" ],
		}
	}
}

2. Add a filter to force rendering of certain filters

Instead of adding settings to theme.json, we could take the filter route.

This is much more hidden than the theme.json option. And I don't think that all theme authors would be comfortable with this approach if they're simply working with the theme.json file. But it is much more flexible, as you could choose to use other conditionals such as is_page(), is_singular(), etc..

function mytheme_should_use_duotone_preset( $is_included, $preset ) {
	return $is_included || ( isset( $preset['slug'] ) && $preset['slug'] === 'grayscale' ) )
}
add_filter( 'wp_include_duotone_preset', 'mytheme_should_use_duotone_preset', 10, 2 );
@ajlende ajlende added [Package] Block editor /packages/block-editor Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json labels Aug 15, 2023
@jordesign jordesign added the [Type] Enhancement A suggestion for improvement. label Aug 30, 2023
@joemcgill
Copy link
Member

I've punted this issue from the WP 6.4 milestone, so please update that tracking ticket once work on this has started. See: https://core.trac.wordpress.org/ticket/59017#comment:23

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json [Package] Block editor /packages/block-editor [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

No branches or pull requests

3 participants