Post Featured Image: Add border support applied to inner img
Related:
- https://github.com/WordPress/gutenberg/pull/42765
What?
Adopts border block support for the Post Featured Image block and applies those classes/styles to the inner img element.
Why?
This is a step towards reducing the gap between what you can control with the Image block and the Post Featured Image block. In terms of the bigger picture, it is part of providing more consistent design tools across blocks.
How?
- Opts into border block support
- Skips serialization of the border block support so classes and styles can be applied on the inner
imginstead of the block wrapper - Uses new "feature-level" selector flag to allow Global Styles and Theme.json to generate their styles targeting the inner image
- Leverages the style engine to generate the border classes and styles to be applied to the block during server-side rendering.
- Borders are also applied to the block's placeholder
Testing Instructions
- Edit a post, add a Post Featured Image block, and select it.
- Trial configuring various combinations of borders on the block. The borders should display correctly.
- Save and confirm the borders display on the frontend.
- Back in the block editor, clear your block's border styles and save.
- Switch to the site editor and navigate to Global Styles > Blocks > Post Featured Image > Layouts.
- Try configuring the border options there and check they are reflected in the preview.
- Save the global styles and confirm they are applied in both the block editor and frontend.
- Reset your global styles and add a default border for the Post Featured Image block in your theme.json
- Confirm the theme.json border works appropriately.
Example snippet
"styles": {
"blocks": {
"core/post-featured-image": {
"border": {
"color": "fuchsia",
"width": "0.5em",
"style": "solid",
"radius": "50px"
}
}
},
},
Screenshots or screencast
Post Editor - With Image
Post Editor - Placeholders
Site / Template Editor
This should be pretty close to reviewable, I've run out of time today to test fully but will do that later this week.
Size Change: +1.65 kB (0%)
Total Size: 1.24 MB
| Filename | Size | Change | |
|---|---|---|---|
build/block-directory/index.min.js |
7.06 kB | +5 B (0%) | |
build/block-editor/index.min.js |
159 kB | +32 B (0%) | |
build/block-library/blocks/audio/style-rtl.css |
122 B | +19 B (+18%) | ⚠️ |
build/block-library/blocks/audio/style.css |
122 B | +19 B (+18%) | ⚠️ |
build/block-library/blocks/image/editor-rtl.css |
870 B | +134 B (+18%) | ⚠️ |
build/block-library/blocks/image/editor.css |
873 B | +136 B (+18%) | ⚠️ |
build/block-library/blocks/paragraph/editor-rtl.css |
174 B | +17 B (+11%) | ⚠️ |
build/block-library/blocks/paragraph/editor.css |
174 B | +17 B (+11%) | ⚠️ |
build/block-library/blocks/post-featured-image/editor-rtl.css |
507 B | +130 B (+34%) | 🚨 |
build/block-library/blocks/post-featured-image/editor.css |
505 B | +128 B (+34%) | 🚨 |
build/block-library/blocks/post-featured-image/style-rtl.css |
166 B | +13 B (+8%) | 🔍 |
build/block-library/blocks/post-featured-image/style.css |
166 B | +13 B (+8%) | 🔍 |
build/block-library/editor-rtl.css |
11 kB | +214 B (+2%) | |
build/block-library/editor.css |
11 kB | +211 B (+2%) | |
build/block-library/index.min.js |
186 kB | +443 B (0%) | |
build/block-library/style-rtl.css |
11.8 kB | +8 B (0%) | |
build/block-library/style.css |
11.8 kB | +6 B (0%) | |
build/blocks/index.min.js |
49.5 kB | +3 B (0%) | |
build/components/index.min.js |
198 kB | +22 B (0%) | |
build/components/style-rtl.css |
11.6 kB | +41 B (0%) | |
build/components/style.css |
11.7 kB | +42 B (0%) | |
build/core-data/index.min.js |
15.4 kB | -2 B (0%) | |
build/edit-site/index.min.js |
57.3 kB | +4 B (0%) | |
build/edit-site/style-rtl.css |
8.22 kB | -1 B (0%) | |
build/edit-site/style.css |
8.2 kB | -2 B (0%) | |
build/edit-widgets/index.min.js |
16.5 kB | -6 B (0%) |
ℹ️ View Unchanged
| Filename | Size |
|---|---|
build/a11y/index.min.js |
982 B |
build/annotations/index.min.js |
2.76 kB |
build/api-fetch/index.min.js |
2.26 kB |
build/autop/index.min.js |
2.14 kB |
build/blob/index.min.js |
475 B |
build/block-directory/style-rtl.css |
990 B |
build/block-directory/style.css |
991 B |
build/block-editor/default-editor-styles-rtl.css |
378 B |
build/block-editor/default-editor-styles.css |
378 B |
build/block-editor/style-rtl.css |
15.1 kB |
build/block-editor/style.css |
15.1 kB |
build/block-library/blocks/archives/editor-rtl.css |
61 B |
build/block-library/blocks/archives/editor.css |
60 B |
build/block-library/blocks/archives/style-rtl.css |
65 B |
build/block-library/blocks/archives/style.css |
65 B |
build/block-library/blocks/audio/editor-rtl.css |
150 B |
build/block-library/blocks/audio/editor.css |
150 B |
build/block-library/blocks/audio/theme-rtl.css |
110 B |
build/block-library/blocks/audio/theme.css |
110 B |
build/block-library/blocks/avatar/editor-rtl.css |
116 B |
build/block-library/blocks/avatar/editor.css |
116 B |
build/block-library/blocks/avatar/style-rtl.css |
59 B |
build/block-library/blocks/avatar/style.css |
59 B |
build/block-library/blocks/block/editor-rtl.css |
161 B |
build/block-library/blocks/block/editor.css |
161 B |
build/block-library/blocks/button/editor-rtl.css |
441 B |
build/block-library/blocks/button/editor.css |
441 B |
build/block-library/blocks/button/style-rtl.css |
539 B |
build/block-library/blocks/button/style.css |
539 B |
build/block-library/blocks/buttons/editor-rtl.css |
292 B |
build/block-library/blocks/buttons/editor.css |
292 B |
build/block-library/blocks/buttons/style-rtl.css |
275 B |
build/block-library/blocks/buttons/style.css |
275 B |
build/block-library/blocks/calendar/style-rtl.css |
207 B |
build/block-library/blocks/calendar/style.css |
207 B |
build/block-library/blocks/categories/editor-rtl.css |
84 B |
build/block-library/blocks/categories/editor.css |
83 B |
build/block-library/blocks/categories/style-rtl.css |
79 B |
build/block-library/blocks/categories/style.css |
79 B |
build/block-library/blocks/code/style-rtl.css |
103 B |
build/block-library/blocks/code/style.css |
103 B |
build/block-library/blocks/code/theme-rtl.css |
124 B |
build/block-library/blocks/code/theme.css |
124 B |
build/block-library/blocks/columns/editor-rtl.css |
108 B |
build/block-library/blocks/columns/editor.css |
108 B |
build/block-library/blocks/columns/style-rtl.css |
406 B |
build/block-library/blocks/columns/style.css |
406 B |
build/block-library/blocks/comment-author-avatar/editor-rtl.css |
125 B |
build/block-library/blocks/comment-author-avatar/editor.css |
125 B |
build/block-library/blocks/comment-content/style-rtl.css |
92 B |
build/block-library/blocks/comment-content/style.css |
92 B |
build/block-library/blocks/comment-template/style-rtl.css |
187 B |
build/block-library/blocks/comment-template/style.css |
185 B |
build/block-library/blocks/comments-pagination-numbers/editor-rtl.css |
123 B |
build/block-library/blocks/comments-pagination-numbers/editor.css |
121 B |
build/block-library/blocks/comments-pagination/editor-rtl.css |
222 B |
build/block-library/blocks/comments-pagination/editor.css |
209 B |
build/block-library/blocks/comments-pagination/style-rtl.css |
235 B |
build/block-library/blocks/comments-pagination/style.css |
231 B |
build/block-library/blocks/comments-title/editor-rtl.css |
75 B |
build/block-library/blocks/comments-title/editor.css |
75 B |
build/block-library/blocks/comments/editor-rtl.css |
834 B |
build/block-library/blocks/comments/editor.css |
832 B |
build/block-library/blocks/comments/style-rtl.css |
632 B |
build/block-library/blocks/comments/style.css |
630 B |
build/block-library/blocks/cover/editor-rtl.css |
615 B |
build/block-library/blocks/cover/editor.css |
616 B |
build/block-library/blocks/cover/style-rtl.css |
1.55 kB |
build/block-library/blocks/cover/style.css |
1.55 kB |
build/block-library/blocks/embed/editor-rtl.css |
293 B |
build/block-library/blocks/embed/editor.css |
293 B |
build/block-library/blocks/embed/style-rtl.css |
410 B |
build/block-library/blocks/embed/style.css |
410 B |
build/block-library/blocks/embed/theme-rtl.css |
110 B |
build/block-library/blocks/embed/theme.css |
110 B |
build/block-library/blocks/file/editor-rtl.css |
300 B |
build/block-library/blocks/file/editor.css |
300 B |
build/block-library/blocks/file/style-rtl.css |
253 B |
build/block-library/blocks/file/style.css |
254 B |
build/block-library/blocks/file/view.min.js |
346 B |
build/block-library/blocks/freeform/editor-rtl.css |
2.44 kB |
build/block-library/blocks/freeform/editor.css |
2.44 kB |
build/block-library/blocks/gallery/editor-rtl.css |
948 B |
build/block-library/blocks/gallery/editor.css |
950 B |
build/block-library/blocks/gallery/style-rtl.css |
1.53 kB |
build/block-library/blocks/gallery/style.css |
1.53 kB |
build/block-library/blocks/gallery/theme-rtl.css |
108 B |
build/block-library/blocks/gallery/theme.css |
108 B |
build/block-library/blocks/group/editor-rtl.css |
412 B |
build/block-library/blocks/group/editor.css |
412 B |
build/block-library/blocks/group/style-rtl.css |
57 B |
build/block-library/blocks/group/style.css |
57 B |
build/block-library/blocks/group/theme-rtl.css |
78 B |
build/block-library/blocks/group/theme.css |
78 B |
build/block-library/blocks/heading/style-rtl.css |
76 B |
build/block-library/blocks/heading/style.css |
76 B |
build/block-library/blocks/html/editor-rtl.css |
327 B |
build/block-library/blocks/html/editor.css |
329 B |
build/block-library/blocks/image/style-rtl.css |
627 B |
build/block-library/blocks/image/style.css |
630 B |
build/block-library/blocks/image/theme-rtl.css |
110 B |
build/block-library/blocks/image/theme.css |
110 B |
build/block-library/blocks/latest-comments/style-rtl.css |
284 B |
build/block-library/blocks/latest-comments/style.css |
284 B |
build/block-library/blocks/latest-posts/editor-rtl.css |
213 B |
build/block-library/blocks/latest-posts/editor.css |
212 B |
build/block-library/blocks/latest-posts/style-rtl.css |
463 B |
build/block-library/blocks/latest-posts/style.css |
462 B |
build/block-library/blocks/list/style-rtl.css |
88 B |
build/block-library/blocks/list/style.css |
88 B |
build/block-library/blocks/media-text/editor-rtl.css |
266 B |
build/block-library/blocks/media-text/editor.css |
263 B |
build/block-library/blocks/media-text/style-rtl.css |
493 B |
build/block-library/blocks/media-text/style.css |
490 B |
build/block-library/blocks/more/editor-rtl.css |
431 B |
build/block-library/blocks/more/editor.css |
431 B |
build/block-library/blocks/navigation-link/editor-rtl.css |
705 B |
build/block-library/blocks/navigation-link/editor.css |
703 B |
build/block-library/blocks/navigation-link/style-rtl.css |
115 B |
build/block-library/blocks/navigation-link/style.css |
115 B |
build/block-library/blocks/navigation-submenu/editor-rtl.css |
296 B |
build/block-library/blocks/navigation-submenu/editor.css |
295 B |
build/block-library/blocks/navigation-submenu/view.min.js |
423 B |
build/block-library/blocks/navigation/editor-rtl.css |
2.03 kB |
build/block-library/blocks/navigation/editor.css |
2.04 kB |
build/block-library/blocks/navigation/style-rtl.css |
1.98 kB |
build/block-library/blocks/navigation/style.css |
1.97 kB |
build/block-library/blocks/navigation/view-modal.min.js |
2.78 kB |
build/block-library/blocks/navigation/view.min.js |
443 B |
build/block-library/blocks/nextpage/editor-rtl.css |
395 B |
build/block-library/blocks/nextpage/editor.css |
395 B |
build/block-library/blocks/page-list/editor-rtl.css |
363 B |
build/block-library/blocks/page-list/editor.css |
363 B |
build/block-library/blocks/page-list/style-rtl.css |
175 B |
build/block-library/blocks/page-list/style.css |
175 B |
build/block-library/blocks/paragraph/style-rtl.css |
260 B |
build/block-library/blocks/paragraph/style.css |
260 B |
build/block-library/blocks/post-author/style-rtl.css |
175 B |
build/block-library/blocks/post-author/style.css |
176 B |
build/block-library/blocks/post-comments-form/editor-rtl.css |
96 B |
build/block-library/blocks/post-comments-form/editor.css |
96 B |
build/block-library/blocks/post-comments-form/style-rtl.css |
493 B |
build/block-library/blocks/post-comments-form/style.css |
493 B |
build/block-library/blocks/post-excerpt/editor-rtl.css |
73 B |
build/block-library/blocks/post-excerpt/editor.css |
73 B |
build/block-library/blocks/post-excerpt/style-rtl.css |
69 B |
build/block-library/blocks/post-excerpt/style.css |
69 B |
build/block-library/blocks/post-template/editor-rtl.css |
99 B |
build/block-library/blocks/post-template/editor.css |
98 B |
build/block-library/blocks/post-template/style-rtl.css |
282 B |
build/block-library/blocks/post-template/style.css |
282 B |
build/block-library/blocks/post-terms/style-rtl.css |
73 B |
build/block-library/blocks/post-terms/style.css |
73 B |
build/block-library/blocks/post-title/style-rtl.css |
80 B |
build/block-library/blocks/post-title/style.css |
80 B |
build/block-library/blocks/preformatted/style-rtl.css |
103 B |
build/block-library/blocks/preformatted/style.css |
103 B |
build/block-library/blocks/pullquote/editor-rtl.css |
135 B |
build/block-library/blocks/pullquote/editor.css |
135 B |
build/block-library/blocks/pullquote/style-rtl.css |
326 B |
build/block-library/blocks/pullquote/style.css |
325 B |
build/block-library/blocks/pullquote/theme-rtl.css |
167 B |
build/block-library/blocks/pullquote/theme.css |
167 B |
build/block-library/blocks/query-pagination-numbers/editor-rtl.css |
122 B |
build/block-library/blocks/query-pagination-numbers/editor.css |
121 B |
build/block-library/blocks/query-pagination/editor-rtl.css |
221 B |
build/block-library/blocks/query-pagination/editor.css |
211 B |
build/block-library/blocks/query-pagination/style-rtl.css |
282 B |
build/block-library/blocks/query-pagination/style.css |
278 B |
build/block-library/blocks/query/editor-rtl.css |
439 B |
build/block-library/blocks/query/editor.css |
439 B |
build/block-library/blocks/quote/style-rtl.css |
213 B |
build/block-library/blocks/quote/style.css |
213 B |
build/block-library/blocks/quote/theme-rtl.css |
223 B |
build/block-library/blocks/quote/theme.css |
226 B |
build/block-library/blocks/read-more/style-rtl.css |
132 B |
build/block-library/blocks/read-more/style.css |
132 B |
build/block-library/blocks/rss/editor-rtl.css |
202 B |
build/block-library/blocks/rss/editor.css |
204 B |
build/block-library/blocks/rss/style-rtl.css |
289 B |
build/block-library/blocks/rss/style.css |
288 B |
build/block-library/blocks/search/editor-rtl.css |
165 B |
build/block-library/blocks/search/editor.css |
165 B |
build/block-library/blocks/search/style-rtl.css |
396 B |
build/block-library/blocks/search/style.css |
393 B |
build/block-library/blocks/search/theme-rtl.css |
114 B |
build/block-library/blocks/search/theme.css |
114 B |
build/block-library/blocks/separator/editor-rtl.css |
146 B |
build/block-library/blocks/separator/editor.css |
146 B |
build/block-library/blocks/separator/style-rtl.css |
233 B |
build/block-library/blocks/separator/style.css |
233 B |
build/block-library/blocks/separator/theme-rtl.css |
194 B |
build/block-library/blocks/separator/theme.css |
194 B |
build/block-library/blocks/shortcode/editor-rtl.css |
464 B |
build/block-library/blocks/shortcode/editor.css |
464 B |
build/block-library/blocks/site-logo/editor-rtl.css |
455 B |
build/block-library/blocks/site-logo/editor.css |
455 B |
build/block-library/blocks/site-logo/style-rtl.css |
192 B |
build/block-library/blocks/site-logo/style.css |
192 B |
build/block-library/blocks/site-tagline/editor-rtl.css |
86 B |
build/block-library/blocks/site-tagline/editor.css |
86 B |
build/block-library/blocks/site-title/editor-rtl.css |
84 B |
build/block-library/blocks/site-title/editor.css |
84 B |
build/block-library/blocks/social-link/editor-rtl.css |
184 B |
build/block-library/blocks/social-link/editor.css |
184 B |
build/block-library/blocks/social-links/editor-rtl.css |
674 B |
build/block-library/blocks/social-links/editor.css |
673 B |
build/block-library/blocks/social-links/style-rtl.css |
1.39 kB |
build/block-library/blocks/social-links/style.css |
1.38 kB |
build/block-library/blocks/spacer/editor-rtl.css |
322 B |
build/block-library/blocks/spacer/editor.css |
322 B |
build/block-library/blocks/spacer/style-rtl.css |
48 B |
build/block-library/blocks/spacer/style.css |
48 B |
build/block-library/blocks/table/editor-rtl.css |
494 B |
build/block-library/blocks/table/editor.css |
494 B |
build/block-library/blocks/table/style-rtl.css |
611 B |
build/block-library/blocks/table/style.css |
609 B |
build/block-library/blocks/table/theme-rtl.css |
175 B |
build/block-library/blocks/table/theme.css |
175 B |
build/block-library/blocks/tag-cloud/style-rtl.css |
239 B |
build/block-library/blocks/tag-cloud/style.css |
239 B |
build/block-library/blocks/template-part/editor-rtl.css |
235 B |
build/block-library/blocks/template-part/editor.css |
235 B |
build/block-library/blocks/template-part/theme-rtl.css |
101 B |
build/block-library/blocks/template-part/theme.css |
101 B |
build/block-library/blocks/text-columns/editor-rtl.css |
95 B |
build/block-library/blocks/text-columns/editor.css |
95 B |
build/block-library/blocks/text-columns/style-rtl.css |
166 B |
build/block-library/blocks/text-columns/style.css |
166 B |
build/block-library/blocks/verse/style-rtl.css |
87 B |
build/block-library/blocks/verse/style.css |
87 B |
build/block-library/blocks/video/editor-rtl.css |
561 B |
build/block-library/blocks/video/editor.css |
563 B |
build/block-library/blocks/video/style-rtl.css |
159 B |
build/block-library/blocks/video/style.css |
159 B |
build/block-library/blocks/video/theme-rtl.css |
110 B |
build/block-library/blocks/video/theme.css |
110 B |
build/block-library/common-rtl.css |
1.01 kB |
build/block-library/common.css |
1 kB |
build/block-library/editor-elements-rtl.css |
75 B |
build/block-library/editor-elements.css |
75 B |
build/block-library/elements-rtl.css |
54 B |
build/block-library/elements.css |
54 B |
build/block-library/reset-rtl.css |
478 B |
build/block-library/reset.css |
478 B |
build/block-library/theme-rtl.css |
695 B |
build/block-library/theme.css |
700 B |
build/block-serialization-default-parser/index.min.js |
1.11 kB |
build/block-serialization-spec-parser/index.min.js |
2.83 kB |
build/compose/index.min.js |
12 kB |
build/customize-widgets/index.min.js |
11.3 kB |
build/customize-widgets/style-rtl.css |
1.4 kB |
build/customize-widgets/style.css |
1.4 kB |
build/data-controls/index.min.js |
653 B |
build/data/index.min.js |
8.03 kB |
build/date/index.min.js |
32 kB |
build/deprecated/index.min.js |
507 B |
build/dom-ready/index.min.js |
324 B |
build/dom/index.min.js |
4.69 kB |
build/edit-navigation/index.min.js |
16 kB |
build/edit-navigation/style-rtl.css |
4 kB |
build/edit-navigation/style.css |
4.01 kB |
build/edit-post/classic-rtl.css |
546 B |
build/edit-post/classic.css |
547 B |
build/edit-post/index.min.js |
30.5 kB |
build/edit-post/style-rtl.css |
6.94 kB |
build/edit-post/style.css |
6.94 kB |
build/edit-widgets/style-rtl.css |
4.35 kB |
build/edit-widgets/style.css |
4.35 kB |
build/editor/index.min.js |
41.5 kB |
build/editor/style-rtl.css |
3.66 kB |
build/editor/style.css |
3.65 kB |
build/element/index.min.js |
4.68 kB |
build/escape-html/index.min.js |
537 B |
build/format-library/index.min.js |
6.75 kB |
build/format-library/style-rtl.css |
571 B |
build/format-library/style.css |
571 B |
build/hooks/index.min.js |
1.64 kB |
build/html-entities/index.min.js |
448 B |
build/i18n/index.min.js |
3.77 kB |
build/is-shallow-equal/index.min.js |
527 B |
build/keyboard-shortcuts/index.min.js |
1.78 kB |
build/keycodes/index.min.js |
1.79 kB |
build/list-reusable-blocks/index.min.js |
1.74 kB |
build/list-reusable-blocks/style-rtl.css |
835 B |
build/list-reusable-blocks/style.css |
835 B |
build/media-utils/index.min.js |
2.93 kB |
build/notices/index.min.js |
953 B |
build/nux/index.min.js |
2.05 kB |
build/nux/style-rtl.css |
732 B |
build/nux/style.css |
728 B |
build/plugins/index.min.js |
1.94 kB |
build/preferences-persistence/index.min.js |
2.22 kB |
build/preferences/index.min.js |
1.3 kB |
build/primitives/index.min.js |
933 B |
build/priority-queue/index.min.js |
612 B |
build/react-i18n/index.min.js |
696 B |
build/react-refresh-entry/index.min.js |
8.44 kB |
build/react-refresh-runtime/index.min.js |
7.31 kB |
build/redux-routine/index.min.js |
2.74 kB |
build/reusable-blocks/index.min.js |
2.21 kB |
build/reusable-blocks/style-rtl.css |
256 B |
build/reusable-blocks/style.css |
256 B |
build/rich-text/index.min.js |
11.2 kB |
build/server-side-render/index.min.js |
1.61 kB |
build/shortcode/index.min.js |
1.53 kB |
build/token-list/index.min.js |
644 B |
build/url/index.min.js |
3.61 kB |
build/vendors/react-dom.min.js |
38.5 kB |
build/vendors/react.min.js |
4.34 kB |
build/viewport/index.min.js |
1.08 kB |
build/warning/index.min.js |
268 B |
build/widgets/index.min.js |
7.19 kB |
build/widgets/style-rtl.css |
1.16 kB |
build/widgets/style.css |
1.16 kB |
build/wordcount/index.min.js |
1.06 kB |
Nice! This is working well for me.
Would it be possible to also apply the styles to the placeholder you find in the template editor when a featured image isn't set, or when no context is passed?
Would it be possible to also apply the styles to the placeholder you find in the template editor when a featured image isn't set, or when no context is passed?
It should be possible. I'll take a run at it later this week.
Would it be possible to also apply the styles to the placeholder you find in the template editor when a featured image isn't set, or when no context is passed?
I've explored applying borders to the Post Featured Image's placeholder and run into a few issues that make it a bit of a clunky fit.
Theme.json / Global Styles
To display any borders set via theme.json or global styles on the placeholder, we'd need to add an editor-specific selector to the block.json config, which would also result in that selector being included in the CSS generated for the frontend. This is minor, but it might add up if we intend to do this for every image-related block or any block supporting borders but using a placeholder.
Block specific borders
For borders set via block support, we can manually apply these to the placeholder. The downside is that the application of the border can really detract from it appearing as a placeholder.
To achieve this cleanly, we'd need to update the way MediaPlaceholder calls its renderPlaceholder callback also to pass wrapper props in addition to the placeholder content. This might be better done in a follow-up PR. A short-term alternative is to slightly duplicate the placeholder markup in the feature image block's edit.js so it can access the required block attributes and generated border styles.
Another UX issue here is the default placeholder styles define border-style: none, which forces a user to have to select a border style to see a visual border on the placeholder. This makes the experience of configuring a border a little different between when there's a placeholder displayed and an actual image. Some extra editor-only CSS leveraging :where might help smooth this out though.
Example of borders detracting from placeholder
https://user-images.githubusercontent.com/60436221/182775238-116786ca-1182-4b36-97ee-2ceaa3d8d1c2.mp4
Image Block
The Image block does not apply borders to its placeholder state. I appreciate that the use cases here are a little different but given the similarities between the blocks, should they be consistent?
Before investing too much time here, I'd like to double-check how desirable applying borders to the placeholder actually is. I'd also be happy to continue exploring this in a follow-up.
I'd like to double-check how desirable applying borders to the placeholder actually is
I think it's pretty important. Not so much in the post editor, but in the template editor – where this block is going to see more use – definitely. If I'm designing my Single template and would like to add a border to the featured image, I'm going to want to see a preview of that border on the canvas.
I don't find the border detracting from the placeholder to be a big deal. The diagonal dashed line is the key visual indicator so as long as that's partially visible most of the time then we should be ok.
Another UX issue here is the default placeholder styles define border-style: none
It's probably not out of the question to update the placeholder design a bit to better accommodate the border controls. Since this could be a bit tricky to get right, a follow-up may make more sense.
@jameskoster I've updated this PR to apply the border styles to the block's placeholder.
It's mostly there except for a small issue around the border radius for the placeholder's SVG. If I make the SVG inherit the placeholder's border radius (current state of this PR), depending upon that value and the width of the border, we get a small gap between the placeholder border and the SVG's.
An alternative was to clip the SVG by setting overflow: hidden on the placeholder's wrapper. This looked a bit worse. Another option might be to look into calculating an adjusted border radius for that similar to how the search block's border radius works when the button is positioned inside. I think that would be better suited to a follow-up to this PR.
@aaronrobertshaw could we remove the placeholder border together if one is added via the border control? 🤔
could we remove the placeholder border together if one is added via the border control? 🤔
So I'm on the same page, the "placeholder border" to me is the blue border in the screenshot in my earlier comment. The dotted border is on the placeholder's inner SVG. Am I correct in assuming it is that dotted border you are asking if we can remove if a border is set?
We could if the border is added at the individual block level however that is more problematic when the borders are added via Global Styles or theme.json. In those cases, the border styles are applied via a generated stylesheet. In the block editor, for example, we don't have access to this data short of getting computed styles.
Am I correct in assuming it is that dotted border you are asking if we can remove if a border is set?
Yes.
We could if the border is added at the individual block level however that is more problematic when the borders are added via Global Styles or theme.json. In those cases, the border styles are applied via a generated stylesheet. In the block editor, for example, we don't have access to this data short of getting computed styles.
That sounds like it won't be possible?
Making the radii match would be acceptable I think (in a follow-up like you mentioned). Alternatively we could explore different design approaches to the placeholder that do not use a border.
This is damn sweet. Let's for sure land this for 6.1. Here's a status with the border radius issue as discussed above:

