Skip to content

Commit aff21e8

Browse files
committed
fix(cdk/a11y): make cdk-high-contrast work w/ emulated view encapsulation (#18152)
* fix(cdk/a11y): make cdk-high-contrast work w/ emulated view encapsulation Say you have this in your component: ```scss .some-element { @include cdk-high-contrast() { border: 1px solid white; } } ``` With this change, this will output: ```scss .cdk-high-contrast-active .some-element, .cdk-high-contrast-active :host .some-element { border: 1px solid white; } ``` Here, `.cdk-high-contrast-active .some-element` will apply in places where encapsulation is turned off, and `.cdk-high-contrast-active :host .some-element` will apply in cases where encapsulation is emulated. Neither will work in Shadow DOM (which we don't officially support). AFAIK, Shadow DOM would need to use `:host-content()`, which we could consider adding if we get an additional request. This adds a few more bytes, but high-contrast styles tend to be pretty limited. (cherry picked from commit ea17135)
1 parent 2b83a0a commit aff21e8

File tree

1 file changed

+41
-12
lines changed

1 file changed

+41
-12
lines changed

src/cdk/a11y/_a11y.scss

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,58 @@
1818
}
1919
}
2020

21-
// Applies styles for users in high contrast mode. Note that this only applies
22-
// to Microsoft browsers. Chrome can be included by checking for the `html[hc]`
23-
// attribute, however Chrome handles high contrast differently.
24-
//
25-
// @param target Which kind of high contrast setting to target. Defaults to `active`, can be
26-
// `white-on-black` or `black-on-white`.
27-
@mixin cdk-high-contrast($target: active) {
21+
/// Emits the mixin's content nested under `$selector-context` if `$selector-context`
22+
/// is non-empty.
23+
/// @param selector-context The selector under which to nest the mixin's content.
24+
@mixin _cdk-optionally-nest-content($selector-context) {
25+
@if ($selector-context == '') {
26+
@content;
27+
}
28+
@else {
29+
#{$selector-context} {
30+
@content;
31+
}
32+
}
33+
}
34+
35+
/// Applies styles for users in high contrast mode. Note that this only applies
36+
/// to Microsoft browsers. Chrome can be included by checking for the `html[hc]`
37+
/// attribute, however Chrome handles high contrast differently.
38+
///
39+
/// @param target Which kind of high contrast setting to target. Defaults to `active`, can be
40+
/// `white-on-black` or `black-on-white`.
41+
/// @param encapsulation Whether to emit styles for view encapsulation. Values are:
42+
/// * `on` - works for `Emulated`, `Native`, and `ShadowDom`
43+
/// * `off` - works for `None`
44+
/// * `any` - works for all encapsulation modes by emitting the CSS twice (default).
45+
@mixin cdk-high-contrast($target: active, $encapsulation: 'any') {
2846
@if ($target != 'active' and $target != 'black-on-white' and $target != 'white-on-black') {
2947
@error 'Unknown cdk-high-contrast value "#{$target}" provided. ' +
3048
'Allowed values are "active", "black-on-white", and "white-on-black"';
3149
}
3250

51+
@if ($encapsulation != 'on' and $encapsulation != 'off' and $encapsulation != 'any') {
52+
@error 'Unknown cdk-high-contrast encapsulation "#{$encapsulation}" provided. ' +
53+
'Allowed values are "on", "off", and "any"';
54+
}
55+
3356
// If the selector context has multiple parts, such as `.section, .region`, just doing
3457
// `.cdk-high-contrast-xxx #{&}` will only apply the parent selector to the first part of the
3558
// context. We address this by nesting the selector context under .cdk-high-contrast.
3659
@at-root {
3760
$selector-context: #{&};
38-
.cdk-high-contrast-#{$target} {
39-
@if ($selector-context == '') {
40-
@content;
61+
62+
@if ($encapsulation != 'on') {
63+
.cdk-high-contrast-#{$target} {
64+
@include _cdk-optionally-nest-content($selector-context) {
65+
@content;
66+
}
4167
}
42-
@else {
43-
#{$selector-context} {
68+
}
69+
70+
@if ($encapsulation != 'off') {
71+
.cdk-high-contrast-#{$target} :host {
72+
@include _cdk-optionally-nest-content($selector-context) {
4473
@content;
4574
}
4675
}

0 commit comments

Comments
 (0)