From f4558551429f6add270eb79a4af96f91f7d4c4de Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Tue, 3 Sep 2024 09:09:49 +0200 Subject: [PATCH] fix(cdk/overlay): load structural styles in a cascade layer Recently we switched to loading the styles of the overlay dynamically which can make them more specific than pre-existing themes. These changes use a cascade layer in order to reduce their specificity. --- src/cdk/overlay/BUILD.bazel | 11 +++++- src/cdk/overlay/_index.scss | 55 ++++++++++++++++++++------ src/cdk/overlay/overlay-container.ts | 2 +- src/cdk/overlay/overlay-structure.scss | 3 ++ 4 files changed, 57 insertions(+), 14 deletions(-) create mode 100644 src/cdk/overlay/overlay-structure.scss diff --git a/src/cdk/overlay/BUILD.bazel b/src/cdk/overlay/BUILD.bazel index a7bc728efa0a..03eefa013649 100644 --- a/src/cdk/overlay/BUILD.bazel +++ b/src/cdk/overlay/BUILD.bazel @@ -19,7 +19,7 @@ ng_module( exclude = ["**/*.spec.ts"], ), assets = [ - ":overlay-prebuilt.css", + ":overlay-structure.css", ], deps = [ "//src:dev_mode_types", @@ -46,7 +46,14 @@ sass_binary( src = "overlay-prebuilt.scss", deps = [ ":overlay_scss_lib", - "//src/cdk/a11y:a11y_scss_lib", + ], +) + +sass_binary( + name = "overlay_structure_scss", + src = "overlay-structure.scss", + deps = [ + ":overlay_scss_lib", ], ) diff --git a/src/cdk/overlay/_index.scss b/src/cdk/overlay/_index.scss index 2da3f6020dad..ce8be7b73c5b 100644 --- a/src/cdk/overlay/_index.scss +++ b/src/cdk/overlay/_index.scss @@ -12,8 +12,20 @@ $overlay-backdrop-color: rgba(0, 0, 0, 0.32) !default; $backdrop-animation-duration: 400ms !default; $backdrop-animation-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default; -/// Emits structural styles required for cdk/overlay to function. -@mixin overlay() { +// Conditionally wraps some styles in a layer depending on a flag. +@mixin _conditional-layer($should-wrap) { + @if ($should-wrap) { + @layer cdk-overlay { + @content; + } + } @else { + @content; + } +} + +// Structural styles for the overlay. Pass `$wrap-customizable-styles` to emit +// the styles that support customization in a way that makes them easier to change. +@mixin private-overlay-structure($wrap-customizable-styles) { .cdk-overlay-container, .cdk-global-overlay-wrapper { // Disable events from being captured on the overlay container. pointer-events: none; @@ -28,7 +40,10 @@ $backdrop-animation-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default; // The overlay-container is an invisible element which contains all individual overlays. .cdk-overlay-container { position: fixed; - z-index: $overlay-container-z-index; + + @include _conditional-layer($wrap-customizable-styles) { + z-index: $overlay-container-z-index; + } &:empty { // Hide the element when it doesn't have any child nodes. This doesn't @@ -44,7 +59,10 @@ $backdrop-animation-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default; .cdk-global-overlay-wrapper { display: flex; position: absolute; - z-index: $overlay-z-index; + + @include _conditional-layer($wrap-customizable-styles) { + z-index: $overlay-z-index; + } } // A single overlay pane. @@ -54,13 +72,16 @@ $backdrop-animation-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default; position: absolute; pointer-events: auto; box-sizing: border-box; - z-index: $overlay-z-index; // For connected-position overlays, we set `display: flex` in // order to force `max-width` and `max-height` to take effect. display: flex; max-width: 100%; max-height: 100%; + + @include _conditional-layer($wrap-customizable-styles) { + z-index: $overlay-z-index; + } } .cdk-overlay-backdrop { @@ -71,11 +92,14 @@ $backdrop-animation-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default; left: 0; right: 0; - z-index: $overlay-backdrop-z-index; pointer-events: auto; -webkit-tap-highlight-color: transparent; - transition: opacity $backdrop-animation-duration $backdrop-animation-timing-function; opacity: 0; + + @include _conditional-layer($wrap-customizable-styles) { + z-index: $overlay-backdrop-z-index; + transition: opacity $backdrop-animation-duration $backdrop-animation-timing-function; + } } .cdk-overlay-backdrop-showing { @@ -84,7 +108,7 @@ $backdrop-animation-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default; // Note that we can't import and use the `high-contrast` mixin from `_a11y.scss`, because // this file will be copied to the top-level `cdk` package when putting together the files // for npm. Any relative import paths we use here will become invalid once the file is copied. - .cdk-high-contrast-active & { + @media (forced-colors: active) { // In high contrast mode the rgba background will become solid // so we need to fall back to making it opaque using `opacity`. opacity: 0.6; @@ -92,8 +116,9 @@ $backdrop-animation-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default; } .cdk-overlay-dark-backdrop { - // Add a CSS variable to make this easier to override. - background: var(--cdk-overlay-backdrop-dark-color, $overlay-backdrop-color); + @include _conditional-layer($wrap-customizable-styles) { + background: $overlay-backdrop-color; + } } .cdk-overlay-transparent-backdrop { @@ -121,7 +146,6 @@ $backdrop-animation-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default; // overlay element's size to fit within the viewport. .cdk-overlay-connected-position-bounding-box { position: absolute; - z-index: $overlay-z-index; // We use `display: flex` on this element exclusively for centering connected overlays. // When *not* centering, a top/left/bottom/right will be set which overrides the normal @@ -135,6 +159,10 @@ $backdrop-animation-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default; // Add some dimensions so the element has an `innerText` which some people depend on in tests. min-width: 1px; min-height: 1px; + + @include _conditional-layer($wrap-customizable-styles) { + z-index: $overlay-z-index; + } } // Used when disabling global scrolling. @@ -152,3 +180,8 @@ $backdrop-animation-timing-function: cubic-bezier(0.25, 0.8, 0.25, 1) !default; overflow-y: scroll; } } + +/// Emits structural styles required for cdk/overlay to function. +@mixin overlay { + @include private-overlay-structure(false); +} diff --git a/src/cdk/overlay/overlay-container.ts b/src/cdk/overlay/overlay-container.ts index 5c27341638fb..e071cf3da78c 100644 --- a/src/cdk/overlay/overlay-container.ts +++ b/src/cdk/overlay/overlay-container.ts @@ -24,7 +24,7 @@ import {Platform, _isTestEnvironment} from '@angular/cdk/platform'; changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, standalone: true, - styleUrl: 'overlay-prebuilt.css', + styleUrl: 'overlay-structure.css', host: {'cdk-overlay-style-loader': ''}, }) export class _CdkOverlayStyleLoader {} diff --git a/src/cdk/overlay/overlay-structure.scss b/src/cdk/overlay/overlay-structure.scss new file mode 100644 index 000000000000..aaa4016ad998 --- /dev/null +++ b/src/cdk/overlay/overlay-structure.scss @@ -0,0 +1,3 @@ +@use './index' as overlay; + +@include overlay.private-overlay-structure(true);