Skip to main content
 —  James Oakley
Radix Drupal theme logo

I recently wrote about my experiences migrating this website from Drupal 7 to Drupal 10. In that post I said that I would write separately about my experiences theming the site. This is that post.

I was broadly happy with the look and feel of the Drupal 7 version of the site, so didn't want something vastly different. At the sametime, I wanted to make sure that I was using the most maintainable underlying code, behind what end-users see.

The Theming Spectrum: Base Themes

When it comes to theming a site, there is a spectrum. At one end of the spectrum, you build everything yourself. You write the HTML templates, using Twig from Drupal 8 onwards, that the site will use to render the content. You write all the CSS, laying things out, making sure they are responsive and designed for mobile devices first. At the other end of the spectrum, you pull an existing theme off the shelf, like the many excellent ones you can download from the Drupal website. (As I write, there are 3,190 themes on the Drupal website.)

In between those extremes, moving slightly more customised than starting with an off-the-peg theme, you can take an off-the-peg theme and create a subtheme where you tweak the things you want to change. CSS is easiest, allowing you to change fonts, margins, relative sizes, images, colours, and so on. But template tweaks are possible too.

But I'm most comfortable one level further of controlling things myself. I don't like to write everything myself — it's far too much work, and involves a lot of wheel re-invention. But I find customising someone else's theme constrains my ability to get things looking how I want. I've done that in the past, and end up changing colours and typeface but not a lot else; as soon as you want to move content around on the screen, things start to get messy.

So I like to start with a base theme. A base theme is one that does the heavy lifting for you by giving you lots of default HTML and sensible CSS, but that doesn't make assumptions about what you will want to do on your own site.

My dilemma was: Which base theme to use?

Use a stable theme, as far as you can.

Relatively few of the 260 actively maintained Drupal 10 themes are base themes.

Even fewer are stable.

One of the things I've learnt using earlier versions of Drupal is the importance of using themes that are actively maintained and will continue to be so. Too many times, I've customised a theme, only for the maintainer to wander off and stop updating it. I then have to choose a new base theme in order to keep moving through the versions of Drupal core. If I've customised a theme designed as a base theme, it means designing a new theme using that base theme as a starter. If I've tweaked a theme designed as a fully finished theme, it means swallowing the fact that the visual appearance of the site is going to have to change. Neither is great.

For example, in various previous versions of Drupal core, I've used:

  • Omega. It was a very versatile base theme that was slightly further down the spectrum of doing things for you, but very capable with some great customisation tools. The maintainers started work on a Drupal 8 version of the theme, but never got one released. So, today, there are no releases available with current versions of Drupal core (Drupal 10 or 11). They got as far as 8.x-5.0-alpha7, and the project page says: “The current list of features for Omega Five is only a small sampling of the features available. This section will be updated with additional features and descriptions as it nears a stable release for Drupal 8.” Great in its day, but no more.
  • Zen. Another very versatile theme. You have to do your customisations in code, rather than with the kind of UI you got with Omega, but I see that as a strength. Again, a workhorse of a base theme for me in Drupal 7. However the project page tells you the extra features you get with 7.x-6.x compared to 7.x-5.x, but no mention of the Drupal 8+ version. The most recent commit was in February 2021 (to help with getting things ready for Drupal 9), and the one before that was 3 years earlier. Sadly (because it was a great theme) it's also run out of steam.
  • Pixture Reloaded. I loved this theme. It was more of a complete theme that you can recolour and adjust as you wish, but it was responsive and worked well. It was built on a base theme called Adaptive Theme. Back in the day, there were a good half dozen Adaptive Theme subthemes on the Drupal site. There was a website for Adaptive Themes where you could download any of them, or buy premium ones too. They offered a service to build a custom theme for your site. Sadly, none of this saw any releases beyond Drupal 7, and the Adaptive Themes website now just contains a domain-parking page.

You get the idea. Even since Drupal 8, there's been a whittling down. Just looking at themes that say they are actively maintained, and that have security team coverage, there are currently 210 themes that support Drupal 8, 181 that support Drupal 9, 162 that support Drupal 10, and 81 that support Drupal 11. So users of 129 of the 210 themes that support Drupal 8 are not able to move to Drupal 11, and nearly 50 of them can't use Drupal 10 either giving them no supported options. You'll recall that I'm using Drupal 10, not Drupal 11, because there are modules that haven't released Drupal 11 versions yet.

So as far as you can, try to find a base theme that is still being actively maintained. Look to see if code is still being committed. Look for two things in the issue queues. 1. Do the maintainers respond reasonably promptly? 2. Are there issues that have been stuck at "reviewed and tested by the community" for some time? If improvements / bug fixes have been tested, they should either be committed or moved to "won't fix" with a clear reason. Code stuck on RTBC is an amber flag in my book.

