Skip to content
Snippets Groups Projects
Verified Commit 34b0bcda authored by Théodore Biadala's avatar Théodore Biadala
Browse files

Issue #2998451 by bnjmnm, HOG, lauriii, ndf, gaurav-mathur, Ambient.Impact,...

Issue #2998451 by bnjmnm, HOG, lauriii, ndf, gaurav-mathur, Ambient.Impact, Chi, nod_, andy-blum, droplet: Toolbar tray rendering can result "flickering" resizing of content area to accommodate open trays
parent 0c59ee88
Branches
Tags
26 merge requests!12227Issue #3181946 by jonmcl, mglaman,!54479.5.x SF update,!5014Issue #3071143: Table Render Array Example Is Incorrect,!4868Issue #1428520: Improve menu parent link selection,!4289Issue #1344552 by marcingy, Niklas Fiekas, Ravi.J, aleevas, Eduardo Morales...,!4114Issue #2707291: Disable body-level scrolling when a dialog is open as a modal,!4100Issue #3249600: Add support for PHP 8.1 Enums as allowed values for list_* data types,!2378Issue #2875033: Optimize joins and table selection in SQL entity query implementation,!2334Issue #3228209: Add hasRole() method to AccountInterface,!2062Issue #3246454: Add weekly granularity to views date sort,!1591Issue #3199697: Add JSON:API Translation experimental module,!1484Exposed filters get values from URL when Ajax is on,!1255Issue #3238922: Refactor (if feasible) uses of the jQuery serialize function to use vanillaJS,!1105Issue #3025039: New non translatable field on translatable content throws error,!1073issue #3191727: Focus states on mobile second level navigation items fixed,!10223132456: Fix issue where views instances are emptied before an ajax request is complete,!925Issue #2339235: Remove taxonomy hard dependency on node module,!877Issue #2708101: Default value for link text is not saved,!872Draft: Issue #3221319: Race condition when creating menu links and editing content deletes menu links,!844Resolve #3036010 "Updaters",!617Issue #3043725: Provide a Entity Handler for user cancelation,!579Issue #2230909: Simple decimals fail to pass validation,!560Move callback classRemove outside of the loop,!555Issue #3202493,!485Sets the autocomplete attribute for username/password input field on login form.,!30Issue #3182188: Updates composer usage to point at ./vendor/bin/composer
Showing
with 452 additions and 80 deletions
......@@ -356,6 +356,9 @@ function shortcut_toolbar() {
'keys' => ['shortcut_set_toolbar_links'],
'contexts' => ['user'],
],
'#lazy_builder_preview' => [
'#markup' => '<a href="#" class="toolbar-tray-lazy-placeholder-link">&nbsp;</a>',
],
],
],
'#weight' => -10,
......
......@@ -79,23 +79,6 @@
right: 0;
left: 0;
}
/* .toolbar-loading is required by Toolbar JavaScript to pre-render markup
* style to avoid extra reflow & flicker. */
@media (min-width: 61em) {
.toolbar-loading.toolbar-horizontal .toolbar .toolbar-bar .toolbar-tab:last-child .toolbar-tray {
position: relative;
z-index: -999;
display: block;
visibility: hidden;
width: 1px;
}
.toolbar-loading.toolbar-horizontal .toolbar .toolbar-bar .toolbar-tab:last-child .toolbar-tray .toolbar-lining {
width: 999em;
}
.toolbar-loading.toolbar-horizontal .toolbar .toolbar-bar .home-toolbar-tab + .toolbar-tab .toolbar-tray {
display: block;
}
}
/* Layer the bar just above the trays and above contextual link triggers. */
.toolbar-oriented .toolbar-bar {
......@@ -103,13 +86,13 @@
}
/* Position the admin toolbar fixed when the configured standard breakpoint is
* active. */
body.toolbar-fixed .toolbar-oriented .toolbar-bar {
.toolbar-fixed .toolbar-oriented .toolbar-bar {
position: fixed;
}
/* When the configured narrow breakpoint is active, the toolbar is sized to wrap
* around the trays in order to provide a context for scrolling tray content
* that is taller than the viewport. */
body.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented {
.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented {
bottom: 0;
width: 240px;
width: 15rem;
......@@ -198,7 +181,7 @@ body.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented {
* the tray scroll within the confines of the viewport.
*/
.toolbar .toolbar-tray-vertical.is-active,
body.toolbar-fixed .toolbar .toolbar-tray-vertical {
.toolbar-fixed .toolbar .toolbar-tray-vertical {
position: fixed;
overflow-x: hidden;
overflow-y: auto;
......@@ -217,27 +200,16 @@ body.toolbar-fixed .toolbar .toolbar-tray-vertical {
}
/* When the configured standard breakpoint is active, the tray appears to push
* the page content away from the edge of the viewport. */
body.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
margin-left: 240px; /* LTR */
margin-left: 15rem; /* LTR */
.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
margin-inline-start: 15rem;
}
@media print {
body.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
margin-left: 0;
.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
margin-inline-start: 0;
}
}
[dir="rtl"] body.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
margin-right: 240px;
margin-right: 15rem;
margin-left: auto;
}
@media print {
[dir="rtl"] body.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
margin-right: 0;
}
}
/**
* ToolBar tray orientation toggle.
*/
......@@ -278,3 +250,46 @@ body.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
.path-admin .toolbar-bar .home-toolbar-tab {
display: block;
}
/* Anti flicker styling. */
.toolbar-anti-flicker.toolbar-loading.toolbar-fixed body {
padding-top: 2.4375rem;
}
.toolbar-anti-flicker.toolbar-loading.toolbar-fixed.toolbar-horizontal.toolbar-tray-open body {
padding-top: 4.91331rem;
}
.toolbar-anti-flicker.toolbar-loading.toolbar-vertical.toolbar-tray-open .toolbar-tray {
position: fixed;
z-index: -1;
top: 2.4375rem;
bottom: 0;
display: block;
width: 15rem;
inset-inline-start: 0;
}
.toolbar-tray-lazy-placeholder-link {
position: relative;
z-index: 0;
display: block;
}
.toolbar-tray-open.toolbar-fixed.toolbar-vertical #toolbar-administration {
margin-inline-start: -15rem;
}
.toolbar .toolbar-tray-vertical > .toolbar-lining::before {
width: 100%;
}
.toolbar-oriented .toolbar-tray-vertical > .toolbar-lining::before {
position: fixed;
z-index: -1;
top: 0;
bottom: 0;
display: block;
width: 15rem;
content: "";
inset-inline-start: 0;
}
.toolbar-anti-flicker.toolbar-vertical.toolbar-tray-open .menu-item + .menu-item {
border-top: 1px solid #ddd;
}
......@@ -4,6 +4,39 @@
*/
(function ($, Drupal, drupalSettings) {
// Set UI-impacting toolbar classes before Drupal behaviors initialize to
// minimize flickering on load. This is encapsulated in a function to
// emphasize this having a distinct purpose than the code that follows it.
(() => {
if (!sessionStorage.getItem('Drupal.toolbar.toolbarState')) {
return;
}
const toolbarState = JSON.parse(
sessionStorage.getItem('Drupal.toolbar.toolbarState'),
);
const { activeTray, orientation, isOriented } = toolbarState;
const activeTrayElement = document.querySelector(
`.toolbar-tray[data-toolbar-tray="${activeTray}"]`,
);
const activeTrayToggle = document.querySelector(
`.toolbar-item[data-toolbar-tray="${activeTray}"]`,
);
if (activeTrayElement) {
activeTrayElement.classList.add(
`toolbar-tray-${orientation}`,
'is-active',
);
activeTrayToggle.classList.add('is-active');
}
if (isOriented) {
document
.querySelector('#toolbar-administration')
.classList.add('toolbar-oriented');
}
})();
// Merge run-time settings with the defaults.
const options = $.extend(
{
......@@ -150,13 +183,20 @@
$(document).trigger('drupalToolbarTrayChange', tray);
});
// If the toolbar's orientation is horizontal and no active tab is
// defined then show the tray of the first toolbar tab by default (but
// not the first 'Home' toolbar tab).
const toolbarState = sessionStorage.getItem(
'Drupal.toolbar.toolbarState',
)
? JSON.parse(sessionStorage.getItem('Drupal.toolbar.toolbarState'))
: {};
// If the toolbar's orientation is horizontal, no active tab is defined,
// and the orientation state is not set (which means the user has not
// yet interacted with the toolbar), then show the tray of the first
// toolbar tab by default (but not the first 'Home' toolbar tab).
if (
Drupal.toolbar.models.toolbarModel.get('orientation') ===
'horizontal' &&
Drupal.toolbar.models.toolbarModel.get('activeTab') === null
Drupal.toolbar.models.toolbarModel.get('activeTab') === null &&
!toolbarState.orientation
) {
Drupal.toolbar.models.toolbarModel.set({
activeTab: $(
......@@ -190,6 +230,42 @@
},
});
});
// Add anti-flicker functionality.
if (
once('toolbarAntiFlicker', '#toolbar-administration', context).length
) {
Drupal.toolbar.models.toolbarModel.on(
'change:activeTab change:orientation change:isOriented change:isTrayToggleVisible change:offsets',
function () {
const hasActiveTab = !!$(this.get('activeTab')).length > 0;
const previousToolbarState = sessionStorage.getItem(
'Drupal.toolbar.toolbarState',
)
? JSON.parse(
sessionStorage.getItem('Drupal.toolbar.toolbarState'),
)
: {};
const toolbarState = {
...previousToolbarState,
orientation:
Drupal.toolbar.models.toolbarModel.get('orientation'),
hasActiveTab,
activeTabId: hasActiveTab ? this.get('activeTab').id : null,
activeTray: $(this.get('activeTab')).attr('data-toolbar-tray'),
isOriented: this.get('isOriented'),
isFixed: this.get('isFixed'),
};
// Store toolbar UI state in session storage, so it can be accessed
// by JavaScript that executes before the first paint.
// @see core/modules/toolbar/js/toolbar.anti-flicker.js
sessionStorage.setItem(
'Drupal.toolbar.toolbarState',
JSON.stringify(toolbarState),
);
},
);
}
},
};
......
......@@ -113,7 +113,11 @@
});
$item
.children('.toolbar-box')
.append(Drupal.theme('toolbarMenuItemToggle', options));
.append(
$(Drupal.theme('toolbarMenuItemToggle', options))
.hide()
.fadeIn(150),
);
}
});
}
......
......@@ -114,6 +114,16 @@
this.updateTrayOrientation();
this.updateBarAttributes();
$('[data-toolbar-anti-flicker-loading]').remove();
$('html').removeClass([
'toolbar-loading',
'toolbar-horizontal',
'toolbar-vertical',
'toolbar-tray-open',
'toolbar-fixed',
'toolbar-oriented',
'toolbar-anti-flicker',
]);
$('body').removeClass('toolbar-loading');
// Load the subtrees if the orientation of the toolbar is changed to
......@@ -208,6 +218,9 @@
// Deactivate the previous tray.
$(this.model.previous('activeTray')).removeClass('is-active');
// The stored active tab is removed as updateTabs() can be called when
// a tray is explicitly closed, thus not replaced with a new active tab.
localStorage.removeItem('Drupal.toolbar.activeTabID');
// Activate the selected tab.
if ($tab.length > 0) {
$tab
......
<?php
namespace Drupal\Tests\toolbar\FunctionalJavascript;
use Drupal\Component\Serialization\Json;
use Drupal\FunctionalJavascriptTests\WebDriverTestBase;
/**
* Tests the sessionStorage state set by the toolbar.
*
* @group toolbar
*/
class ToolbarStoredStateTest extends WebDriverTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = ['toolbar', 'node'];
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
public function testToolbarStoredState() {
$admin_user = $this->drupalCreateUser([
'access toolbar',
'administer site configuration',
'access content overview',
]);
$this->drupalLogin($admin_user);
$page = $this->getSession()->getPage();
$assert_session = $this->assertSession();
$this->drupalGet('<front>');
$this->assertNotEmpty($this->assertSession()->waitForElement('css', 'body.toolbar-horizontal'));
$this->assertNotEmpty($this->assertSession()->waitForElementVisible('css', '.toolbar-tray'));
$this->assertSession()->waitForElementRemoved('css', '.toolbar-loading');
$page->clickLink('toolbar-item-user');
$this->assertNotEmpty($assert_session->waitForElementVisible('css', '#toolbar-item-user.is-active'));
// Expected state values with the user tray open with horizontal
// orientation.
$expected = [
'orientation' => 'horizontal',
'hasActiveTab' => TRUE,
'activeTabId' => 'toolbar-item-user',
'activeTray' => 'toolbar-item-user-tray',
'isOriented' => TRUE,
'isFixed' => TRUE,
];
$toolbar_stored_state = JSON::decode(
$this->getSession()->evaluateScript("sessionStorage.getItem('Drupal.toolbar.toolbarState')")
);
$this->assertSame($expected, $toolbar_stored_state);
$page->clickLink('toolbar-item-user');
$assert_session->assertNoElementAfterWait('css', '#toolbar-item-user.is-active');
// Update expected state values to reflect no tray being open.
$expected['hasActiveTab'] = FALSE;
$expected['activeTabId'] = NULL;
unset($expected['activeTray']);
$toolbar_stored_state = JSON::decode(
$this->getSession()->evaluateScript("sessionStorage.getItem('Drupal.toolbar.toolbarState')")
);
$this->assertSame($expected, $toolbar_stored_state);
$page->clickLink('toolbar-item-administration');
$orientation_toggle = $assert_session->waitForElementVisible('css', '[title="Vertical orientation"]');
$orientation_toggle->click();
$assert_session->waitForElementVisible('css', 'body.toolbar-vertical');
// Update expected state values to reflect the administration tray being
// open with vertical orientation.
$expected['orientation'] = 'vertical';
$expected['hasActiveTab'] = TRUE;
$expected['activeTabId'] = 'toolbar-item-administration';
$expected['activeTray'] = 'toolbar-item-administration-tray';
$toolbar_stored_state = JSON::decode(
$this->getSession()->evaluateScript("sessionStorage.getItem('Drupal.toolbar.toolbarState')")
);
$this->assertSame($expected, $toolbar_stored_state);
$this->getSession()->resizeWindow(600, 600);
// Update expected state values to reflect the viewport being at a width
// that is narrow enough that the toolbar isn't fixed.
$expected['isFixed'] = FALSE;
$toolbar_stored_state = JSON::decode(
$this->getSession()->evaluateScript("sessionStorage.getItem('Drupal.toolbar.toolbarState')")
);
$this->assertSame($expected, $toolbar_stored_state);
}
}
......@@ -7,6 +7,7 @@
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Render\Element;
use Drupal\Core\Render\Markup;
use Drupal\Core\Render\RenderContext;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Template\Attribute;
......@@ -48,6 +49,94 @@ function toolbar_theme($existing, $type, $theme, $path) {
return $items;
}
/**
* Implements hook_page_attachments().
*/
function toolbar_page_attachments(array &$page) {
// This JavaScript code provides temporary styles while the toolbar loads, so
// it better visually resembles the appearance it will have once fully loaded.
// @todo investigate potential alternatives to this approach in
// https://www.drupal.org/i/3355381
$anti_flicker_js = <<<JS
(function() {
const toolbarState = sessionStorage.getItem('Drupal.toolbar.toolbarState')
? JSON.parse(sessionStorage.getItem('Drupal.toolbar.toolbarState'))
: false;
// These are classes that toolbar typically adds to <body>, but this code
// executes before the first paint, when <body> is not yet present. The
// classes are added to <html> so styling immediately reflects the current
// toolbar state. The classes are removed after the toolbar completes
// initialization.
const classesToAdd = ['toolbar-loading', 'toolbar-anti-flicker'];
if (toolbarState) {
const {
orientation,
hasActiveTab,
isFixed,
activeTray,
activeTabId,
isOriented,
} = toolbarState;
classesToAdd.push(
orientation ? `toolbar-` + orientation + `` : 'toolbar-horizontal',
);
if (hasActiveTab !== false) {
classesToAdd.push('toolbar-tray-open');
}
if (isFixed) {
classesToAdd.push('toolbar-fixed');
}
if (isOriented) {
classesToAdd.push('toolbar-oriented');
}
if (activeTray) {
// These styles are added so the active tab/tray styles are present
// immediately instead of "flickering" on as the toolbar initializes. In
// instances where a tray is lazy loaded, these styles facilitate the
// lazy loaded tray appearing gracefully and without reflow.
const styleContent = `
.toolbar-loading #` + activeTabId + ` {
background-image: linear-gradient(rgba(255, 255, 255, 0.25) 20%, transparent 200%);
}
.toolbar-loading #` + activeTabId + `-tray {
display: block; box-shadow: -1px 0 5px 2px rgb(0 0 0 / 33%);
border-right: 1px solid #aaa; background-color: #f5f5f5;
z-index: 0;
}
.toolbar-loading.toolbar-vertical.toolbar-tray-open #` + activeTabId + `-tray {
width: 15rem; height: 100vh;
}
.toolbar-loading.toolbar-horizontal :not(#` + activeTray + `) > .toolbar-lining {opacity: 0}`;
const style = document.createElement('style');
style.textContent = styleContent;
style.setAttribute('data-toolbar-anti-flicker-loading', true);
document.querySelector('head').appendChild(style);
}
}
document.querySelector('html').classList.add(...classesToAdd);
})();
JS;
// The anti flicker javascript is added as an inline tag so it is executed
// as early as possible. This enables it to add classes that prevent
// flickering before the first paint.
$page['#attached']['html_head'][] = [
[
'#tag' => 'script',
'#attributes' => [
'type' => 'text/javascript',
'data-toolbar-anti-flicker-loading' => TRUE,
],
// Process through Markup to prevent character escaping.
'#value' => Markup::create($anti_flicker_js),
],
'anti_flicker_js',
];
}
/**
* Implements hook_page_top().
*
......@@ -252,9 +341,7 @@ function toolbar_preprocess_html(&$variables) {
if (!\Drupal::currentUser()->hasPermission('access toolbar')) {
return;
}
$variables['attributes']['class'][] = 'toolbar-tray-open';
$variables['attributes']['class'][] = 'toolbar-horizontal';
$variables['attributes']['class'][] = 'toolbar-fixed';
$variables['attributes']['class'][] = 'toolbar-loading';
}
......
......@@ -1203,6 +1203,9 @@ function user_toolbar() {
$items['user']['tray']['user_links'] = [
'#lazy_builder' => ['user.toolbar_link_builder:renderToolbarLinks', []],
'#create_placeholder' => TRUE,
'#lazy_builder_preview' => [
'#markup' => '<a href="#" class="toolbar-tray-lazy-placeholder-link">&nbsp;</a>',
],
];
}
......
......@@ -104,22 +104,16 @@
visibility: hidden;
width: 1px;
}
.toolbar-loading.toolbar-horizontal .toolbar .toolbar-bar .toolbar-tab:last-child .toolbar-tray .toolbar-lining {
width: 999em;
}
.toolbar-loading.toolbar-horizontal .toolbar .toolbar-bar .home-toolbar-tab + .toolbar-tab .toolbar-tray {
display: block;
}
}
/* Position the admin toolbar fixed when the configured standard breakpoint is
* active. */
body.toolbar-fixed .toolbar-oriented .toolbar-bar {
.toolbar-fixed .toolbar-oriented .toolbar-bar {
position: fixed;
}
/* When the configured narrow breakpoint is active, the toolbar is sized to wrap
* around the trays in order to provide a context for scrolling tray content
* that is taller than the viewport. */
body.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented {
.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented {
inset-block-end: 0;
width: 15rem;
}
......@@ -184,7 +178,7 @@ body.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented {
* the tray scroll within the confines of the viewport.
*/
.toolbar .toolbar-tray-vertical.is-active,
body.toolbar-fixed .toolbar .toolbar-tray-vertical {
.toolbar-fixed .toolbar .toolbar-tray-vertical {
position: fixed;
overflow-x: hidden;
overflow-y: auto;
......@@ -199,12 +193,12 @@ body.toolbar-fixed .toolbar .toolbar-tray-vertical {
}
/* When the configured standard breakpoint is active, the tray appears to push
* the page content away from the edge of the viewport. */
body.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
margin-inline-start: 15rem;
}
@media print {
body.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
margin-inline-start: 0;
}
}
......@@ -243,3 +237,43 @@ body.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
.path-admin .toolbar-bar .home-toolbar-tab {
display: block;
}
/* Anti flicker styling. */
.toolbar-anti-flicker.toolbar-loading.toolbar-fixed body {
padding-top: 2.4375rem;
}
.toolbar-anti-flicker.toolbar-loading.toolbar-fixed.toolbar-horizontal.toolbar-tray-open body {
padding-top: 4.91331rem;
}
.toolbar-anti-flicker.toolbar-vertical.toolbar-tray-open .menu-item + .menu-item {
border-top: 1px solid #ddd;
}
.toolbar-loading.toolbar-vertical.toolbar-tray-open .toolbar-tray {
position: fixed;
z-index: -1;
top: 2.4375rem;
bottom: 0;
display: block;
width: 15rem;
inset-inline-start: 0;
}
.toolbar-tray-lazy-placeholder-link {
position: relative;
z-index: 0;
display: block;
}
.toolbar-tray-open.toolbar-fixed.toolbar-vertical #toolbar-administration {
margin-inline-start: -15rem;
}
.toolbar .toolbar-tray-vertical > .toolbar-lining::before {
width: 100%;
}
.toolbar-oriented .toolbar-tray-vertical > .toolbar-lining::before {
position: fixed;
z-index: -1;
top: 0;
bottom: 0;
display: block;
width: 15rem;
content: "";
inset-inline-start: 0;
}
......@@ -110,23 +110,17 @@
visibility: hidden;
width: 1px;
}
.toolbar-loading.toolbar-horizontal .toolbar .toolbar-bar .toolbar-tab:last-child .toolbar-tray .toolbar-lining {
width: 999em;
}
.toolbar-loading.toolbar-horizontal .toolbar .toolbar-bar .home-toolbar-tab + .toolbar-tab .toolbar-tray {
display: block;
}
}
/* Position the admin toolbar fixed when the configured standard breakpoint is
* active. */
body.toolbar-fixed .toolbar-oriented .toolbar-bar {
.toolbar-fixed .toolbar-oriented .toolbar-bar {
position: fixed;
}
/* When the configured narrow breakpoint is active, the toolbar is sized to wrap
* around the trays in order to provide a context for scrolling tray content
* that is taller than the viewport. */
body.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented {
.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented {
inset-block-end: 0;
width: 15rem;
}
......@@ -199,7 +193,7 @@ body.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented {
* the tray scroll within the confines of the viewport.
*/
.toolbar .toolbar-tray-vertical.is-active,
body.toolbar-fixed .toolbar .toolbar-tray-vertical {
.toolbar-fixed .toolbar .toolbar-tray-vertical {
position: fixed;
overflow-x: hidden;
overflow-y: auto;
......@@ -218,17 +212,13 @@ body.toolbar-fixed .toolbar .toolbar-tray-vertical {
}
/* When the configured standard breakpoint is active, the tray appears to push
* the page content away from the edge of the viewport. */
body {
&.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
margin-inline-start: 15rem;
}
.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
margin-inline-start: 15rem;
}
@media print {
body {
&.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
margin-inline-start: 0;
}
.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
margin-inline-start: 0;
}
}
......@@ -291,3 +281,45 @@ body {
}
}
}
/* Anti flicker styling. */
.toolbar-anti-flicker.toolbar-loading.toolbar-fixed body {
padding-top: 2.4375rem;
}
.toolbar-anti-flicker.toolbar-loading.toolbar-fixed.toolbar-horizontal.toolbar-tray-open body {
padding-top: 4.91331rem;
}
.toolbar-anti-flicker.toolbar-vertical.toolbar-tray-open .menu-item + .menu-item {
border-top: 1px solid #ddd;
}
.toolbar-loading.toolbar-vertical.toolbar-tray-open .toolbar-tray {
position: fixed;
z-index: -1;
top: 2.4375rem;
bottom: 0;
display: block;
width: 15rem;
inset-inline-start: 0;
}
.toolbar-tray-lazy-placeholder-link {
position: relative;
z-index: 0;
display: block;
}
.toolbar-tray-open.toolbar-fixed.toolbar-vertical #toolbar-administration {
margin-inline-start: -15rem;
}
.toolbar .toolbar-tray-vertical > .toolbar-lining::before {
width: 100%;
}
.toolbar-oriented .toolbar-tray-vertical > .toolbar-lining::before {
position: fixed;
z-index: -1;
top: 0;
bottom: 0;
display: block;
width: 15rem;
content: "";
inset-inline-start: 0;
}
......@@ -22,7 +22,7 @@
box-shadow: 36px 1px 36px rgba(0, 0, 0, 0.08);
}
body.toolbar-vertical.toolbar-tray-open .node-preview-container {
.toolbar-vertical.toolbar-tray-open .node-preview-container {
max-width: calc(100vw - var(--toolbar-tray-vertical-width) - var(--scrollbar-width));
}
......
......@@ -17,7 +17,7 @@
box-shadow: 36px 1px 36px rgba(0, 0, 0, 0.08);
}
body.toolbar-vertical.toolbar-tray-open .node-preview-container {
.toolbar-vertical.toolbar-tray-open .node-preview-container {
max-width: calc(100vw - var(--toolbar-tray-vertical-width) - var(--scrollbar-width));
}
......
......@@ -103,13 +103,15 @@
}
/* Position the admin toolbar fixed when the configured standard breakpoint is
* active. */
body.toolbar-fixed .toolbar-oriented .toolbar-bar {
body.toolbar-fixed .toolbar-oriented .toolbar-bar,
html.toolbar-fixed .toolbar-oriented .toolbar-bar {
position: fixed;
}
/* When the configured narrow breakpoint is active, the toolbar is sized to wrap
* around the trays in order to provide a context for scrolling tray content
* that is taller than the viewport. */
body.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented {
body.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented,
html.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented {
bottom: 0;
width: 240px;
width: 15rem;
......@@ -198,7 +200,8 @@ body.toolbar-tray-open.toolbar-fixed.toolbar-vertical .toolbar-oriented {
* the tray scroll within the confines of the viewport.
*/
.toolbar .toolbar-tray-vertical.is-active,
body.toolbar-fixed .toolbar .toolbar-tray-vertical {
body.toolbar-fixed .toolbar .toolbar-tray-vertical,
html.toolbar-fixed .toolbar .toolbar-tray-vertical {
position: fixed;
overflow-x: hidden;
overflow-y: auto;
......@@ -217,24 +220,28 @@ body.toolbar-fixed .toolbar .toolbar-tray-vertical {
}
/* When the configured standard breakpoint is active, the tray appears to push
* the page content away from the edge of the viewport. */
body.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
body.toolbar-tray-open.toolbar-vertical.toolbar-fixed,
html.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
margin-left: 240px; /* LTR */
margin-left: 15rem; /* LTR */
}
@media print {
body.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
body.toolbar-tray-open.toolbar-vertical.toolbar-fixed,
html.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
margin-left: 0;
}
}
[dir="rtl"] body.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
[dir="rtl"] body.toolbar-tray-open.toolbar-vertical.toolbar-fixed,
[dir="rtl"].toolbar-tray-open.toolbar-vertical.toolbar-fixed {
margin-right: 240px;
margin-right: 15rem;
margin-left: auto;
}
@media print {
[dir="rtl"] body.toolbar-tray-open.toolbar-vertical.toolbar-fixed {
[dir="rtl"] body.toolbar-tray-open.toolbar-vertical.toolbar-fixed,
[dir="rtl"].toolbar-tray-open.toolbar-vertical.toolbar-fixed {
margin-right: 0;
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment