diff --git a/core/modules/views_ui/css/views_ui.admin.css b/core/modules/views_ui/css/views_ui.admin.css index 2507d306578a24111649bd9b903baf54ea416d11..aca14d88bf69a58b7663c993784d79ba351eeb7e 100644 --- a/core/modules/views_ui/css/views_ui.admin.css +++ b/core/modules/views_ui/css/views_ui.admin.css @@ -206,3 +206,30 @@ html.js span.js-only { .js .views-edit-view .dropbutton-wrapper { width: auto; } + +/* JS moves Views action buttons under a secondary tabs container, which causes +a large layout shift. We mitigate this by using animations to temporarily hide +the buttons, but they will appear after a set amount of time just in case the JS +is loaded but does not properly run. */ +@media (scripting: enabled) { + .views-tabs__action-list-button:not(.views-tabs--secondary *) { + animation-name: appear; + animation-duration: 0.1s; + /* Buttons will be hidden for the amount of time in the animation-delay if + not moved. Note this is the approximate time to download the views + aggregate CSS with slow 3G. */ + animation-delay: 5s; + animation-iteration-count: 1; + animation-fill-mode: backwards; + } +} + +@keyframes appear { + from { + display: none; + } + + to { + display: unset; + } +} diff --git a/core/themes/claro/css/components/views-ui.css b/core/themes/claro/css/components/views-ui.css index ae0bb5a0afee215746c66ecb8dbc8e94d0845df9..3b4a505af00f9873b9e89929b37df2516dd220cd 100644 --- a/core/themes/claro/css/components/views-ui.css +++ b/core/themes/claro/css/components/views-ui.css @@ -406,6 +406,34 @@ details.fieldset-no-legend { font-weight: normal; } +/* JS moves Views action buttons under a secondary tabs container, which causes +a large layout shift. We mitigate this by using animations to temporarily hide +the buttons, but they will appear after a set amount of time just in case the JS +is loaded but does not properly run. */ + +@media (scripting: enabled) { + .views-tabs__action-list-button:not(.views-tabs--secondary *) { + animation-name: appear; + animation-duration: 0.1s; + /* Buttons will be hidden for the amount of time in the animation-delay if + not moved. Note this is the approximate time to download the views + aggregate CSS with slow 3G. */ + animation-delay: 5s; + animation-iteration-count: 1; + animation-fill-mode: backwards; + } +} + +@keyframes appear { + from { + display: none; + } + + to { + display: unset; + } +} + /* RTL required for precedence over core's styles. */ [dir="rtl"] .views-tabs__action-list-button { diff --git a/core/themes/claro/css/components/views-ui.pcss.css b/core/themes/claro/css/components/views-ui.pcss.css index eec7ad688ac2975f9d6f2ce0b92542ddb4e7b036..1537a1f93f307fbd2300edda5da8bf5b23a84387 100644 --- a/core/themes/claro/css/components/views-ui.pcss.css +++ b/core/themes/claro/css/components/views-ui.pcss.css @@ -350,6 +350,34 @@ details.fieldset-no-legend { background: none repeat scroll 0 0 transparent; font-weight: normal; } + +/* JS moves Views action buttons under a secondary tabs container, which causes +a large layout shift. We mitigate this by using animations to temporarily hide +the buttons, but they will appear after a set amount of time just in case the JS +is loaded but does not properly run. */ +@media (scripting: enabled) { + .views-tabs__action-list-button:not(.views-tabs--secondary *) { + animation-name: appear; + animation-duration: 0.1s; + /* Buttons will be hidden for the amount of time in the animation-delay if + not moved. Note this is the approximate time to download the views + aggregate CSS with slow 3G. */ + animation-delay: 5s; + animation-iteration-count: 1; + animation-fill-mode: backwards; + } +} + +@keyframes appear { + from { + display: none; + } + + to { + display: unset; + } +} + /* RTL required for precedence over core's styles. */ [dir="rtl"] .views-tabs__action-list-button { margin: 0;