Premise
This is based on the conditions we usually work under in projects, as follows:
- Uses Nuxt.js. Targets small-to-medium-sized web service (site) build projects.
- CSS is basically written as
scopedinside Vue files. - Normalize/reset CSS and the like are loaded via config, etc.
This article doesn't get into how to split components — that's a rabbit hole deep enough on its own.
What is HTML
Philosophical questions like this can feel vague and there are many opinions, but I want to go back to basics, so here's a note. HTML is structured text, and structure carries meaning. The only thing you need to keep in mind is that HTML's role is not to assemble a puzzle out of divs.
- Avoid using divs and spans that have no structural meaning (avoid using them purely for decoration)
- Use the elements redefined in HTML5 — section, main, nav, figure, etc. — to place elements semantically
- Fewer elements is generally better (though it depends on the case)
I think it's fine to use a div when you need one to wrap elements. In fact, limiting div usage to that purpose makes it clearer what each div is for.
Let's write it simply
"Write it simply" might sound difficult, but it may be easier to picture if you think of it as writing explicitly and plainly. Note that stripping out information ≠ writing simply.
What matters most is whether someone other than yourself can understand it. "Understandable to others" could be rephrased as "it's clear where each thing is written."
It might also help to keep the following in mind.
Do you misunderstand the DRY principle? - Qiita
Every piece of knowledge must have a single, unambiguous, authoritative representation within a system.
A concrete approach
So how should you actually write it? Let's go through some concrete examples.
- Give each section a unique class (think of it as naming a component)
- As much as possible, the name should be understandable on its own
- Good example: names like
hero,newsthat clearly convey their function or role - Bad example: names like
information1that depend on ordering or don't convey their role
- Good example: names like
- As much as possible, the name should be understandable on its own
- Naming under a section can generally just use common nouns
- Under
News, clear class names like.listor.itemare fine - That said, structure your SCSS properly and use the child combinator
>- Structuring SCSS this way is an important point for keeping it readable
- Under
- Try to keep the order in which you write classes consistent with the HTML side
- It helps to have a rule for the order you write things in: properties for that class → media queries for responsive support → child elements, and so on
- Even if similar properties recur, don't turn everything into a mixin
- Prioritize explicitness over saving effort
- Conversely, for things like color and font specifications, use variables to avoid inconsistency in notation
<!-- Example: a two-column layout below the hero area, showing news and embedded SNS -->
<template>
<main class="cout-wrap">
<section class="col-wrap wrap-center">
<div class="hero col-lg-10">
<h1>Lorem Ipsum</h1>
<p>Lorem Ipsum is simply dummy text. </p>
</div>
</section>
<section class="col-wrap wrap-center">
<div class="news col-lg-5">
<h2>News</h2>
<ul class="list">
<li class="item">
<div class="date">YYYY.MM.DD</div>
<div class="title">newstitle</div>
</li>
<li class="item">
<div class="date">YYYY.MM.DD</div>
<div class="title">newstitle</div>
</li>
<li class="item">
<div class="date">YYYY.MM.DD</div>
<div class="title">newstitle</div>
</li>
</ul>
</div>
<div class="sns col-lg-5">
<h2>SNS</h2>
<div class="twittermodule">
<iframe>...</iframe>
</div>
<div class="facebookmodule">
<iframe>...</iframe>
</div>
</div>
</section>
</main>
</template>
/* Structure of CSS written inside scoped */
.hero{
> h1{
hogehoge
}
> p{
hogehoge
}
}
.news{
> .list{
> .item{
> .date{
hogehoge
}
> .title{
hogehoge
}
}
}
}
Classes like .cout-wrap, .col-wrap, and .col-lg-10 are for layout. I'll cover those in a separate article, so let's skip past them here.
There are also places where properties are applied directly to HTML elements, but the idea is to add classes freely where needed. This makes maximum use of the benefits of scoped. I know there's a strong opinion out there that common nouns shouldn't be used as class names, but by using scoped together with the child combinator, we keep the scope of influence contained.
How to share common styles
There's the question of what to do with classes you want to share across components, but in my view, this ultimately ties back to the question of how to handle Atoms in Atomic Design. As you break components into layers and load each one, the leaf-level components end up being little more than a bundle of style properties. A button component at the Atoms level, for example, really doesn't do much beyond specifying styles.
For properties like that, it seems best to create classes and load them globally. Turning them into Vue file components is also clear, but for small-to-medium projects, going too far with componentization tends to add more burden than it saves.
Things to avoid
The following are anti-patterns — some pretty basic mistakes I've noticed while doing reviews.
- Don't write properties applied to the same class in scattered places
- Don't use property names like
widthorflexas class names - Don't use abbreviations
- Things like
info, which I tend to use myself too — stop using it - Same goes for
btn
- Things like
- Don't create classes whose meaning is unclear
- Don't use class names like
mini_info
- Don't use class names like
- Don't use class names like
sp,tb - Use
:nth-childor:first-of-typeonly for a list of identical elements- Don't use them to target elements with different roles based on their order within a parent element
- Avoid having to write the same thing over and over
- Avoid writing the same thing repeatedly for each device width in media queries
This time, I focused on CSS design for small-to-medium-sized projects. I also referenced articles like the ones below. Comparing OOCSS, BEM, SMACSS, FLOCSS, and RSCSS to find the design philosophy that suits you | Black Everyday Company
A summary of ECSS's overview and approach - Qiita
I'm not a fan of overly verbose class names, so I'd like to digest these ideas in my own way and put them into practice. If you have any thoughts or feedback, please feel free to share.