Магия CSS вне Хогвартса

Никита Дубко, iTechArt Group

Магия CSS
вне Хогвартса

Никита Дубко, iTechArt Group

Day after end
apofiss.deviantart.com
Никита Дубко

Никита Дубко

MinskCSS MinskJS CSS-Minsk-JS
Hogwarts Гриффиндор Слизерин

CSS vs JavaScript

Disco (by MaryG)
< offline >

Illustration 'face' (by white pallet)
< offline >

Moustached Nanny (by Julia Muzafarova)
< offline >

Clock (by dark_mefody)
< offline >

Earth World (by akella)

Бумага

Мой путь

Скука Bootstrap jQuery
CSS Secrets Book
Анна Селезнева

MinskCSS Meetup #1

First time
Pure CSS Images Guide
Pure CSS Images Koala

#dailycssimages

Google
Email
Flying lesson
Quidditch
Dave Seven

#CodePenChallenge

Stargate (by dark_mefody)
< offline >

Picked Pens
Book

CSS Magic Guideline

Hugrid

Наш мозг
любит обманываться

Shadow illusion

Слои, много слоев

Слои

Сколько стилизуемых элементов?

<div></div>
div {
    border: 5px solid red;
}
div::before {
    border: 5px solid green;
}
div::after {
    border: 5px solid blue;
}

А если так?

<html>
    ::before
    <head>
        ::before
        ::after
    </head>
    <body>
        ::before
        ::after
    </body>
    ::after
</html>

Прямоугольник 1

div {
    background: #f60;
}

Прямоугольник 2

div {
    background: linear-gradient(
        transparent 25%,
        #f60 25%, #f60 50%,
        #60f 50%, #60f 75%,
        #6f0 75%
    );
}

background:

    background-image ||
    background-position [ / background-size ]? ||
    background-repeat ||
    background-attachment ||
    background-origin ||
    background-clip

Прямоугольник 3

