Add a class to opt-out of off-canvas resets in contrib

Created on 20 October 2023, about 1 year ago
Updated 16 November 2023, about 1 year ago

Problem/Motivation

πŸ› Off-canvas style resets are overriding styles (especially SVGs) resulting in display issues Fixed introduced off-canvas reset
πŸ“Œ Refactor Drupal 10 settings tray / off-canvas to use modern CSS Fixed improved it to use modern CSS

As you can see here: https://git.drupalcode.org/project/drupal/-/blob/11.x/core/misc/dialog/o...
the current implementation of the reset looks like this:

/*
 * DO NOT EDIT THIS FILE.
 * See the following change record for more information,
 * https://www.drupal.org/node/3084859
 * @preserve
 */

/**
 * @file
 * Reset HTML elements styles for the off-canvas dialog.
 *
 * @internal
 */

#drupal-off-canvas-wrapper *:where(:not(svg, svg *, .ck-reset *, [data-drupal-ck-style-fence] *, .ui-resizable-handle)) {
  all: revert;
  box-sizing: border-box;
  -webkit-font-smoothing: antialiased;
  line-height: 1.4;
}

#drupal-off-canvas-wrapper *:where(:not(svg, svg *, .ck-reset *, [data-drupal-ck-style-fence] *, .ui-resizable-handle))::after,
#drupal-off-canvas-wrapper *:where(:not(svg, svg *, .ck-reset *, [data-drupal-ck-style-fence] *, .ui-resizable-handle))::before {
  all: revert;
  box-sizing: border-box;
  -webkit-font-smoothing: antialiased;
}

It already contains some excludes for special cases in core, but doesn't allow for contrib to opt-out of the resets, if needed.

That's what we should allow to do, by adding a general helper class to

Steps to reproduce

Need CSS in contrib not to be reset by the off-canvas layer

Proposed resolution

Provide a documented class in :not() selector to opt-out of the reset in contrib, just like the existing, predefined cases.

The class name should be discussed. Proposals:

  • .drupal-off-canvas-wrapper-unreset
  • .drupal-off-canvas-wrapper-noreset
  • ...?

That might also solve the raised point in the comments here:
https://herchel.com/articles/new-drupal-core-refactored-canvas-dialog-css

And eventually it can save us from adding some further special cases and use the class instead?

Remaining tasks

  1. Discuss
  2. Implement
  3. Document
  4. Release

User interface changes

None

API changes

None

Data model changes

None

Release notes snippet

✨ Feature request
Status

Active

Version

11.0 πŸ”₯

Component
Settings trayΒ  β†’

Last updated 15 days ago

  • Maintained by
  • πŸ‡ΊπŸ‡ΈUnited States @tedbow
Created by

πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @Anybody
  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica
  • Status changed to Needs review about 1 year ago
  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica
  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Like the idea. Think a framework manager would have to make the call.

  • πŸ‡ΊπŸ‡ΈUnited States bnjmnm Ann Arbor, MI

    This solution is something I'd FEFM-approve some form of. Seems like a fairly gentle change that would address an annoying pain point with off canvas dialogs.

    • This should include tests that use getComputedStyle to confirm styles are applied/not applied accordingly
    • If we go with a long class name as suggested, they should be BEM. If the class name was shorter I'd be inclined let that BEM requirement slide. (In other words, if it's already unweildy, then BEM should be there.. but something easier to understand at a glance might be better DX than BEM.
    • Is there any benefit in having two classes - one for a single element and another for .class * so all child elements are reset immune?
    • I'd like to see a comment in the CSS explaining the use of the no-reset class(es). The ideal place would be where someone is most likely to look when they are frustrated and tracking down the CSS that is messing with their UI.
  • Status changed to Active about 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Thanks @bnjmnm! Removing the tag for frontend framework.

  • πŸ‡©πŸ‡ͺGermany Anybody Porta Westfalica

    @bnjmnm thank you!

    FYI: Guess I'm not the right one to implement and decide on this, as I'm not really experienced in frontend ;) My times writing bit more complex CSS are a decade ago, so please don't wait for my unqualified feedback here. I'll watch this issue and had the idea for this, yes, but my focus is elsewhere. Hopefully we have some frontend / CSS guys to take a look :)

    Thank you all, I'm really happy you like the idea!

  • πŸ‡³πŸ‡±Netherlands ndf Amsterdam

    Just stumbled on this one when working on πŸ› Select2 css not applied inside off-canvas because Drupal core reset.css removes it (since Drupal core 10) Active

    Does someone knows a workaround that can be used?
    Maybe a method to replace core reset.css with an application specific one.

    And imagine we have the exclusion class. How will the css of contrib look? Something like this:

    button.contrib-module {border: 2px solid grey}
    .drupal-off-canvas-wrapper-noreset button.contrib-module {border: 2px solid grey}
    

    Wouldn't that mean that all contrib css that might be rendered inside the off-canvas must be duplicated with the exclusion class prefixed. πŸ€”

  • πŸ‡ΊπŸ‡ΈUnited States justcaldwell Austin, Texas

    @ndf β€” yes, you can replace core's off-canvas reset with your own as a workaround:

    use Drupal\Core\Asset\AttachedAssetsInterface;
    ...
    function YOUR_MODULE_css_alter(&$css, AttachedAssetsInterface $assets) {
      if (isset($css['core/misc/dialog/off-canvas/css/reset.css'])) {
        $css['core/misc/dialog/off-canvas/css/reset.css']['data'] = 'path/to/your/module/css/your-module-off-canvas-reset.css';
      }
    }

    Then your-module-off-canvas-reset.css is just a copy of core's, with your selector added where needed:

    #drupal-off-canvas-wrapper *:where(:not(svg, svg *, .ck-reset *, [data-drupal-ck-style-fence] *, .ui-resizable-handle, .YOUR-CLASS)) {
      all: revert;
      box-sizing: border-box;
      -webkit-font-smoothing: antialiased;
      line-height: 1.4;
    }
    
    #drupal-off-canvas-wrapper *:where(:not(svg, svg *, .ck-reset *, [data-drupal-ck-style-fence] *, .ui-resizable-handle, .YOUR-CLASS))::after,
    #drupal-off-canvas-wrapper *:where(:not(svg, svg *, .ck-reset *, [data-drupal-ck-style-fence] *, .ui-resizable-handle, .YOUR-CLASS))::before {
      all: revert;
      box-sizing: border-box;
      -webkit-font-smoothing: antialiased;
    }
    

    Maybe not ideal, but it can make life much easier when you're trying to style for off-canvas.

    Wouldn't that mean that all contrib css that might be rendered inside the off-canvas must be duplicated with the exclusion class prefixed.

    Yes, I think so. That's why I'm hoping for a shorter classname, maybe something like .drupal-noreset.

  • πŸ‡ΊπŸ‡ΈUnited States justcaldwell Austin, Texas

    Of course, if/when more projects take this approach, there will be conflicts.

  • πŸ‡ΊπŸ‡ΈUnited States bnjmnm Ann Arbor, MI

    Yes, I think so. That's why I'm hoping for a shorter classname, maybe something like .drupal-noreset.

    I'm pro-BEM in many cases, but (as a front end framework manager / committer) I'm not opposed to approving something with a shorter classname. I think it's helpful to see at a glance if something has been un-reset and .drupal-off-canvas-wrapper-noreset is a little too long for it to register quickly.

    For this to get further we'd need some kind of test coverage like what I requested in #6. If anyone following this issue is interested in doing this but unsure where to start (either writing the tests, or just getting it set up locally), find me on Drupal Slack and I can assist. This seems like a pain point worth solving sooner than later.

Production build 0.71.5 2024