Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,31 @@ Upgrade Guide

## EasyAdmin 5.2.0

### CSS Cascade Layers

All CSS styles of the backend are now assigned to [cascade layers](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer):
`vendor` (Bootstrap, Font Awesome and other third-party styles), `ea` (the
EasyAdmin styles, with the `ea.tokens`, `ea.base`, `ea.components` and
`ea.utilities` sublayers) and `ea-overrides` (a few special rules explained below).

Since unlayered CSS always wins over layered CSS, any custom styles you add
(e.g. with `addCssFile()`) now override the backend styles regardless of their
specificity or loading order. In practice this means:

* Most custom styles keep working as before, and overriding backend styles no
longer requires `!important` or artificially specific selectors; you can
safely remove those workarounds.
* If some global CSS of your application (e.g. a reset stylesheet or generic
rules like `button { ... }`) is loaded in the backend pages, it previously
lost against the more specific backend styles but now it wins. If the backend
looks different after upgrading, scope those global styles or assign them to
their own cascade layer.
* For `!important` declarations the layer order is inverted, so the few
`!important` rules that the backend still needs (defined in the `ea-overrides`
layer) now win over `!important` declarations in your unlayered custom CSS.
If one of your `!important` overrides stopped working, remove the
`!important` flag: the normal declaration now wins.

### HTML Markup Changes

The HTML markup of the boolean switch has changed. Before, the element wrapping
Expand Down
17 changes: 12 additions & 5 deletions assets/css/app.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
@import "~bootstrap/dist/css/bootstrap.min.css";
/* All styles are assigned to cascade layers so that any unlayered CSS added by
backend applications always overrides EasyAdmin styles, no matter its
specificity or loading order. The layer order is defined in layers.css,
which must be the first import */
@import "./layers.css";

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

@import "./easyadmin-theme/theme.css";
@import "~@fortawesome/fontawesome-free/css/all.css" layer(vendor.fontawesome);
@import "~@fortawesome/fontawesome-free/css/v4-shims.css" layer(vendor.fontawesome);
@import "~@fortawesome/fontawesome-free/css/v5-font-face.css" layer(vendor.fontawesome);

