1 Comment // Reading Time: 7 min.
Just another framework?
Traditional CSS frameworks such as Bootstrap, Foundation and Bulma specify how HTML elements, such as buttons, inputs and tooltips, etc. look. They come with prefabricated UI components styled with CSS. This creates the typical styles for the respective framework, which can be found on various websites. In other words: design elements resemble each other and appear "off the peg". Bootstrap, for example, provides a button component:
<button type="button" class="btn btn-primary">
Bootstrap
</button>
Code example 1: Button component in Bootstrap
The code above creates the following button:
UI component 1: Button from the Bootstrap website (source: Bootstrap)
With the help of the two CSS classes btn
and btn-primary
, the CSS properties such as color
, background-color
, border
, font-size
, font-weight
and text-decoration
are defined.
Utility classes
It is different with Tailwind CSS: Here, no ready-styled UI components, such as UI component 1, are provided. Instead, utility classes can be used to create UI components on a granular basis. Granular means that individual properties of a design element, such as the CSS attributes color
, background-color
, but also display
and text-align
, can be controlled by using CSS classes. These CSS classes are also called utility classes. The button from code example 1 can be implemented with Tailwind CSS as in code example 2:
<button type=“button“ class="rounded bg-blue-500 hover:bg-blue-700 py-2 px-4 text-white">
Tailwind
</button>
Code example 2: Button element with Tailwind CSS utility classes
UI component 2: Tailwind CSS Button
Mit den verwendeten CSS-Klassen werden Klassen vergeben, die jeweils einen Layout-Aspekt des Buttons abbilden:
With the CSS classes rounded
, bg-blue-500
, hover:bg-blue-700
, py-2
, px-4
and text-white
used, classes are assigned that each represent one layout aspect of the button:
Utility class | CSS style |
---|---|
rounded | border-radius: 0.25rem; |
bg-blue-500 | --tw-bg-opacity: 1; |
py-2 | padding-top: 0.5rem; |
px-4 | padding-left: 1rem; |
text-white | --tw-text-opacity: 1; |
Table 1: Utility classes and their CSS properties
What does 'utility-first' mean?
Tailwind CSS has dedicated itself to this granular approach: It is called the "utility-first CSS framework" (source: Tailwind CSS). The preceding very simple example serves to illustrate the utility-first approach. The following UI component and related code examples are from Tailwind CSS and illustrate the impact on the scope and style of the code.
UI component 3: Chat component (source: Tailwind CSS).
<div class="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-lg flex items-center space-x-4">
<div class="shrink-0">
<img class="h-12 w-12" src="/img/logo.svg" alt="ChitChat Logo">
</div>
<div>
<div class="text-xl font-medium text-black">ChitChat</div>
<p class="text-slate-500">You have a new message!</p>
</div>
</div>
Code example 3: Implementation of the chat component with Tailwind CSS (source: Tailwind CSS).
In the outer div element, for example, the classes flex
, p-6
and rounded-xl
are used. The class flex
turns the div element into a flexbox, p-6
adds padding to it and rounded-xl rounds off the corners of the div element. The above classes and their styles are listed in Table 2.
Utility class | CSS style |
---|---|
flex | display: flex |
p-6 | padding: 1.5rem |
rounded-xl | border-radius: .75rem |
Tabelle 2: Beispiele von Utility-Klassen
In code example 3, it is noticeable that the UI component can be implemented with only six HTML elements. However, a remarkably large number of utility classes were used, especially in the first div element.
Classic approach
In contrast to the utility-first approach, styles are classically separated from HTML code. The styles are then outsourced in the form of CSS files with self-defined classes, ids and further selectors. The chat component (UI component 3) would be implemented with this approach as in code example 4.
<div class="chat-notification">
<div class="chat-notification-logo-wrapper">
<img class="chat-notification-logo" src="/img/logo.svg" alt="ChitChat Logo">
</div>
<div class="chat-notification-content">
<h4 class="chat-notification-title">ChitChat</h4>
<p class="chat-notification-message">You have a new message!</p>
</div>
</div>
<style>
.chat-notification {
display: flex;
max-width: 24rem;
margin: 0 auto;
padding: 1.5rem;
border-radius: 0.5rem;
background-color: #fff;
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
.chat-notification-logo-wrapper {
flex-shrink: 0;
}
.chat-notification-logo {
height: 3rem;
width: 3rem;
}
.chat-notification-content {
margin-left: 1.5rem;
padding-top: 0.25rem;
}
.chat-notification-title {
color: #1a202c;
font-size: 1.25rem;
line-height: 1.25;
}
.chat-notification-message {
color: #718096;
font-size: 1rem;
line-height: 1.5;
}
</style>
Code example 4: Implementation of the chat component with HTML and external CSS file (Source: Tailwind CSS)
In code example 4, it should be noted that the styles are inserted in the HTML instead of in an external file to make it easier to understand. With this presentation, some aspects become clear:
- little HTML code with few, self-defined CSS classes
- numerous, self-defined styles
Summary: Advantages and disadvantages of Utility-First
Anyone familiar with HTML markup and coding in general knows how tedious it can be to come up with suitable class names for components and to agree on both the class names and any other naming conventions within the team. With utility classes, this effort is eliminated. Moreover, after getting used to the framework, productivity increases because there are no context changes between the coding in CSS files and HTML files.
On the other hand, the Tailwind CSS component looks jumbled and overloaded with classes. With the plugin Headwind for the IDE Visual Studio Code, the class names of the HTML elements are automatically put in a consistent order when saving the file. Names of duplicate CSS classes are also removed.
Another disadvantage of Tailwind CSS is that the utility classes in the markup are repeated for the same HTML elements. So, for example, if you want to use a button in different places, the class names would repeat in the different components of the application. This would violate the coding principle with the acronym "DRY" (Don't Repeat Yourself) in coding.
If the button in code example 2 is to be used repeatedly in the code, with the help of the template engine used (e.g. in vue or jsx formats) a reusable component could be created (code example 5).
<template>
<button class="rounded bg-blue-500 hover:bg-blue-700 py-2 px-4 text-white">
Tailwind
</button>
</template>
<script>
export default {
name: ‘Button’,
};
</script>
Code example 5: vue.js button component with Tailwind CSS utility classes
Framework overhead
Another disadvantage of Tailwind CSS and CSS frameworks in general is the overhead. Overhead is the part of the framework's code that is contained in the production build of the framework (e.g. bootstrap.min.css) but is not used in the application. For example, Bootstrap offers the possibility to include only the CSS classes that are needed for the grid layout. In Tailwind, this is done with the help of the configuration file tailwind.config.js
.
module.exports = {
content: ['./src/**/*.{html,js}'],
theme: {
colors: {
…
},
fontFamily: {
…
},
}
Code example 6: Tailwind CSS configuration file
To illustrate one aspect in connection with the overhead, only a very reduced configuration file is given as an example. The structure of the configuration file is a JavaScript object. The key content contains an array in which all paths to HTML templates, JavaScript components and all other resources that contain Tailwind CSS class names are listed. Using regular expressions, Tailwind searches for these classes in these files, e.g. rounded
, bg-blue-500
, hover:bg-blue-700
, py-2
, px-4
. CSS classes found in this way are added to the generated CSS. This ensures that only CSS code that is really needed is supplied. The overhead is eliminated with this measure.
Disadvantages | Advantages |
---|---|
HTML code can become quite complex due to the number of class names used. | It is possible to work directly in the HTML code without context switching between CSS and HTML files. |
Without the use of a template engine, redundant code may be produced. | Changes to an HTML element or in a component can be made without affecting other elements (no side effects). |
Overhead may occur if the key content in the JavaScript object of the configuration file is not configured correctly. | After becoming familiar with the system, the creation of user interfaces is quick and easy. |
Contact us!
We are a digital agency, which is specialized in the development of digital products. Our core topics are websites and portals with TYPO3, eCommerce with Shopware and Android and iOS-Apps. In addition, we deal with many other topics in the field of web development. Feel free to contact us with your concerns!
Comments
Joël Mai
at 08.04.2024Hey! Cooler Beitrag!
Ich mach mir seit Monaten Gedanken darüber wie ich mein Frontend Stack für TYPO3 Projekte am besten aufbaue. Bootstrap fühlt sich bisher wie ein massiver Overhead an und [...] Hey! Cooler Beitrag!
Ich mach mir seit Monaten Gedanken darüber wie ich mein Frontend Stack für TYPO3 Projekte am besten aufbaue. Bootstrap fühlt sich bisher wie ein massiver Overhead an und Custom CSS für jedes Projekt ist sehr aufwendig. Bisher fahre ich daher mit einer Art Template und Post CSS Kombi... Tailwind klingt daher sehe verlockend, aber ich Frage mich wie sinnvoll es ist in der Kombination mit Fluid und Konfigurierbarkeit des Frontend durch Redakteure :/
Anregungen? Vorschläge?