Skip to content

Commit

Permalink
fix(cdk/overlay): load structural styles in a cascade layer (#29725)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
crisbeto authored Sep 12, 2024
1 parent b8ec0a6 commit 560878a
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 14 deletions.
11 changes: 9 additions & 2 deletions src/cdk/overlay/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ ng_module(
exclude = ["**/*.spec.ts"],
),
assets = [
":overlay-prebuilt.css",
":overlay-structure.css",
],
deps = [
"//src:dev_mode_types",
Expand All @@ -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",
],
)

Expand Down
55 changes: 44 additions & 11 deletions src/cdk/overlay/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand All @@ -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.
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -84,16 +108,17 @@ $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;
}
}

.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 {
Expand Down Expand Up @@ -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
Expand All @@ -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.
Expand All @@ -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);
}
2 changes: 1 addition & 1 deletion src/cdk/overlay/overlay-container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,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 {}
Expand Down
7 changes: 7 additions & 0 deletions src/cdk/overlay/overlay-structure.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@use './index' as overlay;

// We don't emit the layer internally, because all the breaking changes
// have been resolved already and the `@layer` seems to break some targets.
$_is-external-build: true;

@include overlay.private-overlay-structure($_is-external-build);

0 comments on commit 560878a

Please sign in to comment.