CSS Modules
In TaskFlow, we will write our CSS using CSS Modules. This is an intuitive way of writing CSS, as it is equal to writing regular CSS with a few extra perks. CSS Modules are locally scoped, meaning one doesn’t have to worry about name collisions in different files. To use them you simply provide a className
(in camelCase) which you can import in your component and use. It is advisable to decide on a naming convention which your whole team uses, to ensure consistency and readability.
Creating your css-module
As CSS Modules is supported by Next.js, you can simply create your first CSS Module like so:
.container {
background: skyblue;
height: fill-available;
position: fixed;
width: 100vw;
}
We're using position: fixed
and height: fill-available
so the height for mobile devices will fill the screen properly.
Now we're going to import all our classes in our Navigation component at once using import styles from './Navigation.module.css'
. Using import styles
is the way CSS Modules lets us import all classes from our module.css
file.
import styles from "./Navigation.module.css";
const Navigation = () => {
return (
<div className={styles.container}>
<h1>Hi 👋</h1>
</div>
);
};
Notice that the container
class is prefixed by styles
which makes sure that we are using the container class coming from our imported module.css
file.
Conditional styling
To change the styling of our navigation, we can simply use Javascript inside the className={}
brackets to determine what styles are being applied when, for example, isActive=true
const Navigation = () => {
const [isActive, setIsActive] = useState(false);
return (
<div className={`${styles.container} ${isActive && styles.active}`}>
<h1>Hi 👋</h1>
</div>
);
};
Here we can access the isActive
variable by breaking out of the so-called template literal
in the className
and applying the styles
by wrapping them inside ${}
.
.container {
background: skyblue;
height: 32px;
position: fixed;
width: 100vw;
}
.active {
height: fill-available;
}
Composition
In certain situations you can choose to compose a new class based on another class. This allows you to build a new class out of the styles defined by other pre-defined classes. Let's take the .active
class as an example, but now with composition:
.container {
background: skyblue;
height: 32px;
position: fixed;
width: 100vw;
}
.activeContainer {
composes: container;
height: fill-available;
}
And rewrite the logic in the className
.
const Navigation = () => {
const [isActive, setIsActive] = useState(false);
return (
<div className={isActive ? styles.activeContainer : styles.container}>
<h1>Hi 👋</h1>
</div>
);
};
This time, we didn't need to break out the template literal
. .activeContainer
overrides the height property from .container
but still has background-color: green
, position: fixed
and width: 100vw
.
It's up to you to decide when to use composition or just add a new class to the className
that overrides or adds a certain property.