div {
    background:
        linear-gradient(#f60, #f60) 0 0,
        linear-gradient(#6f0, #6f0) 50px 100px,
        linear-gradient(#60f, #60f) 100px 200px;
    background-repeat: no-repeat;
    background-size: 100px 100px;
}

Прямоугольник 3.1

div {
    background:
        linear-gradient(#f60, #f60) 0 0 / 100px 100px
            no-repeat scroll padding-box border-box,
        linear-gradient(#6f0, #6f0) 50px 100px / 100px 100px
            no-repeat scroll padding-box border-box,
        linear-gradient(#60f, #60f) 100px 200px / 100px 100px
            no-repeat scroll padding-box border-box;
}

Эллипс 1

div {
    background: #f60;
    border-radius: 50%;
}

Эллипс 2

div {
    background:
        radial-gradient(
            #f60 0, #f60 70.6%,
            transparent 70.7%
        );
        /* a2 + b2 = c2 */
}

Эллипс 3

div {
    background: #f60;
    clip-path: ellipse();
}

Треугольник 1

div {
    width: 0;
    height: 0;
    border: 100px solid transparent;
    border-left-width: 200px;
    border-bottom-color: #f60;
    border-top-color: #6f0;
    border-left-color: #60f;
    border-right-color: #06f;
}

Треугольник 1.1

div {
    width: 0;
    height: 0;
    border: 100px solid transparent;
    border-left-width: 200px;
    border-top-width: 0;
    border-bottom: 300px solid #f60;
}

Треугольник 2

div {
    background:
        linear-gradient(
            to right top,
            #f60 50%, transparent 50.1%
        );
}

Треугольник 2.1

div {
    width: 300px;
    height: 300px;
    background:
        linear-gradient(
            to left top, #06f 50%, transparent 50.1%
        ) 0 0 / 200px 100%,
        linear-gradient(
            to right top, #f60 50%, transparent 50.1%
        ) 200px 0 / 100px 100%;
    background-repeat: no-repeat;
}

Треугольник 3

div {
    background: #f60;
    clip-path: polygon(
        66.666% 0%,
        0% 100%,
        100% 100%
    );
}

border-radius

div {
    border-radius: 50%;
}
.egg {
    border-radius:
        100px 100px 100px 100px /
        200px 200px 100px 100px;
}

border-radius

.arc {
    border-top: 50px solid #f60;
    border-radius:
        101% 101% 0 0 /
        200% 200% 0 0;
}
Рисуем сову

Francine (by Diana Smith)
< offline >

box-shadow

div {
    width: 200px;
    height: 200px;
    border-radius: 50px;
    border: 5px solid #06f;
    background: transparent;
    box-shadow:
        50px 50px 0 0 #f60,
        -50px 100px 0 50px #0f6,
        inset 10px 10px 0 30px #f06;
}

clip-path (читерство)

div {
    width: 200px;
    height: 200px;
    background: #f60;
    clip-path:
        polygon(
            50% 0%, 61% 35%, 98% 35%,
            68% 57%, 79% 91%, 50% 70%,
            21% 91%, 32% 57%, 2% 35%, 39% 35%
        );
}

Clippy

Clippy
Clip-path

Инструменты CSS-волшебника 🧙‍♂️

HP1

Lynn Fisher
a.singlediv.com

Single Div

Что дальше?

Expectation

animation

animation

Timeline

3D

3D

Ana Tudor
Simplifying CSS Cubes with Custom Properties

Куб (HTML)

<div class="cube">
    <div class="cube__face"></div>
    <div class="cube__face"></div>
    <div class="cube__face"></div>
    <div class="cube__face"></div>
    <div class="cube__face"></div>
    <div class="cube__face"></div>
</div>

Куб (CSS)

.cube__face {
    transform:
        rotate3d(var(--i), var(--j), 0, calc(var(--m) * 90deg))
        translateZ(calc(.5 * var(--cube-edge)));
}
.cube__face:nth-child(1) { --i: 0; --j: 1; --m:  0; }
.cube__face:nth-child(2) { --i: 0; --j: 1; --m:  1; }
.cube__face:nth-child(3) { --i: 0; --j: 1; --m:  2; }
.cube__face:nth-child(4) { --i: 0; --j: 1; --m:  3; }
.cube__face:nth-child(5) { --i: 1; --j: 0; --m:  1; }
.cube__face:nth-child(6) { --i: 1; --j: 0; --m: -1; }

Cube Wave (by dark_mefody)
< offline >

Zombie (by dark_mefody)
< offline >

Stargate (by dark_mefody)
< offline >

Как ускориться?

Car

Правильные инструменты

Deathly Hallows
Emmet logo

Emmet

Zen Coding logo

Zen Coding

Zen HTML

Emmet

ol.list>li.list__item*4>a<TAB>
<ol class="list">
    <li class="list__item"><a href="http://"></a></li>
    <li class="list__item"><a href="http://"></a></li>
    <li class="list__item"><a href="http://"></a></li>
    <li class="list__item"><a href="http://"></a></li>
</ol>

Emmet

posa
w100
h50
bg#0
position: absolute;
width: 100px;
height: 50px;
background: #000000;

live-server

npm i -g live-server

live-server
Serving "~/Sites/talks" at at http://127.0.0.1:8080
Change detected ~/Sites/talks/css-magic/wsd.html
Change detected ~/Sites/talks/css-magic/wsd.html

Препроцессоры

LESS SASS Stylus Pug PostCSS
Codepen

Зачем?

Why

1. Эксперименты

Explosion

2. Опыт

Dumbledore
Swift

3. Понимание нюансов

Potion making

padding-top: 50%;

С чего начать?

Start

Этапы построения магии на CSS

#dailycssimages
#codepenchallenge
#100daysofcode

#dailycssimages gist

Этапы построения магии на CSS

  1. Идея 💡

8. Ждите

Hagrid
Retweet
Hogwarts

Попробуем?

// Pug
- for (let j = 14; j > 0; j--)
    .square
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
<div class="square"></div>
$size: 3vmin;
$n: 14;
$light: #ededed;
$dark: #232323;

body {
    margin: 0;
    min-height: 100vh;
    background-color: $light;
}
.square {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background-color: $light;
}

.square:nth-child(2n+1) {
    background-color: $dark;
}
@for $i from 1 through $n {
    .square:nth-child(#{$i}) {
        width: $size * $i;
        height: $size * $i;
    }
}
@for $i from 1 through $n {
    $c: $n + 1 - $i;
    .square:nth-child(#{$c}) {
        width: $size * $i;
        height: $size * $i;
    }
}
@keyframes rot {
    0%, 100% {
        transform: rotate(30deg);
    }
    50% {
        transform: rotate(-15deg);
    }
}

.square {
    animation: rot infinite ease 1.5s;
}
@keyframes rot {
    0%, 100% {
        transform:
            translate(-50%, -50%)
            rotate(30deg);
    }
    50% {
        transform:
            translate(-50%, -50%)
            rotate(-15deg);
    }
}
@for $i from 1 through $n {
    $c: $n + 1 - $i;
    $t: 1.5 * $n / $c;

    .square:nth-child(#{$c}) {
        animation-duration: #{$t}s;
    }
}
@for $i from 1 through $n {
    @keyframes rot#{$i} {
        0%,
        #{50 - 150 / ($i+3)}%,
        100% {
            transform: translate(-50%, -50%) rotate(30deg);
        }
        50%,
        #{100 - 150 / ($i+3)}% {
            transform: translate(-50%, -50%) rotate(-15deg);
        }
    }
}
@for $i from 1 through $n {
    $c: $n + 1 - $i;

    .square:nth-child(#{$c}) {
        animation-name: rot#{$i};
    }
}
$size: 3vmin;
$n: 14;
$light: #ededed;
$dark: #232323;

body {
  margin: 0;
  min-height: 100vh;
  background-color: $light;
}
.square {
  position: absolute;
  top: 50%;
  left: 50%;
  background-color: $light;
  transform: translate(-50%, -50%);
}
.square:nth-child(2n+1) {
  background-color: $dark;
}
@for $i from 1 through $n {
  $c: $n + 1 - $i;
  .square:nth-child(#{$c}) {
    width: $size * $i;
    height: $size * $i;
    animation: rot#{$i} infinite ease #{1.5 * $n / $c}s;
  }
  @keyframes rot#{$i} {
    0%, #{50 - 150 / ($i+3)}%, 100% {
      transform: translate(-50%, -50%) rotate(30deg);
    }
    50%, #{100 - 150 / ($i+3)}% {
      transform: translate(-50%, -50%) rotate(-15deg);
    }
  }
}

36 строк SCSS-кода

412 строк CSS (+префиксы)

Codepen Picked Pens

Не только CSS

Fly

Line Lisa (by dark_mefody)
< offline >

youtube.com/user/flintyara/

Стримы Юры Артюха

Подытожим

Fly

Чем полезны демо?

Предостережения ⚠️

Материалы

Видео

Спасибо за внимание!

mefody.github.io/talks/css-magic/wsd.html
@dark_mefody
n.a.dubko@gmail.com

QR code — ссылка на презентацию