I also look for themes that are old. I don't want one that has just had its first release. I look for ones that have been around for several major versions of Drupal core, to demonstrate a maintainer who is active in moving it through the release cycles.

Bootstrap Barrio

My first attempt was a theme ecosystem named Barrio Bootstrap.

This is a really strong base theme. As the name suggests, it rewrites all of the Drupal templates to work within the Bootstrap framework. It is intended as a base theme. However, as you develop a sub-theme, it will help greatly if you can write your CSS using Sass; you get the benefits of the Sass mixins, you can use variables, and you can nest rules. There is a subtheme of Barrio Bootstrap called the Bootstrap 5 Sass Starter Kit. The maintainers recommend you extend that, rather than Barrio Bootstrap directly.

As I worked on site structure, I used the Sass Starter Kit unaltered. I think it was this that slightly put me off in the end. The fact I was able to use it out of the box means it made a lot of assumptions I'd want things coloured and laid out. As I came to start making the site look how I wanted it, it was harder work because I was editing to change inbuilt assumptions rather than working from scratch. I'm sure it can be quite intimidating to load an unaltered subtheme of a base theme, and to see just black text on white with no margins or borders between elements. However, if you're going to be using Chrome or Firefox developer tools to lay things out just how you want them, that is actually the best way to start and is going to be less work overall.

I was also slightly nervous that Barrio Bootstrap came with some colour editing tools in the UI. It wasn't immediately obvious where the theme saved the resulting CSS, or how that interfaced with the CSS that I had compiled myself from Sass. I found myself wishing all the configuration was in one place. If I was going to design a site myself, I don't want code potentially overwriting the CSS I've written; it could be hard to find where problems are coming from.

My final hesitation was the way it generates two CSS files, one with source links and one fully optimised. Shipping both, and changing which one is loaded in the theme's info file, felt clumsy. I'm sure to other people it feels really intuitive, but it didn't work for me.

So I looked to see what else was out there.

Radix

And I found the Radix base theme. The theme has a Drupal project page and a really good documentation site of their own. I am unclear what connection, if any, the Drupal theme Radix has with the wider Radix UI project. I suspect they're unrelated.

Unlike the Barrio family, this theme really is not designed to work on its own. In fact, it won't work properly. The theme ships with a starterkit for a subtheme, and sites will only render correctly if you have the elements from both a subtheme and the base theme in place. So your first step has to be to create your subtheme. Happily there are really good instructions for this on their website. I followed them, and everything just worked.