I tried a trick that I think solves it:

What do you think? It feels solid to me. This is the trick:
// Inherit border radius for dashed placeholder.
> svg {
border-radius: inherit;
}
// Hide dashed border entirely when a border is set.
&:where([style*="border-width"]:not([style*="border-style: none"])) {
overflow: hidden;
> svg {
border-style: none;
border-radius: 0;
}
}
You can paste that on line 108 in editor.scss. Let me know what you think.
Inspired by excellent work here, I've started #43143 to do the same for the Image block.
I would be grateful for some help in porting over some of the inheriting features from this PR. The opportunity to refactor the placeholder component, or just componentize the dashed-line variant, is also increasingly becoming clear. Probably doesn't have to happen now, but it'd be a nice optimization at some point now that we're using this style across both Featured Image, Image, and Site Logo.
Thanks for the enthusiastic reception as well as taking a look at this one @jasmussen, appreciate it 👍
What do you think? It feels solid to me. This is the trick:
Unfortunately, there are a few issues with the suggested CSS. Which is actually a subset of what I had in mind with my https://github.com/WordPress/gutenberg/pull/42847#issuecomment-1208762531.
We could if the border is added at the individual block level however that is more problematic when the borders are added via Global Styles or theme.json. In those cases, the border styles are applied via a generated stylesheet. In the block editor, for example, we don't have access to this data short of getting computed styles.
The main issue is that when border styles are generated via theme.json or global styles, we'll end up with something like the following in the generated stylesheet:
.wp-block-image img,
.wp-block-image .block-editor-media-placeholder {
border-style: solid;
border-color: #00000;
border-width: 5px;
}
The border isn't applied by a custom CSS class or style attribute so I'm unaware of any means to conditionally style the inner SVG based upon that. A primary use case raised earlier was setting a global style so featured image blocks within the query block in the site editor would display with a border. In such a scenario we'd still get the misaligned borders.
The second, easily solvable issue, with the proposed CSS is that it only covers flat borders as opposed to those applied to individual sides e.g. top and bottom borders only etc (border-top-width).
I'm hoping to have a little time to experiment further with the placeholder today. One thing I'll try is to perhaps absolutely position the SVG and give it the same border, to essentially overlay it on the placeholder wrapper.
Ah, thanks for the clarity, I had a feeling.
Another option is to draw the dashed border on the placeholder component instead of the SVG, so it will naturally get overridden. The main problem there is that the border is intentionally set to be currentColor so that it will always inherit colors from adjacent text — but it's also semi-transparent, which requires it to be a separate element with opacity applied. I'm going to tinker a bit with this when I get a moment, see what we can do.
Alright, I tinkered with this enough to get a headache. Trying clever inheritance tricks, I got really close while maintaining the semi-transparent currentColor stroke:

