|
8 | 8 | * Cross-Block Selection |
9 | 9 | */ |
10 | 10 |
|
| 11 | +@keyframes selection-overlay__fade-in-animation { |
| 12 | + from { |
| 13 | + opacity: 0; |
| 14 | + } |
| 15 | + to { |
| 16 | + opacity: 0.4; |
| 17 | + } |
| 18 | +} |
| 19 | + |
11 | 20 | // Note to developers refactoring this, please test navigation mode, and |
12 | 21 | // multi selection and hovering the block switcher to highlight the block. |
| 22 | +// Also be sure to test partial selections in Safari, as it draws the |
| 23 | +// selection marker with an entirely different model than Blink. |
13 | 24 | .block-editor-block-list__layout { |
14 | 25 | position: relative; |
15 | 26 |
|
16 | | - // The primary indicator of selection in text is the native selection marker. |
17 | | - // When selecting multiple blocks, we provide an additional selection indicator. |
18 | | - .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected), |
19 | | - .block-editor-block-list__block.is-highlighted, |
20 | | - .block-editor-block-list__block.is-highlighted ~ .is-multi-selected { |
| 27 | + // Hide selections on this element, otherwise Safari will include it stacked |
| 28 | + // under your actual selection. |
| 29 | + &::selection { |
| 30 | + background: transparent; |
| 31 | + } |
| 32 | + |
| 33 | + .has-multi-selection &::selection { |
| 34 | + background: transparent; |
| 35 | + } |
| 36 | + |
| 37 | + // Block multi selection |
| 38 | + .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected) { |
| 39 | + // Hide the native selection indicator. |
| 40 | + &::selection { |
| 41 | + background: transparent; |
| 42 | + } |
| 43 | + |
| 44 | + // Draw a spot color overlay. |
21 | 45 | &::after { |
22 | | - // Show selection borders around every non-nested block's actual footprint. |
| 46 | + content: ""; |
23 | 47 | position: absolute; |
24 | 48 | z-index: 1; |
25 | 49 | pointer-events: none; |
26 | | - content: ""; |
27 | 50 | top: $border-width; |
| 51 | + right: $border-width; |
28 | 52 | bottom: $border-width; |
29 | 53 | left: $border-width; |
30 | | - right: $border-width; |
| 54 | + background: var(--wp-admin-theme-color); |
| 55 | + opacity: 0.4; |
31 | 56 |
|
32 | | - // Everything else. |
33 | | - box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); |
34 | | - border-radius: $radius-block-ui - $border-width; // Border is outset, so subtract the width to achieve correct radius. |
| 57 | + // Animate. |
| 58 | + animation: selection-overlay__fade-in-animation 0.1s ease-out; |
| 59 | + animation-fill-mode: forwards; |
| 60 | + @include reduce-motion("animation"); |
35 | 61 |
|
36 | | - // Windows High Contrast mode will show this outline. |
| 62 | + // Show outline in high contrast mode. |
37 | 63 | outline: 2px solid transparent; |
38 | | - |
39 | | - // Show a lighter color for dark themes. |
40 | | - .is-dark-theme & { |
41 | | - box-shadow: 0 0 0 $border-width $dark-theme-focus; |
42 | | - } |
43 | | - } |
44 | | - |
45 | | - // Provide exceptions for placeholders. |
46 | | - .components-placeholder, |
47 | | - .block-editor-block-list__block.is-multi-selected:not(.is-partially-selected) { |
48 | | - ::selection { |
49 | | - background: transparent; |
50 | | - } |
51 | 64 | } |
52 | 65 | } |
53 | 66 |
|
54 | | - .block-editor-block-list__block.is-highlighted::after { |
55 | | - box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); |
56 | | - outline: $border-width solid transparent; |
57 | | - } |
58 | | - |
59 | | - &.is-navigate-mode .block-editor-block-list__block.is-selected::after, |
| 67 | + // Block highlight, and navigation mode, not focus. |
| 68 | + // By not using a pseudo element, we can limit ourselves to only |
| 69 | + // using ::after, leaving ::before free. Otherwise, highlight + multi-select |
| 70 | + // would require the opacity-changing overlay to be on ::before. |
| 71 | + .block-editor-block-list__block.is-highlighted, |
| 72 | + .block-editor-block-list__block.is-highlighted ~ .is-multi-selected, |
| 73 | + &.is-navigate-mode .block-editor-block-list__block.is-selected, |
60 | 74 | & .is-block-moving-mode.block-editor-block-list__block.has-child-selected { |
61 | | - box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); |
| 75 | + border-radius: $radius-block-ui; |
| 76 | + box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); |
| 77 | + |
| 78 | + // Show outline in high contrast mode. |
62 | 79 | outline: 2px solid transparent; |
63 | 80 | } |
64 | 81 |
|
| 82 | + // Block focus. |
| 83 | + .block-editor-block-list__block:not([contenteditable]):focus { |
| 84 | + outline: none; |
| 85 | + |
| 86 | + // We're using a pseudo element to overflow placeholder borders |
| 87 | + // and any border inside the block itself. |
| 88 | + &::after { |
| 89 | + content: ""; |
| 90 | + position: absolute; |
| 91 | + z-index: 1; |
| 92 | + pointer-events: none; |
| 93 | + top: $border-width; |
| 94 | + right: $border-width; |
| 95 | + bottom: $border-width; |
| 96 | + left: $border-width; |
| 97 | + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); |
| 98 | + border-radius: $radius-block-ui - $border-width; // Border is outset, so subtract the width to achieve correct radius. |
| 99 | + outline: 2px solid transparent; // This shows up in Windows High Contrast Mode. |
| 100 | + |
| 101 | + // Show a light color for dark themes. |
| 102 | + .is-dark-theme & { |
| 103 | + box-shadow: 0 0 0 var(--wp-admin-border-width-focus) $dark-theme-focus; |
| 104 | + } |
| 105 | + } |
| 106 | + } |
| 107 | + |
| 108 | + // Moving blocks using keyboard (Ellipsis > Move). |
65 | 109 | & .is-block-moving-mode.block-editor-block-list__block.is-selected { |
| 110 | + box-shadow: none; |
| 111 | + outline: none; |
66 | 112 |
|
67 | | - &::before { |
| 113 | + &::after { |
68 | 114 | content: ""; |
69 | 115 | position: absolute; |
70 | 116 | z-index: 0; |
|
79 | 125 | border-radius: $radius-block-ui; |
80 | 126 | border-top: 4px solid $gray-400; |
81 | 127 | } |
82 | | - |
83 | | - &::after { |
84 | | - content: none; |
85 | | - } |
86 | 128 | } |
87 | 129 |
|
88 | 130 | & .is-block-moving-mode.can-insert-moving-block.block-editor-block-list__block.is-selected { |
89 | | - &::before { |
| 131 | + &::after { |
90 | 132 | border-color: var(--wp-admin-theme-color); |
91 | 133 | } |
92 | 134 | } |
|
123 | 165 | } |
124 | 166 |
|
125 | 167 | .block-editor-block-list__layout .block-editor-block-list__block { |
| 168 | + // With `position: static`, Safari marks a full-width selection rectangle, including margins. |
| 169 | + // With `position: relative`, Safari marks an inline selection rectangle, similar to that of |
| 170 | + // Blink based browsers, but it also does "crop" the marker, which can result in a small line |
| 171 | + // from the preceeding paragraph showing, which is effectively the above selection bleeding in. |
| 172 | + // We choose relative, as that matches the multi-selection, which is limited to the block footprint. |
126 | 173 | position: relative; |
127 | 174 |
|
128 | 175 | // Re-enable text-selection on editable blocks. |
129 | 176 | user-select: text; |
130 | 177 |
|
131 | | - // Hide the select style pseudo element as it interferes with the style. |
132 | | - &.is-partially-selected::after { |
133 | | - height: 0; |
134 | | - } |
135 | | - |
136 | | - &.is-highlighted::after, |
137 | | - &.is-highlighted ~ .is-multi-selected::after { |
138 | | - height: auto; |
139 | | - } |
140 | | - |
141 | 178 | // Break long strings of text without spaces so they don't overflow the block. |
142 | 179 | overflow-wrap: break-word; |
143 | 180 |
|
|
148 | 185 | /** |
149 | 186 | * Notices |
150 | 187 | */ |
151 | | - |
152 | 188 | .components-placeholder .components-with-notices-ui { |
153 | 189 | margin: -10px 0 12px 0; |
154 | 190 | } |
|
167 | 203 | } |
168 | 204 | } |
169 | 205 |
|
170 | | - |
171 | | - /** |
172 | | - * Block Layout |
173 | | - */ |
174 | | - |
175 | | - // Navigate mode & Focused wrapper. |
176 | | - // We're using a pseudo element to overflow placeholder borders |
177 | | - // and any border inside the block itself. |
178 | | - &:not([contenteditable]):focus { |
179 | | - outline: none; |
180 | | - |
181 | | - &::after { |
182 | | - position: absolute; |
183 | | - z-index: 1; |
184 | | - pointer-events: none; |
185 | | - content: ""; |
186 | | - top: $border-width; |
187 | | - bottom: $border-width; |
188 | | - left: $border-width; |
189 | | - right: $border-width; |
190 | | - |
191 | | - // 2px outside. |
192 | | - box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); |
193 | | - border-radius: $radius-block-ui - $border-width; // Border is outset, so subtract the width to achieve correct radius. |
194 | | - outline: 2px solid transparent; // This shows up in Windows High Contrast Mode. |
195 | | - |
196 | | - // Show a light color for dark themes. |
197 | | - .is-dark-theme & { |
198 | | - box-shadow: 0 0 0 var(--wp-admin-border-width-focus) $dark-theme-focus; |
199 | | - } |
200 | | - } |
201 | | - } |
202 | | - |
203 | | - /** |
204 | | - * Block styles and alignments |
205 | | - */ |
206 | | - &::after { |
207 | | - content: ""; |
208 | | - pointer-events: none; |
209 | | - position: absolute; |
210 | | - top: 0; |
211 | | - right: 0; |
212 | | - bottom: 0; |
213 | | - left: 0; |
214 | | - border-radius: $radius-block-ui; |
215 | | - box-shadow: 0 0 0 0 transparent; |
216 | | - transition: box-shadow 0.1s linear; |
217 | | - @include reduce-motion("transition"); |
218 | | - } |
219 | | - |
220 | 206 | // Warnings |
221 | 207 | &.has-warning { |
222 | 208 | min-height: $grid-unit-60; |
|
263 | 249 | } |
264 | 250 | } |
265 | 251 |
|
266 | | - // Reusable blocks parent borer. |
| 252 | + // Reusable blocks parent border. |
267 | 253 | &.is-reusable.has-child-selected::after { |
268 | 254 | box-shadow: 0 0 0 1px var(--wp-admin-theme-color); |
269 | 255 | } |
|
277 | 263 | .is-outline-mode .block-editor-block-list__block:not(.remove-outline) { |
278 | 264 | &.is-hovered { |
279 | 265 | cursor: default; |
280 | | - |
281 | | - &::after { |
282 | | - top: $border-width; |
283 | | - left: $border-width; |
284 | | - right: $border-width; |
285 | | - bottom: $border-width; |
286 | | - box-shadow: 0 0 0 $border-width var(--wp-admin-theme-color); |
287 | | - // Border is outset, so subtract the width to achieve correct radius. |
288 | | - border-radius: $radius-block-ui - $border-width; |
289 | | - } |
| 266 | + box-shadow: inset 0 0 0 $border-width var(--wp-admin-theme-color); |
| 267 | + border-radius: $radius-block-ui; |
290 | 268 | } |
291 | 269 |
|
292 | 270 | &.is-selected { |
|
296 | 274 | cursor: unset; |
297 | 275 | } |
298 | 276 |
|
299 | | - &::after { |
300 | | - box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); // Selected not focussed. |
301 | | - top: $border-width; |
302 | | - left: $border-width; |
303 | | - right: $border-width; |
304 | | - bottom: $border-width; |
305 | | - border-radius: $radius-block-ui - $border-width; // Border is outset, so subtract the width to achieve correct radius. |
306 | | - } |
| 277 | + box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); // Selected not focussed. |
| 278 | + border-radius: $radius-block-ui; |
307 | 279 |
|
308 | 280 | &:focus { |
309 | | - &::after { |
310 | | - box-shadow: 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); |
311 | | - } |
| 281 | + box-shadow: inset 0 0 0 var(--wp-admin-border-width-focus) var(--wp-admin-theme-color); |
312 | 282 | } |
313 | 283 | } |
314 | 284 | } |
|
0 commit comments