Adding helpful CSS classes to elements in Drupal 9 themes
Hello! It’s been awhile since I’ve written something. I want to share a smattering of examples of adding classes to different elements in a Drupal 9 theme. Would love to hear what classes you’re adding and how.
- Add a CSS class to body if the user is logged in.
- Add a CSS class to the body if you are on the front page
- Add a region name class to region template
- Add
node_id
andnode_type
CSS classes to body - Add CSS classes for node Add, Edit, and Delete forms to body
- Add
view_id
and viewdisplay_id
CSS classes to body - Add your own CSS classes to Views buttons
- Add your own CSS classes to local actions
- Add your own CSS classes to Read More and Comments links
- Add your own CSS class to the search form
- Add your own CSS class to a field
- Add your own CSS to multi-value fields
- Add your own CSS class to form element descriptions
- Using field values as CSS class names
- Using theme settings as CSS classes in theme templates
- Add block type as a CSS class in block templates
Things you should replace with your own info are in bold.
Add a CSS class to body if the user is logged in
The logged_in
variable is available in theme templates.
In the html.html.twig
template where body
liv:
{% set body_classes = [
logged_in ? 'logged-in',
]
%}<body{{ attributes.addClass(body_classes) }}>
...
Add a CSS class to the body if you are on the front page
In the html.html.twig
template where body
lives:
{% set body_classes = [
is_front ? 'is_front' : 'not_front',
]
%}<body{{ attributes.addClass(body_classes) }}>
...
This also works in other templates like page.html.twig
, block.html.twig
, status-messages.html.twig
, etc.
Add region CSS class to region template
region
is built in!
In region.html.twig
(or templates that would override it):
{%
set region_classes = [
'region_' ~ region|clean_class,
]
%}<div{{ attributes.addClass(region_classes) }}>
Add node-id
and node-type
CSS classes to body
.
In the .theme
file:
use Drupal\node\NodeInterface;function mytheme_preprocess_html(&$variables) {
$node = \Drupal::request()->attributes->get('node');
if ($node instanceof NodeInterface) {
$variables['attributes']['class'][] = 'node-id_' . $node->id();
}
if (isset($variables['node_type'])) {
$variables['attributes']['class'][] = 'node-type_' . $variables['node_type'];
}
Add CSS classes for node Add, Edit, and Delete forms to body
In .theme
function mytheme_preprocess(&$variables, $hook) {
$route_name = \Drupal::routeMatch()->getRouteName();
if ($route_name == 'entity.node.edit_form') {
$variables['is_node_edit'] = 'edit';
}
elseif ($route_name == 'node.add') {
$variables['is_node_add'] = 'add';
}
elseif ($route_name == 'entity.node.delete_form') {
$variables['is_node_delete'] = 'delete';
}
}
Then in html.html.twig
{%
set body_classes = [
is_node_edit == 'edit' ? 'node-form node-form_' ~ 'edit',
is_node_add == 'add' ? 'node-form node-form_' ~ 'add',
is_node_delete == 'delete' ? 'node-form node-form_' ~ 'delete',
]
%}
<body{{ attributes.addClass(body_classes) }}>
Add view_id and view display_id CSS classes to body
function mytheme_preprocess_html(&$variables) {
$route = \Drupal::routeMatch()->getRouteObject();
$view_id = $route->getDefault('view_id');
$display_id = $route->getDefault('display_id'); if ($view_id) {
$variables['attributes']['class'][] = 'view_' . $view_id;
$variables['attributes']['class'][] = 'view-display_' . $display_id;
}
}
Add your own CSS classes to Views buttons
function mytheme_preprocess_views_view(&$variables) {
$variables['more']['#options']['attributes']['class'] = array('my-button-class1', 'my-button-class2');
}
Add your own CSS classes to local actions
function mytheme_preprocess_menu_local_action(&$variables) {
$variables['link']['#options']['attributes']['class'][] = 'my-button-class1 my-button-class2';
}
Add your own CSS classes to Read More and Comments links
function mytheme_theme_preprocess_links(&$variables) {
if (!empty($variables['links']['node-readmore']['link'])) {
$variables['links']['node-readmore']['link']['#options']['attributes']['class'][] = 'my-button-class1 my-button-class2';
}
There are several buttons! Repeat the $variables
line for each button type by replacing node-readmore
with the button types below as needed:
comment-comments
comment-add
comment-delete
comment-edit
comment-reply
book_printer
book_add_child
Add your own CSS class to the search form
function mytheme_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
if( $form_id == 'search_block_form') {
$form['actions']['submit']['#attributes']['class'][] = 'my-search-class';
}
}
Add your own CSS class to a field
There may be other ways to do this, but here is one way.
function mytheme_preprocess_field(&$vars) {
if ($vars['element']['#field_name'] == 'field_people_image') {
foreach ($vars['items'] as $key => $item) {
$vars['items'][$key]['content']['#item_attributes']['class'][] = 'my-field-class';
}
}
}
Add your own CSS to multi-value fields
function mytheme_preprocess_field_multiple_value_form(&$variables) {
$variables['table']['#attributes']['class'][] = 'my-multi-value-class';
}
Add your own CSS class to form element descriptions
function mytheme_preprocess_form_element(&$variables) {
if ($variables['element']['#type'] == 'managed_file') {
$variables['description_display'] = 'before';
$variables['description']['attributes']['class'] = 'my-description-class';
}
}
You can replace managed_file
with the form type as needed, such as select
or textarea
. Find a list of form element names here at the Drupal API documentation: form and render elements.
Using field values as CSS class names in Drupal 8/9
Using theme settings as CSS classes in theme templates
In this example I want to use them in my block templates.
function mytheme_preprocess_block(&$variables) {
$variables['my_variable_name'] = theme_get_setting('theme_setting_name');
}
Then in the template, for example:
{% set my_classes = [
my_variable_name|clean_class,
my-other-class,
]
%}{# Then, for example #}
<div class="my_classes">
...
</div>{# Or #}
<div{{ attributes.addClass(my_classes) }}>
...
</div>
More information and how to add your own theme settings at the official Drupal theming documentation. This same technique works perfectly well for both mytheme_preprocess_page
and mytheme_preprocess_node
.
Add block type as a CSS class in block templates
function mytheme_preprocess_block(&$variables) {
if ($variables['elements']['#base_plugin_id'] == 'block_content') {
$blockType = strtr($variables['content']['#block_content']->bundle(), '_', '-');
$variables['attributes']['class'][] = 'block-type_' . $blockType;
}
}