Read time: 8 minutes. Interesting for (front-end) developers.
This article is a retrospective on our designing and theming efforts in 2016 in Open Social. It explains thoughts about the challenges we face with naming things in our distribution.
When building a base theme in a distribution the most important things to think about is that the code is understandable, flexible and extendable for other developers. When starting with such a big project you don’t know yet what features will be included at what stage. The best way to set up the theme for a large project such as Open Social is to use components.
In case you do not know what component-based means I will try to explain it briefly. Every page in a website consist of certain sections that are re-used on other pages. This could be for example a navigation, a button, breadcrumbs or the way you display an article. In essence you can break down each page into smallers sections. Each section can be broken down into smaller bits, which are usually called components. Atomic design describes this categorisation as organisms -> molecules -> atoms.
To make things simple: In component based theming we aim to build a system of components instead of thinking in ‘pages’. A page is a term borrowed from the physical world, like a book. For web design this way of thinking this concept is very limiting. That is why the industry is now moving away from this concept and talks about components instead.
Knowing we wanted to build Open Social out of components we needed a starting point. We could start with a blank sheet and create our own components. This is where we come to the next big challenge: naming things.
There are only two hard things in Computer Science: cache invalidation and naming things.
-- Phil Karlton
Giving components a good name that everyone understands is critical for good communication and teamwork. Before starting we have done some research of how other other platforms handle this and if there are design systems or frameworks we could use. The use of an existing framework serves two purposes: fast deliverance of features and components that communicate and have proven themselves on production sites. This will take away a lot of potential pitfalls while building the theme.
In the beginning it seemed logical to pick a framework that was based on Material Design, as this seems to be the next big design movement and will give Open Social a fresh modern look & feel with well documented design choices. However soon we found out Material Design is not mature yet and mostly designed for mobile apps. Transferring this one on one to a responsive website is hard and leaves too much space for interpretation.
After a while we decided to pick Bootstrap as our foundation. There was already a Drupal 8 Bootstrap base theme which provided many nice functionalities that integrated the components with the Drupal system. Also the Bootstrap component library is very extensive, it is the most used framework in the world and therefore it is good to understand for new / external developers. Bootstrap provides mainly the patterns & building blocks (components). It concerns less about the look & feel the user would notice. Therefore this framework seems to be a good choice. On top of Bootstrap we decided to use Material Design principles for visual depth, use of colors and animations.
The basic concept of Bootstrap
When looking at Bootstrap from a theoretical point of view we conclude that Bootstrap is a object-oriented CSS framework. As with any object-based coding method, the purpose of OOCSS is to encourage code re-use and, ultimately, faster and more efficient stylesheets that are easier to extend and maintain. To put this simple: we create small re-usable CSS classes that are really good at one thing and one thing only. Its behaviour is predictable and you can add the classes to the HTML elements where you needed without conflicts. Most of the times it is even self-explanatory how the element looks.
Let’s look at this example in Open Social
In this example we see a button in the sidebar that we want to align with the block below it. In Bootstrap it is pretty easy to get the right styles on it so it looks the way we want it:
.btn: makes it look like a button
.btn-primary: give it the primary color
.btn-raised: give the button depth
.btn-block: make it full width of its container (which is the sidebar)
.waves-effect: provide a nice click animation effect.
So our markup will look like
<a href="/node/add/topic" class="btn btn-primary btn-raised btn-block waves-effect">Create Topic</a>
Object-oriented CSS is a great method to be really flexible with theming. The classes can be re-used on a lot of places, you do not need to create new class names for each section and they are quite easy to understand and to remember.
So why change it?
When looking at the previous example we have a button that needs to span the full width of the sidebar. On mobile screens however we need to work with a different design.
We see now the button needs to display inline so there is space for another button on the same row. The filter block is displayed off-canvas and can be shown by clicking on this filter button.
For this design to work we need to add properties to one of the existing classes to make sure the button displays inline. This will always conflict with the meaning of .btn-block, which tells us the button is full width. This is where we have a problem.
So where does this problem come from? When analysing the naming conventions of Bootstrap we can see that most class names represent a certain behaviour or style. Look at the following examples. They are explaining exactly what element will look or behave like:
.center-block (center the block)
.navbar-fixed-top (this element stay at the top of the screen)
.btn-sm (small button)
This is good if you want your element to be like that in any viewport or location. But when you want want a certain element to behave different based on a location in the DOM structure or viewport you need to add css rules to a class that do not always make sense.
Because we want the user interface to be super intuitive and easy to use, we cannot and will not take shortcuts in our design.
Also in the example above we cannot assume all .btn-block elements need to display inline on mobile. So we need to make a condition based on a parent element. This is basically not what we want to do in general in component-based theming. We do not want to let our styles depend on the DOM structure as it might change in the future.
So this is one example of why the naming convention of Bootstrap is not ideal for Open Social. Because we want the user interface to be super intuitive and easy to use, we cannot and will not take shortcuts in our design.
Issues in the use of sub themes
Another issue with Bootstrap is the flexibility of overwriting. Our Social base theme aims to provide a solid theme that you can use of the box. But it also needs to be flexible enough to make changes in style where needed. Developers can do this in a sub theme. In the subtheme in general you change colors, fonts etc, but in some cases you want to overwrite a specific element. Let’s say you want a button that is styled in the primary color by default to have another color or style. You can simply isolate that button with a CSS selector and give it another style. But then the button will most likely still have the .btn-primary class. That isn’t communicating very well and might lead to confusion later on in the team. So then you also need to change the template file where that class is set. Then you can end up with a lot of template overwrites just for a few small style changes. This isn’t only a lot more work, it also causes a risk for future updates in the social base theme. The more you overwrite in the sub theme the less updates of the base theme will work out of the box.
How to solve these issues?
A good way of solving the issues we have now is by changing the naming conventions. Instead of choosing class names that describe the styles, like bootstrap does, we create components based on function. We do not give a button classes that describe its appearance, but describe the function. In our example the function of the button is to ‘add content’, so we can create a btn--add-content class. This doesn’t inform you about how the button will look. But it does tell you that it is a button and what that button is used for. It does still allow for flexible re-use on other places. The style of the button can change based on viewport or any other condition.
It does mean we need to think of a lot of new class names for our components. This was a problem we avoided at the beginning of the project, because we didn’t know what features and components were going to be build. Now that we have got a large collection of components in place we know what we are dealing with and can continue to improve on it.
With the new components we are creating we are not limiting ourselves to Bootstrap anymore, which means we can also use the BEM methodology immediately. This methodology is chosen by Drupal as well, as it works very well with the Drupal logic of components and modules.
I am not saying Bootstrap is a bad choice. I think in a lot of projects it provides enough flexibility to build your website fast. For Open Social it has certainly helped us to speed up our development and design process. But when you want full control and flexibility of your components it doesn’t meet the requirements 100%. Also it creates issues with overrides in styles in sub themes.
If you have thoughts on this transition we are making you are welcome to leave a comment. Our goal is to provide developers working with Open Social a smooth and simple experience. Any feedback on how to make things better are welcome.
Contributing to Open Social or Drupal
So how to go about contributing to Open Social and/or Drupal in general? For Open Social a good starting point is the Github Wiki. If you want a starting point for helping Drupal to grow you can find many different ways on the 'ways to get involved'-page on Drupal.org.