Drupal 10 has dropped support for Internet Explorer which means CSS custom properties are fully supported by all browsers that Drupal supports.

Passing backend settings to frontend is quite common task when you need content managers to be able to change site appearance.
Currently it is typically implemented through preprocess variables which is kind of tedious.

Proposed solution

Support attaching CSS properties same way as JS settings.

'#attached': [
  'drupalProperties': [
    ':root': [
      'bg-color': 'pink',
    ],
  ],
],

On FE side it should look like this.

<style>
  :root {--bg-color: pink}
</style>

Issue fork drupal-3296202

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

Chi created an issue. See original summary.

chi’s picture

Issue summary: View changes
chi’s picture

Issue summary: View changes
andypost’s picture

nod_’s picture

That's a pretty neat idea. I don't think it's a duplicate, this is not just about colors.

I could probably be used by Olivero to simplify the color customization code that uses preprocess to do that in olivero_preprocess_html

Few things:

  1. One thing that might come up is that the feature essentially allow some inline CSS and in #2391025: Add support for inline JS/CSS with #attached we've been pretty reluctant to do that at all so I'm going to say now: this shouldn't go outside custom CSS vars, arbitrary CSS will not be allowed.
  2. It might make sense to require the -- in the names to avoid awkward situations where someone is searching for a variable name and doesn't know -- should be removed to find a match in the codebase.
  3. Adding a <style> tag directly might cause some problems down the line for #2513356: Add a default Content-Security-Policy and clickjacking defence to core, with JS we went around it by changing the type attribute of the script tag and having code evaluate that at runtime. This is not possible/wanted here so that's one thing to keep in mind
  4. The name drupalProperties is not ideal, since this is not a Drupal thing, it's purely a CSS thing (see point above), so it might make sense to have a customProperties key under the css key? It's different than what we do with JS settings but this CSS feature will not have Drupal specific code to evaluate it. On the other hand keeping that at the root might make some internal code and the whole alter pipeline easier to deal with.

Despite all that, I'm overall +1 to the proposal :)

immaculatexavier made their first commit to this issue’s fork.

chi’s picture

Issue summary: View changes

Re #5-4. I am not happy with drupalProperties name either. Furthermore, I think drupalSettings is not accurate name as well because it's used not just for settings but for any data that needs to be passed from backend to frontend.

mherchel’s picture

This is really interesting. I really like this!

I could probably be used by Olivero to simplify the color customization code that uses preprocess to do that in olivero_preprocess_html

Agree. We currently inject the styles inline via preprocess.

The name drupalProperties is not ideal

Agree. Call it cssCustomProperties, or have the customProperties under the css key as @nod_ suggested.

jwilson3’s picture

+1 I love this. One thing that occurred to me is that the approach will need to gracefully consider the CSS cascade, and allow devs and themers to adjust the weight at which a group of CSS properties are injected into the page to determine conflict resolution (last item in the cascade wins). This would be similar to (maybe same as?) the SMACSS organization technique employed by core.

A contrived example would be to imagine (for the pure lulz of it):

  1. a core module providing a default value with root: { --toolbar-height: 39px;},
  2. then another core theme overrides that with :root { --toolbar-height: 2rem; },
  3. then a custom child theme overrides that with :root { --toolbar-height: calc(var(--base-font-size) * 2) },
  4. and finally a contrib module providing more features exposes the variable in the admin ui with a user-entered value of :root { --toolbar-height: 50px;}

Revenge of the custom variables.

chi’s picture

and finally a contrib module

I think variables from modules should go first. That would match the order of CSS files.
And to ajust the weight of a variable the one could increase CSS specificity. Something link this.

:root:root { --toolbar-height: 2rem; }

Version: 10.0.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.