JS and CSS assests in drupal are highly customizable. For more information, refer to this blog post.
Here are some practical scenarios:
- Through a global library
- Deleting or overriding existing styles served by core
- Declaring various dependencies that are provided by Drupal 8's core
- Specifying assets scope or sending JS to the footer
- Specifying media type
- Adding external CSS or JS library, e.g: Google Fonts
- Adding conditional CSS or JS for older IE browsers
- Adding custom libraries to specific pages, e.g: front page
Global styles and scripts
In the example below global-styling
is a name of a library (a file or collection of files) that is used for global styles. It is declared in a theme_name.libraries.yml
and then also added to the theme_name.info.yml
file. This specific library will now be available across the whole site.
Here is how it will look in the theme_name.libraries.yml
file.
global-styling:
version: VERSION
css:
theme:
css/style.css: {}
Then it's declared in the theme_name.info.yml
file.
name: Example
type: theme
core: 8.x
libraries:
- theme_name/global-styling
Declaring scripts would be very similar. In the theme_name.libraries.yml
global-scripts:
version: VERSION
js:
js/script.js: {}
Then in the theme_name.info.yml
file, we add these libraries.
name: Example
type: theme
core: 8.x
libraries:
- theme_name/global-styling
- theme_name/global-scripts
Now these two libraries or collections of JS and CSS files are available across the whole site. These two separate sets of CSS and JS can also be combined into one library.
global-styles-and-scripts:
version: VERSION
css:
theme:
css/style.css: {}
js:
js/script.js: {}
Deleting or overriding existing styles served by core
In the theme_name.info.yml
file:
stylesheets-remove:
- normalize.css
or to override the core's stylesheet:
stylesheets-override:
- normalize.css
Declaring dependencies
Example of declaring a dependency.
global-scripts:
version: VERSION
js:
js/script.js: {}
dependencies:
- core/jquery
- core/jquery.once
- core/modernizr
Specifying scope of a JS file or sending it to the footer
There are many cases when it would be best to have a JS asset at the footer of the page. By default they will be included in the header but you can easily send them to the footer by specifying the scope in the theme_name.libraries.yml
file.
js/script.js: { scope: footer }
Specifying media type
Similarly, if there is a need for a print stylesheet in your theme it can also be easily specified with a media parameter in the theme_name.libraries.yml
file.
css/print.css: { media: print }
Bringing in an external JS or CSS resource
Often you would want to include an external library in your theme, here is how it can be added in theme_name.libraries.yml
file.
remote-custom:
remote: https://github.com/yui/yui3
license:
name: BSD
url: https://github.com/yui/yui3/blob/master/LICENSE.md
gpl-compatible: true
version: VERSION
js:
http://yui.yahooapis.com/3.18.1/build/yui/yui-min.js: { type: external, browsers: { IE: 'lte IE 8', '!IE': false } }
You can also specify additional parameters in the theme_name.theme file
with a preprocess hook:
function theme_name_css_alter(&$css) {
$theme_path = drupal_get_path('theme', 'theme_name');
// Add googlefonts.
$googlefonts = '//fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,700|Source+Serif+Pro:700,400';
$css[$googlefonts] = array(
'data' => $googlefonts,
'type' => 'external',
'every_page' => TRUE,
'media' => 'all',
'preprocess' => FALSE,
'group' => CSS_AGGREGATE_THEME,
'browsers' => array('IE' => TRUE, '!IE' => TRUE),
'weight' => -1,
);
}
Conditional CSS or JS for older IE browsers
You can specify IE conditionals through the parameters in the theme_name.libraries.yml
file.
http://yui.yahooapis.com/3.18.1/build/yui/yui-min.js: { type: external, browsers: { IE: 'lte IE 8', '!IE': false } }
Adding or limiting a library to specific pages
If you only need to load a specific library onto a specific page, e.g maintenance page, you will need to add a hook in your theme_name.theme
file. Here is an example:
function theme_name_preprocess_maintenance_page(&$variables) {
$variables['#attached']['library'][] = 'theme_name/custom-library';
}
Here is an example of how a custom-library
can be loaded only on a front page:
function theme_name_preprocess_page(&$variables) {
if($variables['is_front']){
$variables['#attached']['library'][] = 'theme_name/custom-library';
}
}
Remember to always clear your caches when you are adding libraries or creating new hooks. An easy way to do that automatically is to set the debug: true
in your Drupal 8 services.yaml
file in sites/default/
while developing.