Skip to content

Commit a809ac3

Browse files
committed
Update CSS to use layers
1 parent 621dd52 commit a809ac3

18 files changed

Lines changed: 392 additions & 291 deletions

UPGRADE.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,33 @@
11
Upgrade Guide
22
=============
33

4+
## EasyAdmin 5.3.0
5+
6+
### CSS Cascade Layers
7+
8+
All CSS styles of the backend are now assigned to [cascade layers](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer):
9+
`vendor` (Bootstrap, Font Awesome and other third-party styles), `ea` (the
10+
EasyAdmin styles, with the `ea.tokens`, `ea.base`, `ea.components` and
11+
`ea.utilities` sublayers) and `ea-overrides` (a few special rules explained below).
12+
13+
Since unlayered CSS always wins over layered CSS, any custom styles you add
14+
(e.g. with `addCssFile()`) now override the backend styles regardless of their
15+
specificity or loading order. In practice this means:
16+
17+
* Most custom styles keep working as before, and overriding backend styles no
18+
longer requires `!important` or artificially specific selectors; you can
19+
safely remove those workarounds.
20+
* If some global CSS of your application (e.g. a reset stylesheet or generic
21+
rules like `button { ... }`) is loaded in the backend pages, it previously
22+
lost against the more specific backend styles but now it wins. If the backend
23+
looks different after upgrading, scope those global styles or assign them to
24+
their own cascade layer.
25+
* For `!important` declarations the layer order is inverted, so the few
26+
`!important` rules that the backend still needs (defined in the `ea-overrides`
27+
layer) now win over `!important` declarations in your unlayered custom CSS.
28+
If one of your `!important` overrides stopped working, remove the
29+
`!important` flag: the normal declaration now wins.
30+
431
## EasyAdmin 5.2.0
532

633
### HTML Markup Changes

assets/css/app.css

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
1-
@import "~bootstrap/dist/css/bootstrap.min.css";
1+
/* All styles are assigned to cascade layers so that any unlayered CSS added by
2+
backend applications always overrides EasyAdmin styles, no matter its
3+
specificity or loading order. The layer order is defined in layers.css,
4+
which must be the first import */
5+
@import "./layers.css";
26

3-
@import "~@fortawesome/fontawesome-free/css/all.css";
4-
@import "~@fortawesome/fontawesome-free/css/v4-shims.css";
5-
@import "~@fortawesome/fontawesome-free/css/v5-font-face.css";
7+
@import "~bootstrap/dist/css/bootstrap.min.css" layer(vendor.bootstrap);
68

7-
@import "./easyadmin-theme/theme.css";
9+
@import "~@fortawesome/fontawesome-free/css/all.css" layer(vendor.fontawesome);
10+
@import "~@fortawesome/fontawesome-free/css/v4-shims.css" layer(vendor.fontawesome);
11+
@import "~@fortawesome/fontawesome-free/css/v5-font-face.css" layer(vendor.fontawesome);
12+
13+
@import "./easyadmin-theme/vendor-overrides.css" layer(ea-overrides);
14+
@import "./easyadmin-theme/theme.css" layer(ea);

