CSS Modules
What are CSS Modules?
CSS Modules allow you to use CSS without relying on a global scope which can be very useful in an application setting or when you intend to create reusable components, since it avoids potential name clashes.
You can find more documentation about the concept here: https://github.com/css-modules/css-modules
Using CSS Modules in Melody
Melody supports CSS Modules indirectly. It offers a statement that can be used to import them. However, you'll need to configure Webpack appropriately to be able to truly use them.
{% import './home.css' as styles %}
<div class="{{ styles.home }}">
<div class="{{ styles.logo }}">
<svg xmlns="http://www.w3.org/2000/svg" width="270" height="270" viewBox="0 0 270 270">
<circle cx="135" cy="135" r="135" fill="#272361"></circle>
<path d="M146.14 87.94a45 45 0 0 0-53.24 53.23L48.08 186a9 9 0 1 0 3.38 3l42.79-42.79a45 45 0 0 0 9.34 16l-24.05 24.03a9 9 0 1 0 3.19 3.18l24.05-24.05a45 45 0 0 0 16 9.34l-11.43 11.43a9 9 0 1 0 3.26 3.1l13.18-13.18a45 45 0 0 0 18.35-88.12z" fill="#6eceb2"></path>
<circle cx="152.46" cy="100.5" r="13.5" fill="#fff"></circle>
<circle cx="150.46" cy="102.5" r="4.5" fill="#272361"></circle>
<circle cx="173.96" cy="117" r="9" fill="#fff"></circle>
<circle cx="171.96" cy="117" r="3" fill="#272361"></circle>
<path d="M140.2 34.39a4.45 4.45 0 0 1 0 6.36 4.62 4.62 0 0 1-6.47 0 4.45 4.45 0 0 1 0-6.36 4.62 4.62 0 0 1 6.47 0zM73.94 62.38a4.45 4.45 0 0 1 0 6.36 4.62 4.62 0 0 1-6.47 0 4.45 4.45 0 0 1 0-6.36 4.62 4.62 0 0 1 6.47 0zM206.45 62.38a4.45 4.45 0 0 1 0 6.36 4.62 4.62 0 0 1-6.47 0 4.45 4.45 0 0 1 0-6.36 4.62 4.62 0 0 1 6.47 0zM234.45 128.64a4.45 4.45 0 0 1 0 6.36 4.62 4.62 0 0 1-6.47 0 4.45 4.45 0 0 1 0-6.36 4.62 4.62 0 0 1 6.47 0zM200 201.62a4.45 4.45 0 0 1 0-6.36 4.62 4.62 0 0 1 6.47 0 4.45 4.45 0 0 1 0 6.36 4.62 4.62 0 0 1-6.47 0z" fill="#6eceb2"></path>
</svg>
</div>
<h1 class="{{ styles.title }}">
{{ message }}
</h1>
</div>
Importing only some classes
Instead of importing the entire CSS module into a variable you can also import specific CSS classes.
{% from './home.css' import home, logo as logoClass, title %}
<div class="{{ home }}">
<div class="{{ logoClass }}">
<svg xmlns="http://www.w3.org/2000/svg" width="270" height="270" viewBox="0 0 270 270">
<circle cx="135" cy="135" r="135" fill="#272361"></circle>
<path d="M146.14 87.94a45 45 0 0 0-53.24 53.23L48.08 186a9 9 0 1 0 3.38 3l42.79-42.79a45 45 0 0 0 9.34 16l-24.05 24.03a9 9 0 1 0 3.19 3.18l24.05-24.05a45 45 0 0 0 16 9.34l-11.43 11.43a9 9 0 1 0 3.26 3.1l13.18-13.18a45 45 0 0 0 18.35-88.12z" fill="#6eceb2"></path>
<circle cx="152.46" cy="100.5" r="13.5" fill="#fff"></circle>
<circle cx="150.46" cy="102.5" r="4.5" fill="#272361"></circle>
<circle cx="173.96" cy="117" r="9" fill="#fff"></circle>
<circle cx="171.96" cy="117" r="3" fill="#272361"></circle>
<path d="M140.2 34.39a4.45 4.45 0 0 1 0 6.36 4.62 4.62 0 0 1-6.47 0 4.45 4.45 0 0 1 0-6.36 4.62 4.62 0 0 1 6.47 0zM73.94 62.38a4.45 4.45 0 0 1 0 6.36 4.62 4.62 0 0 1-6.47 0 4.45 4.45 0 0 1 0-6.36 4.62 4.62 0 0 1 6.47 0zM206.45 62.38a4.45 4.45 0 0 1 0 6.36 4.62 4.62 0 0 1-6.47 0 4.45 4.45 0 0 1 0-6.36 4.62 4.62 0 0 1 6.47 0zM234.45 128.64a4.45 4.45 0 0 1 0 6.36 4.62 4.62 0 0 1-6.47 0 4.45 4.45 0 0 1 0-6.36 4.62 4.62 0 0 1 6.47 0zM200 201.62a4.45 4.45 0 0 1 0-6.36 4.62 4.62 0 0 1 6.47 0 4.45 4.45 0 0 1 0 6.36 4.62 4.62 0 0 1-6.47 0z" fill="#6eceb2"></path>
</svg>
</div>
<h1 class="{{ title }}">
{{ message }}
</h1>
</div>
By using the logo as logoClass
syntax you can specify a different name for the imported CSS class. This helps to avoid naming conflicts.
Use with the classes filter
When working with CSS classes, you'll often want to use the classes
filter for improved ergonomics.
{% import './styles.css' as styles %}
<button type="button" class="{{ {
base: styles.button,
(styles.primary): isPrimary
} | classes }}">{{ text }}</button>
The above example will add the styles.primary
class if the isPrimary
property is true
.
Using multiple classes
While the imported class names are just strings and can be concatenated easily (class="{{ styles.button }} {{ styles.buttonSmall }}"
) the ergonomics behind that are less than ideal and you'd be working around CSS modules instead of leveraging its full potential.
It is advisable to compose CSS classes within the CSS so that within the template you'll only ever need to work with one of them (unless you're dealing with modifiers like in the example above).
Both buttons will have the styles.button
and the styles.buttonSmall
classes but by leveraging the composes
functionality offered by CSS Modules, we've been able to create a more meaningful, semantically valuable class name: styles.secondaryButton
. And we've increased our separation of concern since the template no longer needs to know how such a secondary button is composed together from different CSS classes.
Last updated
Was this helpful?