SDC CSS <link> definition render order

Created on 17 July 2023, over 1 year ago

Problem/Motivation

The SDC component CSS <link> definitions are rendering before theme libraries CSS, even where they're keyed as base or theme. I have an example where a button in an SDC has styles that are being overridden by a reset base library that's rendered after the SDC.

Steps to reproduce

Ensure CSS <link> definitions from SDC are rendered after the themes base and/or theme libraries.

🐛 Bug report
Status

Active

Version

10.1

Component
Render 

Last updated 3 days ago

Created by

🇳🇿New Zealand gareth.poole

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

Comments & Activities

  • Issue created by @gareth.poole
  • 🇪🇸Spain ivanmartil

    I have the same problem. For now, I have solved it with @layer, but it not has support in some browsers.

  • 🇺🇸United States mherchel Gainesville, FL, US

    This is interesting. I see your point, but SDC's are meant to be self contained and any dependencies should be explicit.

    My thought is if you had a theme level library called reset, you should explicitly declare the dependency within the SDC by doing something like

    libraryOverrides:
      dependencies:
        - my_theme/reset
    

    Thoughts on this? This might also be a question for a frontend framework manager.

  • 🇺🇸United States mherchel Gainesville, FL, US

    Funny enough, running into this right now. The method in #5 doesn't work.

    What I expect

    If I load mytheme/my-library as a dependency to a component, I expect to see the CSS files in my-library loaded before the CSS files from my component

    What I'm seeing:

    Currently it gets added as the last file within the source order. If I change the group to base, it still loads after the the component in the source order.

  • 🇺🇸United States mherchel Gainesville, FL, US

    Updating IS

  • 🇺🇸United States mherchel Gainesville, FL, US
  • First commit to issue fork.
  • Status changed to Postponed: needs info about 1 year ago
  • e0ipso Can Picafort

    I may not be able to fully reproduce this.

    I have tried to reproduce the conditions in the open MR. I cannot have the dependant load after the component stylesheet.

    I do see the reset.css file loaded after the component. However I can also see resize.module.css loaded before reset.css. That CSS is part of system.libraries.yml, and also declared with a component level.

    Do you think that creating the component inside the sdc_test_theme theme instead of the sdc_test component will make a difference?

  • Status changed to Needs work about 1 year ago
  • 🇺🇸United States mherchel Gainesville, FL, US

    Test case patch with a simple component within Olivero. Note that within the SDC, I don't declare any library dependencies.

    This is the source order of the CSS.

  • Status changed to Active about 1 year ago
  • 🇺🇸United States mherchel Gainesville, FL, US

    Here's a test case where I create a dependency on the olivero/feed library to try to force the SDC to load CSS at the end.

  • last update about 1 year ago
    Custom Commands Failed
  • 🇮🇳India _utsavsharma

    Fixed failures in #14.

  • last update about 1 year ago
    Build Successful
  • Status changed to Needs review about 1 year ago
  • e0ipso Can Picafort

    It looks like this is only triggered if the library being depended on lives inside of a theme.

    This patch should turn tests red.

  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & MySQL 5.7 updated deps
    last update about 1 year ago
    Custom Commands Failed
  • Status changed to Needs work about 1 year ago
  • The Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

    This does not mean that the patch needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

    Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

  • Status changed to Needs review about 1 year ago
  • e0ipso Can Picafort

    CC are unhappy.

  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & MySQL 5.7 updated deps
    24:43
    19:25
    Running
  • e0ipso Can Picafort

    Ouf, the branch creation really thew me off. It created my branch against 10.1.x.

    Let's see if the patch is fixed now.

  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & MySQL 5.7 updated deps
    last update about 1 year ago
    Custom Commands Failed
  • Status changed to Needs work about 1 year ago
  • The Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".

    This does not mean that the patch needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.

    Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.

  • last update about 1 year ago
    Custom Commands Failed
  • 🇮🇳India _utsavsharma

    Fixed failures in #19.

  • last update about 1 year ago
    30,473 pass, 1 fail
  • Status changed to Needs review about 1 year ago
  • e0ipso Can Picafort

    Added to cspell instead.

  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & MySQL 5.7 updated deps
    last update about 1 year ago
    30,447 pass, 1 fail
  • e0ipso Can Picafort

    As it turns out, this is not an SDC thing. Libraries autogenerated for components are owned by the SDC module.

    Below there is a failing test that shows how a library owned by a module, that depends on a library owned by a theme, will not produce the expected load order of the link tags.

    Moving this issue to the render system and re-titling it. Issue summary needs an update with new findings.

  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & MariaDB 10.3.22
    last update about 1 year ago
    30,474 pass, 1 fail
  • 🇫🇮Finland lauriii Finland

    Related but probably unrelated issue 🐛 Theme library override can fail in when you have multiple parent themes Needs review .

  • e0ipso Can Picafort

    A workaround could be to move the libraries your components depend on to a module. That should work.

    I am also interested in knowing if adding a dependency in your theme to the SDC module helps at all. If anyone wants to test and report, add the following to your theme's info file:

    dependencies:
      - drupal/sdc
    

    That might, or might not work. I wasn't able to add it to the test because the functional tests installer fails to create the ephemeral site.

  • Status changed to Needs work about 1 year ago
  • 🇳🇱Netherlands eelkeblok Netherlands 🇳🇱
  • 🇳🇱Netherlands eelkeblok Netherlands 🇳🇱

    I am not so sure adding a dependency to the theme works. There is a fairly fundamental mechanism in the sorting of the assets that puts more weight on themes than on modules. In the LibraryDiscoveryParser, the group gets set to either CSS_AGGREGATE_THEME or CSS_AGGREGATE_DEFAULT, depending on whether the extension is a theme or not. When it comes to sorting assets, that happens in the AssetResolver. This comes with its own sort method, which will prioritise the group as set earlier in the LibraryDiscovery parser.

    I think I will try if I can alter the library info from SDC to make my theme the owner of the libraries. That should get them below the base styling I have defined. Not sure if this could serve as a fix for this issue inside SDC, or whether there is a more fundamental problem at hand here.

  • 🇳🇱Netherlands Web-Beest

    Post op Drupal.org m.b.t. component css die eerder wordt ingeladen dan basetheme css
    https://www.drupal.org/project/drupal/issues/3374901 🐛 SDC Stylesheets are output in the wrong order (relating to normal libraries) Active

    I've run into this issue as well. I've created a subtheme of Bootstrap5 and my problem is that my styling is loaded prior to the base styling, rendering my styling useless.

    The problem resides in LibraryDiscoveryParser as eelkeblok already suggested. The stylesheets are loaded by the SDC module, which will always result it in them being placed in the CSS_AGGREGATE_DEFAULT group, higher up the chain then CSS_AGGREGATE_THEME.

    I don't have a solution for this but I've came with this workaround for anyone who encountered this problem:

    /**
     * Implements hook_library_info_alter().
     */
    function theme_virtuel_library_info_alter(&$libraries, $extension) {
      if ($extension == 'sdc') {
        foreach ($libraries as $key => $library) {
          $libraryName = explode('--', $key);
    
          if (empty($libraryName[1])) {
            continue;
          }
          $library['dependencies'][] = $libraryName[0] . '/' . $libraryName[1];
          $libraries[$key] = $library;
        }
      }
    }
    
    /**
     * Implements hook_library_info_build().
     */
    function theme_library_info_build() {
      /** @var \Drupal\Core\Asset\LibraryDiscoveryCollector $libraryDiscoveryCollector */
      $libraryDiscoveryCollector = \Drupal::service('library.discovery.collector');
      $theme = \Drupal::theme()->getActiveTheme();
    
      $libraries = [];
    
      // Duplicate SDC libraries as dependencies.
      $sdc = $libraryDiscoveryCollector->get('sdc');
    
      foreach ($sdc as $key => $library) {
        $libraryName = explode('--', $key);
    
        // Only add items that have a component.
        if (empty($libraryName[1])) {
          continue;
        }
    
        $cssFiles = [];
        foreach ($library['css'] as $cssKey => $cssDefinition) {
          $start = strpos($cssDefinition['data'], $theme->getName()) + strlen($theme->getName());
          $cssFiles[] = base_path() . $theme->getPath() . substr($cssDefinition['data'], $start);
        }
    
        // Remove asset from SDC, otherwhise it will be loaded twice.
        unset($library['css']);
    
        $sdc[$key] = $library;
    
        // Create library based on SDC definition.
        foreach ($cssFiles as $cssFile) {
          $libraries[$libraryName[1]]['css']['component'][$cssFile] = [];
        }
      }
    
      $libraryDiscoveryCollector->set('sdc', $sdc);
    
      return $libraries;
    }
    
  • 🇺🇸United States mherchel Gainesville, FL, US

    I'm continuously running into this. Any progress? I'd like to help but not sure where to start.

  • 🇬🇧United Kingdom catch

    @mherchel it might be worth double checking in 10.4/11.1 because 🐛 Logic error in Drupal's lazy load for asset aggregation Active changed library ordering to more strictly follow dependencies.

    📌 Replace custom weights with dependencies in library declarations; introduce "before" and "after" for conditional ordering Needs work is open for getting rid of custom weights more generally. 📌 Remove separate CSS_AGGREGATE_THEME aggregate file Needs work is open for getting rid of CSS_AGGREGATE_THEME.

    Probably getting rid of CSS_AGGREGATE_THEME is the real blocker here, and that in turn is blocked on 📌 Refactor system/base library Needs work and friends which could use some help but was getting close.

  • 🇺🇸United States mherchel Gainesville, FL, US

    Thanks for the response.

    I re-checked 11.1.x and the problem is still occuring :(

    I will look at those other issues.

  • 🇺🇸United States joelsteidl

    @mherchel

    Have you tried the workaround mentioned in #29. I know it's not the long-term fix, but want to know more out of curiosity.

  • 🇺🇸United States sethhill

    I made a small module called SDC CSS Relocator to help with a similar issue that I was seeing. If there's anything that would make it more helpful while this issue awaits resolution, feel free to comment on that project page.

  • 🇺🇸United States mherchel Gainesville, FL, US

    @sethhill

Production build 0.71.5 2024