@import "./easyadmin-theme/vendor-overrides.css" layer(ea-overrides);
@import "./easyadmin-theme/theme.css" layer(ea);
23 changes: 7 additions & 16 deletions assets/css/easyadmin-theme/base.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ body {
i.fa,
i.fas,
i.far {
font-family: "Font Awesome 6 Free", sans-serif !important;
font-family: "Font Awesome 6 Free", sans-serif;
}
i.fab {
font-family: "Font Awesome 6 Brands", sans-serif !important;
font-family: "Font Awesome 6 Brands", sans-serif;
}
i.fal {
font-family: "Font Awesome 6 Pro", sans-serif !important;
font-family: "Font Awesome 6 Pro", sans-serif;
}
i.fad {
font-family: "Font Awesome 6 Duotone", sans-serif !important;
font-family: "Font Awesome 6 Duotone", sans-serif;
}
span.icon {
display: inline-block;
Expand Down Expand Up @@ -818,22 +818,13 @@ a.user-menu-wrapper .user-details:hover {
}

/* Utilities */
.text-primary {
color: var(--text-primary-color) !important;
}
.text-secondary {
color: var(--text-secondary-color) !important;
}
/* .text-primary, .text-secondary, .border-primary and .border-secondary are
redefined in vendor-overrides.css because they collide with Bootstrap
utilities declared with '!important' */
.text-tertiary {
color: var(--text-tertiary-color) !important;
}

.border-primary {
border: 1px solid var(--border-primary-color) !important;
}
.border-secondary {
border: 1px solid var(--border-secondary-color) !important;
}
.border-tertiary {
border: 1px solid var(--border-tertiary-color) !important;
}
Expand Down
14 changes: 4 additions & 10 deletions assets/css/easyadmin-theme/datagrids.css
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,8 @@ table.datagrid:not(.datagrid-empty) tr:not(.empty-row) td.actions.actions-as-dro
table.datagrid:not(.datagrid-empty) tr:not(.empty-row) td.actions.actions-as-dropdown:before {
display: none;
}
table.datagrid:not(.datagrid-empty) td {
/* because of how the contents are rendered in small screens, table contents must be left-aligned
the !important flag is needed to override the !important used by Bootstrap in .text-center, .text-right, etc. */
text-align: left !important;
}
/* the small-screen left-alignment of table.datagrid td contents lives in
vendor-overrides.css because it must defeat Bootstrap's '!important' utilities */
table.datagrid:not(.datagrid-empty) td::before {
content: attr(data-label);
color: var(--responsive-table-label-color);
Expand Down Expand Up @@ -353,11 +350,8 @@ table.datagrid:not(.datagrid-empty) tr:not(.empty-row) td.actions.actions-as-dro
padding: var(--ea-sp-1-5) var(--ea-sp-2);
}

@media (max-width: 992px) {
.datagrid .field-country {
text-align: left !important;
}
}
/* the small-screen left-alignment of .field-country lives in vendor-overrides.css
because it must defeat Bootstrap's '!important' utilities */
.datagrid .form-check {
margin-block-end: 0;
min-block-size: 15px;
Expand Down
47 changes: 26 additions & 21 deletions assets/css/easyadmin-theme/theme.css
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
@import "./color-palette.css";
@import "./design-tokens.css";
@import "./variables-theme.css";
/* This file is imported into the 'ea' layer (see app.css), so these sublayers
become ea.tokens, ea.base, ea.components and ea.utilities (their order is
defined in layers.css) */
@import "./color-palette.css" layer(tokens);
@import "./design-tokens.css" layer(tokens);
@import "./variables-theme.css" layer(tokens);

@import "./base.css";
@import "./action-menu.css";
@import "./pagination.css";
@import "./modals.css";
@import "./menu.css";
@import "./datagrids.css";
@import "./detail-page.css";
@import "./fields.css";
@import "./images.css";
@import "./forms.css";
@import "./buttons.css";
@import "./alerts.css";
@import "./badges.css";
@import "./switches.css";
@import "./autocomplete.css";
@import "./errors.css";
@import "./pages.css";
@import "./utilities.css";
@import "./base.css" layer(base);

@import "./action-menu.css" layer(components);
@import "./pagination.css" layer(components);
@import "./modals.css" layer(components);
@import "./menu.css" layer(components);
@import "./datagrids.css" layer(components);
@import "./detail-page.css" layer(components);
@import "./fields.css" layer(components);
@import "./images.css" layer(components);
@import "./forms.css" layer(components);
@import "./buttons.css" layer(components);
@import "./alerts.css" layer(components);
@import "./badges.css" layer(components);
@import "./switches.css" layer(components);
@import "./autocomplete.css" layer(components);
@import "./errors.css" layer(components);
@import "./pages.css" layer(components);

@import "./utilities.css" layer(utilities);
37 changes: 37 additions & 0 deletions assets/css/easyadmin-theme/vendor-overrides.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* For '!important' declarations, the cascade layer order is inverted: earlier
layers win over later ones. This file is loaded into the 'ea-overrides' layer,
declared before the 'vendor' layer, so its '!important' rules can defeat the
'!important' rules of Bootstrap utilities (something the 'ea' layer can't do).
Only '!important' rules may live here: a normal declaration in this layer
loses to every other layer. */

/* Bootstrap defines .text-primary, .text-secondary, .border-primary and
.border-secondary utilities with '!important'; redefine them to use the
EasyAdmin design tokens */
.text-primary {
color: var(--text-primary-color) !important;
}
.text-secondary {
color: var(--text-secondary-color) !important;
}

.border-primary {
border: 1px solid var(--border-primary-color) !important;
}
.border-secondary {
border: 1px solid var(--border-secondary-color) !important;
}

@media (max-width: 767px) {
table.datagrid:not(.datagrid-empty) td {
/* because of how the contents are rendered in small screens, table contents must be left-aligned
the !important flag is needed to override the !important used by Bootstrap in .text-center, .text-right, etc. */
text-align: left !important;
}
}

@media (max-width: 992px) {
.datagrid .field-country {
text-align: left !important;
}
}
Loading
Loading