Skip to content

Latest commit

 

History

History
339 lines (260 loc) · 7.58 KB

16. Modern CSS.md

File metadata and controls

339 lines (260 loc) · 7.58 KB

Future-Proof CSS

In this file, you will learn about:

  • Declaring Variables
  • Prefixes
  • Default Values & Reseting Them
  • Block Element Modifier (BEM)
  • CSS & Frameworks

Before we starting these new features, we bring some content for you:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Styling</title>
    <link rel="stylesheet" href="style.css">
</head>

<body>
    <div class="container">
        <div class="box"></div>
    </div>
</body>

</html>
* {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 0;
}

.container {
  margin: 160px auto;
  width: 300px;
  height: 300px;
  border: 1px black solid;
}

.box {
  width: 200px;
  height: 100%;
  background-color: black;
  animation: hamid 800ms steps(1000, start) infinite;
}

@keyframes hamid {
  0% {
    transform: translateX(-400px);
  }

  50% {
    transform: translateX(0);
  }

  100% {
    transform: translateX(800px);
  }
}

We can add custom properties in the CSS. Until now, we worked with built-in properties in CSS and now we want add our own properties. To do that, we put -- to front of the property name which named by us, for example:

Important: Before we start, make sure you declare your variables in the :root root selector. It selects the document's root element

:root {
  --custom-property: value;
}

We apply and use this variable with var() function. This function takes two arguments; first one is for our custom variable name and the second one is for fallback value.

Note: The fallback value means that if the var() function can't find the declared variable, the second argument would be set for us, for example:

:root {
  --black-box-border: black;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 0;
}

.container {
  margin: 160px auto;
  width: 300px;
  height: 300px;
  border: 1px var(--black-box-border, black) solid;
}

.box {
  width: 200px;
  height: 100%;
  background-color: var(--black-box-border, black);
  animation: hamid 800ms steps(1000, start) infinite;
}

@keyframes hamid {
  0% {
    transform: translateX(-400px);
  }

  50% {
    transform: translateX(0);
  }

  100% {
    transform: translateX(800px);
  }
}

In this example, we declared the black-box-border variable (or custom property). Then we use this property in our both container and box wiht with var() function.

If we change the black to green, both container and box will be colored as green.

Prefixes

Some properties like grid, flexblox, transition, transform and animation don't support on older browsers like Safari old version and IE. We can convert our code to make sure all browsers support those features. We can do it with this https://autoprefixer.github.io/ web app. We can paste our CSS code:

:root {
  --black-box-border: black;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 0;
}

.container {
  margin: 160px auto;
  width: 300px;
  height: 300px;
  border: 1px var(--black-box-border, black) solid;
}

.box {
  width: 200px;
  height: 100%;
  background-color: var(--black-box-border, black);
  animation: hamid 800ms steps(1000, start) infinite;
}

@keyframes hamid {
  0% {
    transform: translateX(-400px);
  }

  50% {
    transform: translateX(0);
  }

  100% {
    transform: translateX(800px);
  }
}

and it gives the prefixed version like this:

:root {
  --black-box-border: black;
}

* {
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 0;
}

.container {
  margin: 160px auto;
  width: 300px;
  height: 300px;
  border: 1px var(--black-box-border, black) solid;
}

.box {
  width: 200px;
  height: 100%;
  background-color: var(--black-box-border, black);
  -webkit-animation: hamid 800ms steps(1000, start) infinite;
  animation: hamid 800ms steps(1000, start) infinite;
}

@-webkit-keyframes hamid {
  0% {
    -webkit-transform: translateX(-400px);
    transform: translateX(-400px);
  }

  50% {
    -webkit-transform: translateX(0);
    transform: translateX(0);
  }

  100% {
    -webkit-transform: translateX(800px);
    transform: translateX(800px);
  }
}

@keyframes hamid {
  0% {
    -webkit-transform: translateX(-400px);
    transform: translateX(-400px);
  }

  50% {
    -webkit-transform: translateX(0);
    transform: translateX(0);
  }

  100% {
    -webkit-transform: translateX(800px);
    transform: translateX(800px);
  }
}

Default Values

All browsers have/provide their own default values in their elements and styles. For example buttons are different from some browsers. or h1..h6 are different in some browser. We can remove those default behaviors with * universal selector. But we don't recommend you to use it. **But all developers use box-sizing: border-box in * selector:

* {
  box-sizing: border-box;
}

because the default value for box-sizing in all browsers is content-box and we can change the value manually.

Note: We can also use normilize.css package to resets all default behaviors which browsers provided. You can install this package in https://necolas.github.io/normalize.css/.

Block Element Modifier (BEM)

Some companies use this styles in their web application. It's a methodology that helps us to create reusable components and code sharing in front-end development.

The block name describes its purpose (menu or button), not its state (green or 100px):

<!-- Correct. The `menu` block is semantically meaningful -->
<div class="menu"></div>

<!-- Incorrect. It describes the appearance -->
<div class="green-area"></div>

If we have nested element in there, we can use - and __ in there, for example:

<body>
    <form action="" class="form">
        <button class="form-button"></button>
    </form>



    <form action="" class="search-form">
        <input type="text" class="search-form__input">
        <button class="search-form__button"></button>
    </form>
</body>

If we have more nested element, we can use more __, for example: block__elem1__elem2.

More on BEM in https://en.bem.info/methodology/quick-start/ and http://getbem.com/introduction/ websites.

The whole structure of BEM is:

.block__element--modifier

e.g. .from__button--red-button

CSS and Frameworks

Someone prefer to use frameworks to make their life easier, but there are some pros and cons in both vanilla CSS and frameworks.

CSS:

  • Pros:
    • Full control
    • No unnecessary code
    • Name classes whatever we want
  • Cons:
    • Build everything in scratch
    • danger of bad code

Component Frameworks:

  • Pros:
    • Rapid development
    • Follow best practices
    • No need to be an expert
  • Cons:
    • No control on our code
    • Unnecessary code and we don't want to keep them
    • All websites or web apps look the same (for example if we want use Bootstrap framework)
    • After many practicing, you understand who uses framework (or you can use Wappalyzer to see the technologies of websites)

Utility Frameworks:

  • Pros:
    • Faster development
    • Follow best practices
    • No expert knowledge needed
  • Cons:
    • Little control on our code
    • Unnecessary code and we don't want to keep them