How to write CSS/SCSS

Verze:

02. 03. 2022

Zodpovědná osoba:

Dominik Šlechta

CSS - Sass preprocessor

In templates we use the BEM notation style. We do not use Bootstrap or other frameworks.
Examples of solutions: www.zebra-q.cz/, esd-clevertex.cz
// Blocks are named as standard CSS classes
.block {
}
// Elements declared with 2 underscores, after block
// Grandchildren are named after their grandparent class 
// (.block__grandchild NOT .blog__parent__grandchild)
.block__element {
}
// Modifiers declared with 2 dashes, after block or after element
.block--modifier {
}
// element and modifier together
.block__element--modifier {
}
We try not to nest individual classes, we can nest only in case of easy writing when for example headings are pulled, content without classes from the database or one-step nesting when specifying in which section for example this part should look a bit different
.menu {
background: #333;
padding: 10px;
}

.menu__list {
list-style: none;
padding: 0;
}

.menu__item {
display: inline-block;
padding: 5px;
}

.menu__link {
color: white;
text-decoration: none;
}

.menu__link--active {
font-weight: bold;
}

Use nesting moderately - no more than 2 levels deep
Prefer BEM methodology - ensure clarity and simplicity
Write universal styles - make them easy to reuse

Although SCSS allows nesting, overuse leads to hard to maintain code. Properly structuring styles with BEM will make your life easier and keep your project clean

 

<section class="about-info">
    <div class="about-info__content --content">
        <div class="about-info__container --row --flex-space">
            <div class="about-info__left-column --column --flex-centre --w-12 --w-m-6">
                <div class="about-info__figure">
                    <img class="about-info__img" src="{$web['ABOUT_US_INFO_IMG']}" alt="Craftsmanship Image">
                </div>
            </div>
            <div class="about-info__right-column --flex-centre --column --w-12 --w-m-6">
                <div class="about-info__text --flex-centre --text-center">
                    <h2 class="about-info__title --bold">
                        {$web['ABOUT_US_INFO_TITLE']}
                    </h2>
                    <div class="about-info__subtitle --title-h2 --thin --text-brand-lighter">
                        {$web['ABOUT_US_INFO_SUBTITLE']|noescape}
                    </div>
                    <div class="about-info__perex">
                        {$web['ABOUT_US_INFO_PEREX']}
                    </div>
                    <a href="#" class="about-info__button button button--brand">
                        {$web['ABOUT_US_INFO_BUTTON_TEXT']}
                    </a>
                </div>
            </div>
        </div>
    </div>
</section>
 
.about-info {
    background: $color__gray-lighter;
    padding-top: 25px;
    margin-bottom: 20px;

    @include media($medium){
        padding-top: 50px;
        margin-bottom: 40px;
    }

    @include media($large){
        margin-bottom: 60px;
    }
    @include media($xlarge){
        margin-bottom: 80px;
    }
}

.about-info__figure{

    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 25px;
    width: 100%;

    @include media($tiny){
        width: 75%;
    }

    @include media($small){
        width: 50%;
    }

    @include media($medium){
        padding-right: 17px;
        margin-bottom: -25px;
        width: 100%;
    }

    @include media($large){
        padding-right: 35px;

        margin-bottom: -50px;
    }
}

.about-info__img{
    object-fit: cover;
    width: 100%;
    height: 100%;
}

.about-info__subtitle {
    margin-bottom: 20px;
    color: $color__primary-lighter;
}

.about-info__perex{
    margin-bottom: 15px;
    line-height: 1.38;
    color: $color__text-dark;
    font-weight: 300;

    @include media($medium){
        margin-bottom: 30px;
        //text-transform: uppercase;
    }

    @include media($large){
        font-size: 1.8rem;
    }
}
 
 
Of course, every rule has its exceptions, BUT! Don't abuse, just everything should have its class and everything that has its class will be styled on one class!

Exceptions:

content.scss
// -- Content --

.content {
  font-size: 1.5rem;
}

.content__row {
  display: flex;
  flex-wrap: wrap;
  margin: 0 -8px;
}

.content__column {
  padding-left: 8px;
  padding-right: 8px;
}

.content__flex {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
}

.content--section {
  color: $color__text-dark;
  margin: 0 auto $offset__block-m;
  max-width: 768px;
  width: 100%;

  &:last-child {
    margin-bottom: 0;
  }

  @include media($large) {
    margin: 0 0 $offset__block;

    &:last-child {
      margin-bottom: 0;
    }
  }
}

// -- Content | Title --

