-
Notifications
You must be signed in to change notification settings - Fork 6.8k
fix(cdk/a11y): make cdk-high-contrast work w/ emulated view encapsulation #18152
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
Conversation
d19608a
to
7257817
Compare
src/cdk/a11y/_a11y.scss
Outdated
@@ -35,7 +35,8 @@ | |||
// context. We address this by nesting the selector context under .cdk-high-contrast. | |||
@at-root { | |||
$selector-context: #{&}; | |||
.cdk-high-contrast-#{$target} { | |||
.cdk-high-contrast-#{$target}, | |||
.cdk-high-contrast-#{$target} :host { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tested it out and this breaks the high contrast styles for Edge and IE for unencapsulated components. The problem is that when encapsulation is disabled, Angular leaves the :host
in place which IE/Edge don't support and causes the entire selector to be invalidated. It can be worked around by outputting a separate selector, but it means that we generate double the amount of CSS:
.cdk-high-contrast-#{$target} {
@content;
}
.cdk-high-contrast-#{$target} :host {
@content;
}
We could also add another parameter to the mixin that allows the consumer to tell us whether the styles are encapsulated and we can output the correct styles based on it. By default it can output both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd definitely prefer to add a parameter to toggle this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see- I was assuming IE would ignore a pseudo-class it didn't recognize. I pushed an update that adds a param, defaulting to emitting both styles for maximum compatibility.
7257817
to
f6643c9
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks for the quick PR & fix for (my|the) issue! 🙇
src/cdk/a11y/_a11y.scss
Outdated
/// * `on` - works for `Emulated`, `Native`, and `ShadowDom` | ||
/// * `off` - works for `None` | ||
/// * `both` - works for all encapsulation modes by emitting the CSS twice (default). | ||
@mixin cdk-high-contrast($target: active, $encapsulation: 'both') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure the both
value makes sense since encapsulation is either on or off.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would you do instead? I want the mixin to "just work" by default, even if it is emitting extra styles.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the thing that's throwing me off is that it's called both
which sounds like it can have more than one style encapsulations at the same time. Maybe can make it on | off | undefined
and output both styles if it's emitted? Another approach could be to match the naming from Angular.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand your point, but I think, both
is fine here, because with this option, the mixin supports both general states of view/style encapsulation. So it's rather an option of which policies are supported.
Matching the naming from Angular would be complicated, as AFAIK there's no explicit naming from Angular which addresses Emulated
, Native
, and ShadowDom
together.
undefined
is not a restricted value in Sass, so null
would be the way to go. But I'm feeling that both
fits better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about 'any'
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, that works too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed to any
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but the CI is failing. It looks like not all references to both
were updated.
That's what I get for using the in-browser editor |
…tion 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.
993bd7e
to
3768db6
Compare
…tion (#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)
…tion (angular#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.
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
Say you have this in your component:
With this change, this will output:
Here,
.cdk-high-contrast-active .some-element
will apply in placeswhere 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 couldconsider adding if we get an additional request.
This adds a few more bytes, but high-contrast styles tend to be pretty
limited.
Fixes #18147