I usually do my best to make my CSS code a lot simpler. It's really boring when you open an CSS file and you have no idea what's going on there, right?
It's really important, at least for me, to improve the way you write your code everyday. There is always a way to improve it. If you can't find it, share your code with us so we can understand your strategy. That would be amazing!
The code bellow would be used on my React Components and I achieved this template by writing many components for my project. I would be really happy if you tell me the pros and cons of the structure bellow, so I can improve myself.
If you have no idea about how CSS works please comment at the bottom and I will create a new article about it. This one, requires a little bit more of knowledge about CSS as I am not going through all the rules.
So, let's start!
First thing I would like to say is I don't use either id or tag references for my components. It will avoid elements from a component to be impacted by another component's CSS. Like, ".element h3" can impact ".element .inner-element h3" style.
For this article, let's consider this HTML structure:
And that's how I expect it to looks like in four different states:
- Selected
- Regular
- Regular with mouse hover over
- Button Disabled
I will be using SCSS (Sassy CSS) to make it easier to see the set of rules I will be creating. I won't talk about naming classes or standards but I have been using BEM in my projects.
First thing I will create in this CSS is the component wrapper. It will help me to isolate all the styles for this component as the main class for it won't be repeated anywhere else. That's why I don't like to use tag names in my CSS: A rule created for another component could impact my current one.
.element{
}
For this component I will be splitting my code in few parts and some of these parts can be repeated through each part.
- It will be my CSS code for the element wrapper or main class
- It will be my inner elements and others components classes if they exists
- It will be my list of selectors, like :hover, :active and so on.
- It will be my modifier classes.
- It will be my media queries which is the only one I don't want to repeat inside the inner classes.
Let's see how it looks like!
.element {
// element css
// inner elements and components
&__inner-element {
}
// selectors
&:hover {
}
// modifiers
&--selected {
}
// media queries
@media (min-width: 767px) {
}
}
This code splitting can be repeated inside any of inner elements, selectors, modifiers and media queries. In the case bellow, I repeated this structure inside media query:
...
@media (min-width: 767px) {
// wrapper element css
border: 1px solid #CECECE;
// inner element css
&__inner-element {
padding: 16px;
// another inner element css
&__action {
// inner element selector
&:hover {
background: #FF9900;
}
}
}
}
After sharing all this, i would like to invite you to see the full code for this.
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link
href="https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200;0,300;0,400;0,600;0,700;0,800;0,900;1,200;1,300;1,400;1,600;1,700;1,800;1,900&display=swap"
rel="stylesheet"
/>
<link href="./css/index.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="element element--selected">
<div class="element__inner-element">
<div class="element__inner-element__text">
<h2 class="element__inner-element__text__header">SELECTED</h2>
<p class="element__inner-element__text__paragraph">
ipsum dolor sit amet, consectetur adipiscing elit. Nunc non congue
tortor.
</p>
</div>
<div class="element__inner-element__action">
<button class="element__inner-element__action__button">
View now
</button>
</div>
</div>
</div>
<div class="element element">
<div class="element__inner-element">
<div class="element__inner-element__text">
<h2 class="element__inner-element__text__header">REGULAR</h2>
<p class="element__inner-element__text__paragraph">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non
congue tortor.
</p>
</div>
<div class="element__inner-element__action">
<button class="element__inner-element__action__button">
View now
</button>
</div>
</div>
</div>
<div class="element element">
<div class="element__inner-element">
<div class="element__inner-element__text">
<h2 class="element__inner-element__text__header">MOUSE HOVER</h2>
<p class="element__inner-element__text__paragraph">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non
congue tortor.
</p>
</div>
<div class="element__inner-element__action">
<button class="element__inner-element__action__button">
View now
</button>
</div>
</div>
</div>
<div class="element element--disabled">
<div class="element__inner-element">
<div class="element__inner-element__text">
<h2 class="element__inner-element__text__header">BUTTON DISABLED</h2>
<p class="element__inner-element__text__paragraph">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc non
congue tortor.
</p>
</div>
<div class="element__inner-element__action">
<button class="element__inner-element__action__button" disabled>
View now
</button>
</div>
</div>
</div>
</body>
</html>
.element {
$element: &;
background: #ffffff;
font-family: 'Nunito', sans-serif;
&__inner-element {
border: 1px;
padding: 8px;
display: flex;
align-items: center;
justify-content: space-between;
&__text {
&__header {
margin: 0 0 8px 0;
}
&__paragraph {
margin: 0 0 8px 0;
&:last-child {
margin-bottom: 0px;
}
}
}
&__action {
text-align: center;
&__button {
background: #cecece;
border: 1px solid #999999;
border-radius: 3px;
white-space: nowrap;
padding: 4px 8px;
&:hover {
transform: scale(1.2);
}
&:disabled {
opacity: 0.5;
}
}
}
}
&:hover {
background: #aadaad;
#{$element}__inner-element {
&__action {
&__button {
border: 0px;
background: #f04e23;
color: #ffffff;
}
}
}
}
&--selected {
background: #aaffad;
#{$element}__inner-element {
&__action {
&__button {
background: #cece00;
}
}
}
}
&--disabled {
opacity: 0.5;
&:hover {
background: #ffaaaa;
}
}
@media (min-width: 767px) {
border: 1px;
&__inner-element {
padding: 16px;
}
&--selected {
background: #eeeeee;
}
}
}
NOTE: We use interpolation #{$element} to avoid rewrite the wrapper class name. https://sass-lang.com/documentation/interpolation
What do you think? Please comment bellow if you have a better idea or if you liked the way I wrote this code.
Thanks!
Top comments (3)
It's new to me. I never try nested CSS before. Is it only works on SASS or not? Sorry I don't know a thing about SASS.
Anyway it's interesting, it's like you create a class inside CSS. It makes you easier to find your code. At first, I thought *this * will bulk your code, but if you put general properties in higher level it won't be an issue.
Nice article, I learned a lot from this. I'll give it a try in my next project.
It works only on SCSS or SASS. I had to mention that. SASS basically will convert this code into css. You can use variables for colors for example so u dont need to rewrite same hex all the time. There are many benefits (and few cons on my point of view) using SASS.
I think it’s much more organized than pure css and the way i wrote in this article is working for some time already without any change.
Thanks for your comment!
You're welcome