.content > h3,
.content__column h3 {
  margin: 0 0 15px;
  font-size: 2.4rem;

  @include media($medium) {
    font-size: 3rem;
  }
}

.content > h2,
.content__column h2 {
  margin: 0 0 10px;
}

// -- Content | List --

.content > ul,
.content > p ul,
.content__column ul,
.--list {
  margin: 0 0 20px;
  @include media($medium) {
    margin-bottom: 40px;
  }
}

.content > ul li,
.content > p ul li,
.content__column ul li,
.--list-item {
  font-size: 1.6rem;
  margin: 10px 0 $offset__tiny 23px;
  position: relative;
  font-weight: 300;

  &::before {
    background: $color__primary-light;
    border-radius: 2px;
    content: "";
    height: 8px;
    left: -21px;
    position: absolute;
    top: $offset__small;
    width: 8px;
  }

  @include media($medium) {
    font-size: 1.8rem;

    &::before {
      border-radius: 50%;
      width: 10px;
      height: 10px;
    }
  }
}

// -- Content | List Num --

.content > ol,
.content > p ol,
.content__column ol,
.--list-num {
  counter-reset: counter-list;
  margin: 0 0 $offset__large;
}

.content > ol li,
.content > p ol li,
.content__column ol li,
.--list-num-item {
  counter-increment: counter-list;
  font-size: 1.6rem;
  padding: 10px 0 $offset__tiny 23px;
  position: relative;

  &::before {
    font-weight: bold;
    content: counter(counter-list) ".";
    left: 0;
    position: absolute;
    top: 10px;
    color: $color__primary-light;
    font-size: 1.6rem;
  }

  &:nth-child(n + 10) {
    &::before {
      content: counter(counter-list);
    }
  }

  @include media($medium) {
    font-size: 1.8rem;

    &::before {
      font-size: 1.8rem;
    }
  }
}

// -- Content | Text --

.content > p,
.content__column p {
  margin: 0 0 30px;
  color: $color__primary-dark;
  font-size: 1.6rem;
  font-weight: 300;

  @include media($medium) {
    font-size: 1.8rem;
  }
}

.content > a,
.content > p a,
.content table a,
.content__column a,
.content ul a,
.content ol a {
  text-decoration: underline;
}

/* Content video */

.content video {
  height: auto;
  aspect-ratio: 16/9;
}

/* Content iframe */

.content iframe {
  height: auto;
  aspect-ratio: 16/9;
}

// -- Content | Table --

.content .table-wrapper {
  border: 1px solid #eee;
  margin-bottom: 25px;
  overflow-x: auto;
  border-radius: 5px;
  font-size: 1.5rem;

  .--bold {
    color: $color__text-dark;
  }
}

.content table {
  border: none;
}

.content table td,
.content table th {
  padding: 8px 4px;
  border: none;

  @include media($small) {
    padding: 10px 4px;
  }
}

.content table tr {
  padding: 10px;
  border-bottom: 1px solid $color__primary-border;

  // &:nth-child(even) td {
  // 	background: $color__bg-section;
  // }
}

.content table td {
  font-size: 1.4rem;
  color: $color__primary-dark;
  padding-left: 15px;

  &:nth-child(2) {
    font-weight: 500;
  }

  @include media($medium) {
    font-size: 1.6rem;
  }
}

.content table th {
  font-weight: 700;
  color: $color__text-dark;
  border-bottom: 1px solid $color__table-border;
  font-size: 1.8rem;
}

// -- Content | Image --

.content > img,
.content > p img,
.content__column img,
.content > figure img {
  margin: 0 0 12px;
  height: auto;
}
​

Tags in translations!
For example, if we have a title and we need a subtitle. We use the heading class and we embed span.

Media queries:

We use media qeries for better clarity of wrapping to mobile/tablet resolution.

We have several sizes where the contents are breaking:

$min:               320px;
$tiny: 480px;
$small: 640px;
$medium: 960px;
$large: 1260px;
$xlarge: 1580px;
$max: 1920px;

Media queries for us looks like this:

@include media($medium){

}

 

Write styling from top to bottom i.e:

From the largest unit to the smallest, and from the smallest size to the largest. The so-called mobile first approach. It's much better to style up from mobile to larger screen than the other way around.

The css then looks like this:

.subitems{
  padding-top: 2.5rem;
  padding-bottom: 2.5rem;

  @include media($medium){
    padding-top: 4.4rem;
    padding-bottom: 5rem;
  }

  @include media($large){
    padding-top: 6.6rem;
  }

  @include media($xlarge){
    padding-top: 8.9rem;
  }
}

 

And once again, DO NOT NEST, unless it is absolutely necessary!!