4

How do I add CSS styles for a specific page?

For example, I want the <body> background color on a specific page to be different from the background color used on the front page.
I've looked into hook_theme_preprocess(), but I am confused on how I should implement it.

3
  • In most cases you can make use of body classes.
    – ya.teck
    Nov 27, 2016 at 5:58
  • If you are trying to style specific nodes then Code per Node module can help you do that via the Drupal UI, without writing any custom PHP code.
    – W.M.
    Nov 27, 2016 at 6:56
  • This module is only available for Drupal 7, the question was regarding Drupal 8, as it was tagged with the 8 tag.
    – No Sssweat
    Nov 27, 2016 at 7:05

4 Answers 4

8

You can find totorial for adding specific CSS to specif page to the following links.

  1. Drupal 8 Theming Fundamentals, Part 1, but it is describing how to add specific CSS to front page.

  2. Drupal8 attaching libraries to specific pages, to add the specific CSS to specific node you need to follow tutorial on this page .

To give you example I am explaining with bartik theme for easy understanding.

I have created a css file cssfile.css and pasted at path css/cssfile.css Now this CSS file I want to use in one case to only front page and in otehr case to only specific node.

Step 1: Adding a library to the theme

Add the following code to bartik.libraries.yml.

css-filling: 
  css:
    theme:
      css/cssfile.css: {}

The library name I used is css-filling, but you can use other names.

Step 2: Adding the CSS styles to a specific page

Step 2a: Adding CSS styles only to the front page

The following code in the bartik.theme adds the library to the front page.

function bartik_preprocess_page(&$variables) {
  if ($variables['is_front']) {
    $variables['#attached']['library'][] = 'bartik/css-filling';
  }
}
Step 2b: Adding CSS styles to a specific node

The following code adds the library only to a specific node.

function bartik_preprocess_node(&$variables) {
  $node = \Drupal::routeMatch()->getParameter('node');
  if ($node) {
    if ($node->id() == 3) {
      $variables['#attached']['library'][] = 'bartik/css-filling';
    }
  }
}

In the above code the important thing is path, bartik comes from the theme name and css-filling comes from step 1.

2
  • I apply css to individual pages by embedding them in the source of the page via <style type="text/css"> css code </style>
    – PatriciaW
    Nov 12, 2018 at 15:33
  • @PatriciaW this is not the best approach. Use {{ attach_library(“theme-name/library-name”) }} instead Apr 17, 2020 at 12:42
4

Most Drupal themes still provide enough classes on the body tag to allow you to target the front page separately from all others. Stable (the most basic of base-themes in Drupal 8 core) provides front on the front page and not-front on all others.

But you can load style sheets conditionally if that's important to your project. The complete details are available here, but the short version is that you can define a library in your theme and then attach the library in whatever html.twig file you need to ensure that libraries loads for:

{{ attach_library('mytheme/mylibrary') }}
2
  • Would I have to make multiple html.twig files depending on the node for this to work?
    – klo009
    Nov 27, 2016 at 8:51
  • I would always look first at adding extra body classes to enable you to specify background colours based on whatever makes the page distinct. Aug 8, 2019 at 14:36
0

To add custom style for a specific page. Here I'm adding it for login page, register page.

File:- mytheme.theme

function mytheme_preprocess_page(&$variables)
{
  // \Drupal::logger('mytheme')->error('Start');
    $route_name = \Drupal::routeMatch()->getRouteName();
    if (in_array($route_name, ['user.login', 'user.pass', 'user.register'])) {
        $variables['#attached']['library'][] = 'mytheme/login';
    }
}

Following content are same as the @CodeNext answer.

File:- mytheme.info.yml

Doc: https://www.drupal.org/docs/theming-drupal/adding-assets-css-js-to-a-drupal-theme-via-librariesyml

libraries:
  - mytheme/global-styling
  - bootstrap5/bootstrap5-js-latest
libraries-override:
  bootstrap5/global-styling: false

Note: I'm not adding login library in mytheme.info.yml

File:- mytheme.libraries.yml

login:
  css:
    theme:
      css/login.css: { minified: true }
-1

In Drupal 7, there is a class like page-node-NID (with NID replaced by the node ID of the node being viewed) added to the tag so we can easily add CSS styles to specific nodes for example:

body.page-node-NID{
  background-color: red;
}

Drupal 8 is missing this core D7 functionality, but now there is a module for that, its called Body node ID class

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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