But unfortunately, I couldn't thread the needle. There was always some tradeoff, and the complexity was getting out there.
So I tried a different approach: ditching the opacity entirely:
That's with the following code diff:
diff --git a/packages/components/src/placeholder/style.scss b/packages/components/src/placeholder/style.scss
index d74fd7cdde..ac1d3cb51c 100644
--- a/packages/components/src/placeholder/style.scss
+++ b/packages/components/src/placeholder/style.scss
@@ -33,7 +33,6 @@
&.has-illustration {
background: none;
- border: none;
box-shadow: none;
min-width: 100px;
}
@@ -180,17 +179,21 @@
}
// Style the placeholder illustration.
-.components-placeholder__illustration {
+.has-illustration {
border: $border-width dashed currentColor;
- box-sizing: border-box;
+ overflow: hidden;
+}
+
+.components-placeholder__illustration {
+ box-sizing: content-box;
position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
width: 100%;
height: 100%;
stroke: currentColor;
stroke-dasharray: 3;
- opacity: 0.4;
+ border-width: inherit;
+ border-style: inherit;
}
Or, you can manually integrate it with this chunk:
// Style the placeholder illustration.
.has-illustration {
border: $border-width dashed currentColor;
overflow: hidden;
}
.components-placeholder__illustration {
box-sizing: content-box;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100%;
height: 100%;
stroke: currentColor;
stroke-dasharray: 3;
border-width: inherit;
border-style: inherit;
}
— but you have to remove the border: none; from .has-illustration longer up in the hierarchy.
So the question is: is that text-color dark outline good enough? I think yes, but I'd love input from @WordPress/gutenberg-design. Keep in mind, this should also affect Site Logo and soon Image in #43143. What do you think?
So the question is: is that text-color dark outline good enough?
Do you mean on the 'No color, but width and radius defined' config?
That's a tricky one. It feels a bit strange to see a color applied when one isn't explicitly set. But I appreciate that's an accurate representation of how border-color behaves. It's probably an acceptable trade-off.
Perhaps as a follow-up we can consider making the Border color control behave like the spec, IE the default border color is inherited from the text color of the selected element (when we're able to detect it 😅).
There's some nuance. Right now the placeholder is drawn using currentColor (and transparency) to ensure that its appearance works in any context. I.e. white text on dark background you'll have white dashed line on a black background placeholder. Or in other styles, like this one:
What I'm saying is that we can have either of these two, but not both at the same time:
- Inherit radius, keep the text-color dashed borders, but they have to be full opacity.
- Don't inherit radius (or inherit in that buggy way we found), keep the text-color dashed borders, and keep the partial (0,4) opacity.
Is 1 fine? I suppose that's the main question.
I think it's fine. In fact, I think I prefer it 😆
Cool. We should probably try it. The thing is, we can always come back to these (especially if we can clean up the code and componentize it a bit) and try a different style if we like.
I've gone ahead and created #43228 which deduplicates and simplifies the code for these dashed placeholders. Part of that PR is also a fix that should enable border inheritance in this PR.
Edit: now merged. This PR should hopefully just work if rebased. Let me know if you need any help!
Let's add this issue to the 6.1 Editor Tasks board and prioritize it as it's a requirement for the new default theme. cc @michalczaplinski @ockham @mikachan @beafialho
Let's add this issue to the 6.1 Editor Tasks board and prioritize it
This is on my list to rebase and polish up now the placeholder changes are in place. Should be ready for a final review in the next couple of days.
This PR has been rebased. The video below demos the current state of borders on the Post Featured Image block.
There are still several issues with applying borders to the block's placeholder. The end of the video includes a demonstration of one that occurs when opposite sides get differing width borders. Another is when the block sets a zero-width border, a border-style: none rule is applied, and the placeholder will then only consist of a diagonal line.
It feels to me that the styling of the placeholder has regressed now rather than been improved after recent efforts to inherit the border on the SVG.
I'd like to propose that we give this a final review to merge and address the placeholder problems in a separate follow-up.
https://user-images.githubusercontent.com/60436221/185296723-49dabfc5-e557-4665-b2d4-ae158306cc4d.mp4
I have not yet tested it, but from looking at the video Aaron this looks really nice! I want it!
This is great, my GIF also shows border and radius working well in the setup state:

There are still several issues with applying borders to the block's placeholder. The end of the video includes a demonstration of one that occurs when opposite sides get differing width borders.
I'll take a quick look and if I think up a fix I'll push! Hope that's okay.
Another is when the block sets a zero-width border, a border-style: none rule is applied, and the placeholder will then only consist of a diagonal line.
I think this is acceptable. It's first and foremost in edgecase territory, and secondly it's technically accurate.
@aaronrobertshaw I pushed a fix for the inner color:

What do you think? If you're cool with it, looks like this one needs updated snapshots.
I think this is acceptable.
I agree. Still, it might be good to (separate to this PR) explore adding a background to the placeholder so that it is still visible when placed on a noisy background, or when placeholders overlap, e.g. putting featured image inside a cover:
I agree. Still, it might be good to (separate to this PR) explore adding a background to the placeholder so that it is still visible when placed on a noisy background, or when placeholders overlap, e.g. putting featured image inside a cover:
Ack, yes indeed.
Thanks for tweaking the placeholder styles @jasmussen 👍
What do you think? If you're cool with it, looks like this one needs updated snapshots.
It might just be me, but I still think the placeholder with borders has problems however, if we remove the styles inheriting border-width and border-style on the placeholder's SVG along with removing the border-color: transparent, I think we get a better result.
The following videos show what I see with and without the abovementioned styles.
| With | Without |
|---|---|
Given the previous commit adjusting these styles, I'll hold off merging this until we decide whether to strip them or not.
My vote is if they don't impact other block's placeholders, we should remove them. Any other issues with the placeholder, like applying a background color are out of scope for this PR and will be addressed via follow-ups.
Excellent sleuthing. As far as I can tell, the major difference is the positioning of the diagonal, which is off when those styles are inherited:

It is not off when they are gone:
I could swear I added those for a reason, but testing with a rebase the new Image, as well as Site Logo and various combinations of borders and no borders, this change seems solid! In other words, they don't seem needed. Definitely remove those, then land this. Thank you! 🙏
(Besides, if they turn out to become necessary again, we'll just add them back.)