The more I use Radix, the more I like it as a base theme, and I can see this being my default base theme for future projects. Here are some of the things I like:

  • It's well maintained. Development started in 2012, and the first non-beta release was for Drupal 7 in February 2014. That means it's an 11-year old project, with some continuity in the maintainers. The project has not one but three commercial organisations sponsoring development time, which is a great way to make sure things continue. (To give link-credit where it's due, those are Ramsalt Lab, Chapter Three, and O8). In February 2025 (last month), there were 10 commits to the 6.0.x branch. The latest release works with Drupal 10.3 and higher, and Drupal 11; it's current. The maintainers are really responsive in the issue queue. I've found a couple of (small) bugs or ways to improve, and they've been really proactive picking up merge requests and helping me improve what I was proposing so they can commit the changes. That's a really refreshing experience that encourages collaboration.
  • It uses single-directory components. Once you get the hang of it, it's a great way to maintain a theme's code. There is a component directory for everything: headers, menus, nodes, pages, comments, and so on. The theme simply inherits the twig and CSS from the base theme unless you decide you want to override a specific component. It makes it easy to find any code you've changed; as long as you've used the component directory structure consistently, those changes will be exactly where you'd expect.
  • There's a great CLI tool for creating components, called drupal-radix-cli. It can bring across a component from the base theme and create the directory in your subtheme for you, and it can also create a brand new component if you want it to.
  • It uses Sass, and you can easily compile your CSS in either development or release mode. The former is ideal for seeing where particular lines of CSS come from so you can fix things; the latter is fully minimised and ready for production. I develop in development mode (npm run watch), then compile in release mode (npm run production) before I commit a series of changes to git. That keeps the git commit noise down, and means staging and production environments only ever pull the production-ready styling.
  • It works with BrowserSync. Now, in fairness, Barrio Bootstrap can do something similar, but Radix does it out of the box. If you run npm run watch, a web server starts running on a port in the 3000s that will render a copy of your site showing the most current layouts. Any time you make a change to the source .scss or template files, the CSS is automatically recompiled and a signal sent to your browser to reload. So you can tweak things like margins and colours and watch the effects in near real-time. I don't develop on my local machine, so I had to open the requisite ports through my development server firewall, but other than that this is a really easy way to work on a site's appearance.
  • It also uses Bootstrap; Barrio isn't the only way to get access to Bootstrap. Because this really is a base theme, you don't get a site that shouts visually "I was built with Bootstrap" unless you want that. But you get all the access to HTML classes to adjust things like margins, grid layouts and forms. You also get an easy way to make many adjustments using Bootstrap variables, as I'll discuss below. It means a really well-planned framework is behind the theme, so you get all those benefits, whilst giving you genuine freedom to control what your site looks like.

Tips for Working with Radix

As I've built a theme with Radix, I've learnt a few lessons along the way that are worth sharing.

  • Keep track of changes.
    • Your subtheme contains a copy of all the templates from the base theme, so the subtheme/templates folder contains a mixture of original and altered templates.
    • Your subtheme contains only those components that you've chosen to override (or create), so the subtheme/components folder contains only your alterations.
    • When you update the Radix base theme to a new version, you'll want to know what changes affect components or templates you've altered.
    • Having created my subtheme, I create copies of the components and templates folders of the base theme at the time I created my subtheme.
      cp -ar ../../config/radix/src/kits/radix_starterkit/templates ./.templates.orig
      cp -ar ../../config/radix/components ./.components.orig
    • Then you can use diff -urq to compare templates / components in the new Radix version with .templates.orig / .components.orig in your subtheme.
    • You can then carefully test bringing those changes across to the subtheme before updating your .templates.orig / .components.orig folders so they're ready as reference points for the next base theme update.
  • Link to components from templates.
    • When you create a component (deriving from a base template one, or generating a new one), your webpage won't automatically pick it up. That's possible to forget if your template uses custom twig, but very easy to forget if your template just contains CSS.
    • Your subtheme will use the templates in the templates folder to work out what HTML to render. The templates folder in the Radix theme is intentionally thin; most of the templates simply insert the HTML generated by a component, and let the components folder do the heavy-lifting. This helps keep your theme maintainable. Throughout the templates folder, you'll see code like this: {% include "radix:page-title" %}. That tells the theme engine to include the output from the page-title component within the radix theme.
    • The key thing is that all the templates embed the output of the radix components. Your custom component will not be included unless you change the template that calls it from {% include "radix:page-title" %} to {% include "your_subtheme:page-title" %}. As I say, it's easy to forget.
  • Whenever you change a template, you should clear the caches on your site.
    • Drupal will often cache templates.
    • If your working on theme development, you should always go to Home > Administration > Configuration > Development and check the box labelled "Do not cache markup".
    • However I've found that can still cache templates themselves, so running drush cr after a template change can help ensure those changes appear on the site.
  • Whenever you introduce new components that mean you have new CSS files appearing, you need to restart your laravel mix process.
    • When you first run npm run watch, the process seems to read all the files that need watching for changes.
    • If you change those files, the CSS will rebuild and the page will reload.
    • If you add a custom component that means an extra CSS file should be included in the page, this won't be picked up. You need to Ctrl+C, and run npm run watch again.
  • Use Bootstrap variables wherever possible.
    • As you start tweaking your site, you'll want to adjust margins, colours, font sizes and so on.
    • It's really tempting to write lines of scss in the components to do this for you, and that is often the right thing to do.
    • But don't forget that Bootstrap is a really powerful framework. It has a lot of variables set to sensible defaults for these things.
    • Sometimes, instead of writing custom CSS to adjust how things look, it's far better to set one Bootstrap variable to a new value, and the change is made for you in a way that is consistent.
    • Within your subtheme folder is a folder named node_modules, within that is a folder named bootstrap/scss, within that is a file named _variables.scss. At this point grep is your friend. Find the variable you want to change, and go to src/scss/base/_variables.scss within your subtheme. Set the variable you want.
    • For example, I wanted to stop <a> tags from underlining. Rather than writing a { text-decoration: none; } in the scss of a component, all I needed to do was enter $link-decoration: none; in my _variables.scss file

Sidebars

One thing I noticed straight away was that Radix doesn't give you sidebar regions for placing blocks.

I was tempted to feel grumpy and move on to look for another base theme, but then I realised this is deliberate and a good thing. Not every site uses sidebars. So let those sites that want them add them, and let those that don't have leaner mark-up.

It turns out it's easy to add sidebars. Given this isn't a requirement for everyone, but because it will be quite a common wish, I'll write that up in a separate post. Watch this space!

Blog Category:
Add new comment
The content of this field is kept private and will not be shown publicly.