assets/css/easyadmin-theme/base.css

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,16 @@ body {
2121
i.fa,
2222
i.fas,
2323
i.far {
24-
font-family: "Font Awesome 6 Free", sans-serif !important;
24+
font-family: "Font Awesome 6 Free", sans-serif;
2525
}
2626
i.fab {
27-
font-family: "Font Awesome 6 Brands", sans-serif !important;
27+
font-family: "Font Awesome 6 Brands", sans-serif;
2828
}
2929
i.fal {
30-
font-family: "Font Awesome 6 Pro", sans-serif !important;
30+
font-family: "Font Awesome 6 Pro", sans-serif;
3131
}
3232
i.fad {
33-
font-family: "Font Awesome 6 Duotone", sans-serif !important;
33+
font-family: "Font Awesome 6 Duotone", sans-serif;
3434
}
3535
span.icon {
3636
display: inline-block;
@@ -818,22 +818,13 @@ a.user-menu-wrapper .user-details:hover {
818818
}
819819

820820
/* Utilities */
821-
.text-primary {
822-
color: var(--text-primary-color) !important;
823-
}
824-
.text-secondary {
825-
color: var(--text-secondary-color) !important;
826-
}
821+
/* .text-primary, .text-secondary, .border-primary and .border-secondary are
822+
redefined in vendor-overrides.css because they collide with Bootstrap
823+
utilities declared with '!important' */
827824
.text-tertiary {
828825
color: var(--text-tertiary-color) !important;
829826
}
830827

831-
.border-primary {
832-
border: 1px solid var(--border-primary-color) !important;
833-
}
834-
.border-secondary {
835-
border: 1px solid var(--border-secondary-color) !important;
836-
}
837828
.border-tertiary {
838829
border: 1px solid var(--border-tertiary-color) !important;
839830
}

assets/css/easyadmin-theme/datagrids.css

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,8 @@ table.datagrid:not(.datagrid-empty) tr:not(.empty-row) td.actions.actions-as-dro
5959
table.datagrid:not(.datagrid-empty) tr:not(.empty-row) td.actions.actions-as-dropdown:before {
6060
display: none;
6161
}
62-
table.datagrid:not(.datagrid-empty) td {
63-
/* because of how the contents are rendered in small screens, table contents must be left-aligned
64-
the !important flag is needed to override the !important used by Bootstrap in .text-center, .text-right, etc. */
65-
text-align: left !important;
66-
}
62+
/* the small-screen left-alignment of table.datagrid td contents lives in
63+
vendor-overrides.css because it must defeat Bootstrap's '!important' utilities */
6764
table.datagrid:not(.datagrid-empty) td::before {
6865
content: attr(data-label);
6966
color: var(--responsive-table-label-color);
@@ -353,11 +350,8 @@ table.datagrid:not(.datagrid-empty) tr:not(.empty-row) td.actions.actions-as-dro
353350
padding: var(--ea-sp-1-5) var(--ea-sp-2);
354351
}
355352

356-
@media (max-width: 992px) {
357-
.datagrid .field-country {
358-
text-align: left !important;
359-
}
360-
}
353+
/* the small-screen left-alignment of .field-country lives in vendor-overrides.css
354+
because it must defeat Bootstrap's '!important' utilities */
361355
.datagrid .form-check {
362356
margin-block-end: 0;
363357
min-block-size: 15px;
Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
1-
@import "./color-palette.css";
2-
@import "./design-tokens.css";
3-
@import "./variables-theme.css";
1+
/* This file is imported into the 'ea' layer (see app.css), so these sublayers
2+
become ea.tokens, ea.base, ea.components and ea.utilities (their order is
3+
defined in layers.css) */
4+
@import "./color-palette.css" layer(tokens);
5+
@import "./design-tokens.css" layer(tokens);
6+
@import "./variables-theme.css" layer(tokens);
47

5-
@import "./base.css";
6-
@import "./action-menu.css";
7-
@import "./pagination.css";
8-
@import "./modals.css";
9-
@import "./menu.css";
10-
@import "./datagrids.css";
11-
@import "./detail-page.css";
12-
@import "./fields.css";
13-
@import "./images.css";
14-
@import "./forms.css";
15-
@import "./buttons.css";
16-
@import "./alerts.css";
17-
@import "./badges.css";
18-
@import "./switches.css";
19-
@import "./autocomplete.css";
20-
@import "./errors.css";
21-
@import "./pages.css";
22-
@import "./utilities.css";
8+
@import "./base.css" layer(base);
9+
10+
@import "./action-menu.css" layer(components);
11+
@import "./pagination.css" layer(components);
12+
@import "./modals.css" layer(components);
13+
@import "./menu.css" layer(components);
14+
@import "./datagrids.css" layer(components);
15+
@import "./detail-page.css" layer(components);
16+
@import "./fields.css" layer(components);
17+
@import "./images.css" layer(components);
18+
@import "./forms.css" layer(components);
19+
@import "./buttons.css" layer(components);
20+
@import "./alerts.css" layer(components);
21+
@import "./badges.css" layer(components);
22+
@import "./switches.css" layer(components);
23+
@import "./autocomplete.css" layer(components);
24+
@import "./errors.css" layer(components);
25+
@import "./pages.css" layer(components);
26+
27+
@import "./utilities.css" layer(utilities);
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/* For '!important' declarations, the cascade layer order is inverted: earlier
2+
layers win over later ones. This file is loaded into the 'ea-overrides' layer,
3+
declared before the 'vendor' layer, so its '!important' rules can defeat the
4+
'!important' rules of Bootstrap utilities (something the 'ea' layer can't do).
5+
Only '!important' rules may live here: a normal declaration in this layer
6+
loses to every other layer. */
7+
8+
/* Bootstrap defines .text-primary, .text-secondary, .border-primary and
9+
.border-secondary utilities with '!important'; redefine them to use the
10+
EasyAdmin design tokens */
11+
.text-primary {
12+
color: var(--text-primary-color) !important;
13+
}
14+
.text-secondary {
15+
color: var(--text-secondary-color) !important;
16+
}
17+
18+
.border-primary {
19+
border: 1px solid var(--border-primary-color) !important;
20+
}
21+
.border-secondary {
22+
border: 1px solid var(--border-secondary-color) !important;
23+
}
24+
25+
@media (max-width: 767px) {
26+
table.datagrid:not(.datagrid-empty) td {
27+
/* because of how the contents are rendered in small screens, table contents must be left-aligned
28+
the !important flag is needed to override the !important used by Bootstrap in .text-center, .text-right, etc. */
29+
text-align: left !important;
30+
}
31+
}
32+
33+
@media (max-width: 992px) {
34+
.datagrid .field-country {
35+
text-align: left !important;
36+
}
37+
}

0 commit comments

Comments
 (0)