Drupal.displace() (see https://git.drupalcode.org/project/drupal/-/blob/9.4.x/core/misc/displac...) is a method that allows JavaScript to query for the offsets of fixed admin elements on the page.
For example,
- if the Admin Toolbar is active, running
Drupal.displace()will return{top: 79, right: 0, bottom: 0, left: 0}. - If the Settings Tray and Admin Toolbar are open, running
Drupal.displace()will return{top: 79, right: 300, bottom: 0, left: 0}.
Problem
When creating themes for Drupal, themers frequently want to place fixed items against the top of the viewport (or other edges). This will cause the fixed element to overlap the toolbar (or other admin element). Themers frequently aren't aware of Drupal.displace() (I wasn't until @lauriii told me about it), so they either ignore the problem or hard code the values for the toolbars in their CSS.
Solution
Because Drupal 10 no longer supports IE, we can use CSS custom properties (aka CSS variables) to output the displacement values. This will allow themers to 1) discover that these CSS custom properties exist by looking in Developer Tools, and 2) easily hook into the values without having to write custom JavaScript through something like the following:
.my-fixed.header {
position: fixed;
top: var(--drupal-displace-offset-top, 0);
}| Comment | File | Size | Author |
|---|---|---|---|
| #36 | 3256768-36.patch | 12.06 KB | mherchel |
| #33 | interdiff-24-33.txt | 750 bytes | mherchel |
| #33 | 3256768-33.patch | 13.87 KB | mherchel |
| #24 | 3256768-24.patch | 11.77 KB | mherchel |
| #22 | 3256768-22.patch | 12.92 KB | mherchel |
Comments
Comment #2
mherchelThis patch implements this with the namespace of
--drupal-displace--offset-<edge>Comment #3
mherchelComment #4
mherchelComment #5
nod_+1, we should update the css variables before the event though
Comment #6
nod_Not sure what happened with the files here.
Comment #7
nod_reupdating the patch from #4
Comment #8
mherchelThanks for looking at this!
It looks to me like you accidentally re-uploaded the patch from #4. You still have the correct patch? Or I can make the change, too.
Comment #9
nod_it was on purpose, it got deleted somehow from the issue summary.
Comment #10
nod_moved the prop change before the event trigger + small refactor
I do wonder if there is a performance hit.
We have a debounce on the resize event but are the props updated fast enough. Going to the style props is pretty slow. Might want to figure out which edge changed (if any) to avoid needless updates.
Comment #11
nod_forgot to update a patch for #10. anyway going with an other approach.
I tried to use the new css variable to handle the toolbar offset of the body/html element. Went mostly well but ran into troubles because of how tableheader interracts with the offsets object. That means i went with a different approach, making
Drupal.displace.offsetssmarter and making sure that whenever a value is assigned to top/left/bottom/right the corresponding CSS custom variable is also updated. With this code it's possible to replace a bit of code from the toolbar and move that piece from the JS to the CSS:this is not part of this patch because toolbar should use it's own variable to mess with the body padding because not everything that displace the offset top might move the body down (I guess).
One question is around the naming. Do we have a naming convention for css variables yet? Should we use logical properties names (start/end) instead of left/right?
Comment #12
mherchelWe do not yet. My hope is that we can solidify it in #3254529: [PLAN] Drupal CSS Modernization Initiative, but so far, I haven't seen too much traction.
That being said, I'm assuming it's possible to make the change here, and then when/if there are formal conventions for naming the CSS variables, we can then update the code at that time (assuming its before beta)?
I had the same thought. It really determines how the displace function works.
I'm going to step through the code to see if I can understand it better. It's still slightly opaque to me.
Comment #13
mherchelCurrently it seems that the component that sets its
data-offset-edge is responsible for determining if the page is currently RTL.You can see this in off-canvas.es6.js at https://git.drupalcode.org/project/drupal/-/blob/10.0.x/core/misc/dialog... , which is used to set the attribute for the settings tray.
If we were to change the variable naming to
start,end, it would imply to me that the components wouldn't need to manage that. So, at this point it makes sense to me to keep the naming to
left, andright. That being said, we should really refactor this now that we don't have to support IE11.Comment #14
nod_That works for me, we'll need to check with Lauriii. It opens the box of how to document/expose custom css variables names (scope?) and purpose
Comment #15
mherchelPatch in #11 looks great!
I'm personally not too familiar with OO JavaScript, so it was fun stepping through and following along. The patch works perfectly.
I believe that I found one nitpick with a change that needs to be made to the comments, and am fixing it and attaching an interdiff. Note there are no changes to the transpiled file.
The first parameter is not a regular DOM HTMLElement, and not a jQuery Element as specified in the next line.
Comment #16
mherchelTalked to @lauriii. He prefers that we postpone this until #3257287: [Policy] Create CSS standards for core use of CSS custom properties (aka CSS Variables) is resolved.
We also need a change record.
Comment #17
andy-blumReviewed patch #15 and +1 for RTBC, but leaving the status as postponed per #16.
There are 2 main followup issues I'd recommend here:
Comment #18
mherchelTalked with @lauriii about this today.
We can un-postpone this, and rename the variables to
--drupal-displace-offset-topWe also need some basic tests (Drupal.displace() is currently untested as far as I can tell).
Comment #19
andregp commentedI updated the variable name on displace.es6.js and ran
yarn run build:jsto rebuild displace.js automatically.Still needs work for adding tests though.
Comment #20
mherchelAccording to Drupal.displace()'s CR,
The tests are viewable at
https://git.drupalcode.org/project/fat/-/blob/8.x-1.x/tests/drupal.displ...
Comment #21
mherchelNote that this patch also includes the fix from #3272727: Nightwatch's drupalModuleInstall() doesn't handle test modules or modules w underscores in machine name, which I discovered when writing this patch.
This patch adds nightwatch tests for Drupal.displace() and is heavily influenced by the tests at https://git.drupalcode.org/project/fat/-/blob/8.x-1.x/tests/drupal.displ...
Comment #22
mherchelVersion that uses template literals in the JS tests
Comment #23
nod_Tests looks good to me! can't RTBC the whole patch but the test part is good to go.
Comment #24
mherchelHere is another patch that removes the fix from #3272727: Nightwatch's drupalModuleInstall() doesn't handle test modules or modules w underscores in machine name
Comment #25
andy-blumScreenshots of patch #24 in place:
Admin toolbar sets displacement of 39px.

Opening the manage menu adds another 40px to our custom property.

Shrinking the window reduces offset-top back to 39px and sets the offset-left to 240 (239px width + 1px border-right).

Inspecting Drupal.displace.offsets object shows 4 values with getters & setters.

Trying to add a new custom value doesn't error, but also doesn't succeed.

RTBC, pending tests
Comment #27
mherchelUnrelated failure
Comment #29
mherchelUnrelated failure.
Comment #30
lauriiiNit: I guess we could remove the extra newline.
The comment should be updated as well
Comment #31
mherchelUnpublished change record created at https://www.drupal.org/node/3275981
Comment #32
mherchelComment #33
mherchelUpdated patch (and interdiff) attached.
Comment #35
mherchelPrevious unrelated failure. Test is now passing.
Comment #36
mherchel#33 had some unrelated changes relating to another issue. Attached is a patch with only the relevant files.
Comment #38
lauriiiCommitted f8c91fd and pushed to 10.0.x. Thanks!