1

My custom theme uses Bootstrap, which I'd obviously like to load before any module CSS libraries, but Drupal ignores any kind of ordering for themes, and Bootstrap CSS styles appear as @import in a <style> tag that always comes last, even if it's set to base. Modules however, respect SMAACS groupings and will move CSS @imports into different style tags.

How can I get the theme CSS files to load before module CSS files? Why is bootstrap ALWAYS at the bottom?

I've cleared the cache, disabled devel, tried aggregation on and off. Nothing makes a difference.

This is the code I am using.

/themes/custom/trent/trent.info.yml

core: 8.x
type: theme

name: "Trent"
description: "Test theme"
package: "Trent"

libraries:
  - trent/bootstrap

/themes/custom/trent/trent.libraries.yml

bootstrap:
  css:
    base:
      libraries/bootstrap/bootstrap.min.css: {}

/modules/custom/trent_news/trent_news.info.yml

name: Trent News
type: module
description: Displays news
core: 8.x
package: Trent
libraries:
  - trent_news/trent-news

/modules/custom/trent_news/trent_news.libraries.yml

trent-news:
  version: 1.x
  css:
    theme:
      css/trent_news.css: {}
      css/print.css: {}

I want bootstrap to move up higher but Drupal isn't respecting any setting; it just keeps it in that last <style> tag no matter what. However, it does respect SMAACS ordering within that style tag, oddly enough. As I mentioned, I can change the module ordering (e.g. theme -> component) and the CSS imports will move into different <style> tags accordingly.

wrong ordering

UPDATE:

core/lib/Drupal/Core/Asset/LibraryDiscoveryParser.php:165 overrides and ignores any SMACCS setting (or group setting in *.libraries.yml) for theme CSS. It actually doesn't appear possible to move the import higher up before any module includes:

$options['group'] = $extension_type == 'theme' ? CSS_AGGREGATE_THEME : CSS_AGGREGATE_DEFAULT;
1

The proper way to modify the loading order is weight property as described here. The lower the weight the further up your library should go.

Try something like the following in your trent/trent.libraries.yml

bootstrap:
  css:
    base:
      libraries/bootstrap/bootstrap.min.css: {weight: -50}

You might have to adjust the number to get it to desired position.

NOTE: weight is in the process of being replaced by dependencies. Work done can be seen in this issue and when ready this sort of problem will be easier to tackle.

  • Thanks, but weight only "adjusts order relative to other assets (within the same SMACSS group)". The problem is the SMACSS group (base) is totally ignored - after some debugging it's always being set to 100 by the AssetResolver, even if I explicitly set it using something like group: -200 in the libraries YML file. – manafire Apr 8 at 14:27
  • @manafire It should work the way I describe above but I had not tested it personally. I just tested it and it does not. Here is some more reports that it should work drupal.stackexchange.com/questions/202138/… – GiorgosK Apr 8 at 15:43
  • 1
    It should work the way you've specified (thanks) but it doesn't quite exactly because there appears to be code in Core that forces module css libraries to come first in the load order before themes. I created a bug report: drupal.org/project/drupal/issues/3046636 – manafire Apr 8 at 16:56
0

Solution

Implement a hook_css_alter() in your theme and make sure the CSS group for your stylesheet is the right one. Replace THEME with your theme's machine name.

/**
 * Implements hook_css_alter().
 */
function THEME_css_alter(&$css, AttachedAssetsInterface $assets) {
  if (isset($css['libraries/bootstrap/bootstrap.min.css'])) {
    $css['libraries/bootstrap/bootstrap.min.css']['group'] = CSS_BASE;
  }
}

Cause

I think there's a probable bug in core. According to the CSS file organization documentation, CSS_BASE is supposed to be loaded before other things. However, for some reason, Drupal assigns the weight of 100 to the theme's base stylesheets, which is not correct. So, I simply wrote the hook to restore the stylesheet weight to the correct one, i.e. CSS_BASE.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.