Mark Shuf­fle­bot­tom

CSS can still hold its own when it comes to ad­vanced an­i­mated ef­fects and this tu­to­rial demon­strates its power

Web Designer - - Contributors -

Mark is a pro­fes­sor of In­ter­ac­tion De­sign. In this is­sue Mark is ex­plor­ing cre­at­ing glitch an­i­ma­tion ef­fects. Both text and image will be given the dis­tressed glitch an­i­ma­tion to pro­duce an in­ter­est­ing visual aes­thetic with CSS.

The range of spe­cial ef­fects and an­i­ma­tions that are found on web­sites of­ten make them stand out and force an im­me­di­ate im­pact be­fore the user has had a chance to get into read­ing the main parts of the site. If you need a lot of wow on your home­page, CSS has tons of ef­fects to of­fer that don’t need the Javascript cod­ing of other more in­tense so­lu­tions on the can­vas or WEBGL. In this tu­to­rial, CSS is go­ing to show that quite ad­vanced ef­fects such as glitchy im­ages and ti­tles are all pos­si­ble with a lit­tle ef­fort go­ing into cre­at­ing keyframes to con­trol some of the ac­tion. This is ac­tu­ally pretty sim­i­lar to work­ing with an­i­ma­tion soft­ware when keyframes are placed into spe­cific points. The dif­fer­ence with the keyframes in CSS is that they are writ­ten as per­cent­ages for the time­line of an­i­ma­tion in the code. This isn’t any­where near as daunt­ing as it sounds, once you try it, it be­comes rel­a­tively straight­for­ward to achieve good re­sults us­ing this. There will be a small amount of Javascript used in the tu­to­rial, just to re­move the load­ing screen once the im­ages load onto the page. The rest of the page will be built up us­ing reg­u­lar HTML and CSS, with the CSS Grid be­ing used to po­si­tion el­e­ments on the screen.

1. Start­ing the process

To get started, open the ‘start’ folder from the project files in­side your code ed­i­tor. Open the ‘in­dex.html’ page, which con­tains just a bare­bones skele­ton HTML page. In the head sec­tion, the fonts need link­ing up so that the de­sign dis­plays cor­rectly. Add the style link for the fonts. <link href="https://fonts.googleapis.com/css?f am­ily=im+fell+english|play­fair+dis­play:900" rel="stylesheet">

2. Link­ing the CSS

The ba­sic lay­out in CSS has been started in the ‘site.css’ file, but all of the im­por­tant parts re­lat­ing to the glitch ef­fect are go­ing to be added later. In the head sec­tion of the doc­u­ment link up the CSS so that the ba­sic de­sign of the page is in place.

<link rel="stylesheet" type="text/css" href="css/site.css" />

3. Load­ing screen

Now move to the body sec­tion of the page. This con­tains all the vis­i­ble el­e­ments of the page that show up in the browser. Here add in a div that will hold the ‘preloader screen’ un­til ev­ery­thing on the page has loaded. This will dis­play a logo in the cen­tre of the page. <div id="loader" class="load­ing">

<div class="load­ing-logo"><img src="img/logo.svg" class="logo"></div>

</div>

4. Header bar

Along the top of the screen will be a small header con­tain­ing an SVG logo for the site on the left with a text head­ing. Then on the right-hand side of the screen, an in­line menu will be in place for easy nav­i­ga­tion. The struc­ture of the code here adds those el­e­ments onto the page. <div class="con­tent­fixed">

<header class="header">

<h1 class="head­er­ti­tle"><img src="img/logo.svg" class="logo"> Hack­er­con</ h1> </header>

<nav class="menu" id="site­nav"> <ul>

<li><a href="in­dex. html">home</a></li>

<li><a href="news. html">news</a></li>

<li><a href="con­tact. html">con­tact</a></li>

<li><a href="about. html">about</a></li>

</ul>

</nav>

</div>

5. Adding the im­ages

Now the sec­tion that fol­lows con­tains sev­eral ver­sions of the same image in the ‘glitchit’ class. What this will do is have dif­fer­ent parts of th­ese im­ages turned on and off at dif­fer­ent times in order to give a glitch ef­fect. Fol­low­ing this is the text that will sit over the top of the im­ages.

<div class="con­tent">

<div class="glitch">

<div class="glitchit"></div> <div class="glitchit"></div> <div class="glitchit"></div> <div class="glitchit"></div> <div class="glitchit"></div> </div>

<div class="con­tentsec­tion">

<h2 class="con­tent­ti­tle">hacker<span> Con</span></h2>

<p class="con­tent­text">add a de­scrip­tion</p>

</div>

</div>

6. Start­ing it off

At the end of the body con­tent the Javascript tags are placed. All this does is check that the page has loaded and then re­moves the load­ing screen, which in turn trig­gers the glitch ef­fect an­i­ma­tion to start by adding a class to the body to af­fect the rel­e­vant glitch sec­tions. <script>

var loader = doc­u­ment. getele­ment­byid('loader');

win­dow.ad­de­ventlis­tener("load", func­tion(event) {

loader.classlist. re­move('load­ing'); loader.classlist.add('loaded'); doc­u­ment.body.classlist. add('im­gloaded');

});

</script>

7. Set­ting up CSS Vari­ables

Save the page now and move over to the ‘site.css’ file in

the CSS folder. There is al­ready code here, but right above any other code add in the vari­ables shown below. Th­ese CSS Vari­ables will hold colours and sizes that will be used later on in the de­sign.. body {

--color-text: #fff;

--color-bg: #000;

--color-link: #555;

--color-link-hover: #98fadf; --color-info: #f7cfb9;

--glitch-width: 100vw;

--glitch-height: 100vh;

--gap-hor­i­zon­tal: 10px;

--gap-ver­ti­cal: 5px;

--time-anim: 4s;

--de­lay-anim: 2s;

8. Re­main­ing Vari­ables

As you will see th­ese Vari­ables are as­signed to the body tag so they can be used by any tag on the page in­side the body, which is es­sen­tially all the vis­i­ble page. Here the trans­parency and blend­ing modes are set up for the dif­fer­ent im­ages. There are five im­ages and you can ex­per­i­ment with th­ese set­tings to get dif­fer­ent re­sults. --blend-mode-1: none;

--blend-mode-2: over­lay;

--blend-mode-3: none;

--blend-mode-4: none;

--blend-mode-5: over­lay;

--blend-color-1: trans­par­ent; --blend-color-2: #7d948e;

--blend-color-3: trans­par­ent; --blend-color-4: trans­par­ent; --blend-color-5: #af4949; }

9. Fill­ing the screen with im­ages

To keep the code neatly to­gether, scroll down to the com­ment that marks steps 9 to 13 in the CSS file, adding in this code. Here the glitch code po­si­tions the div con­tain­ing all im­ages to fill the full screen and be po­si­tioned ab­so­lutely in the top-left of the screen. Note it gets the width and height from the CSS Vari­ables. .glitch

{ po­si­tion: ab­so­lute; top: 0; left: 0; width: var(--glitch-width); height: var(--glitch-height); over­flow: hid­den; }

10. Each glitch image

As the glitch ef­fect is made up out of copies of the same image, this code po­si­tions each div in the page and makes it slightly larger than the screen. It po­si­tions it off the top and left to ac­count for it be­ing big­ger, and the image is then placed in the back­ground to fill the image.

.glitchit { po­si­tion: ab­so­lute; top: calc(-1 * var(--gap-ver­ti­cal)); left: calc(-1 * var(--gap-hor­i­zon­tal)); width: calc(100% + var(--gap-hor­i­zon­tal) * 2);

height: calc(100% + var(--gap-ver­ti­cal) * 2); back­ground: url(../img/main.jpg) no-re­peat

50% 0; back­ground-color: var(--blend-color-1); back­ground-size: cover; trans­form: trans­late3d(0, 0, 0); back­ground-blend-mode: var(--blend­mode-1);

}

11. Ev­ery­thing ex­cept the first image

The code here se­lects ev­ery image ex­cept the first image. This is be­cause the first image stays on the page, while the oth­ers turn on and off over the top with the keyframe an­i­ma­tion. Th­ese top im­ages are hid­den un­til they are needed with the opac­ity set to zero. .glitchit:nth-child(n+2) {

opac­ity: 0; }

.im­gloaded .glitchit:nth-child(n+2) {

an­i­ma­tion-du­ra­tion: var(--time-anim);

an­i­ma­tion-de­lay: var(--de­lay-anim); an­i­ma­tion-tim­ing-func­tion: lin­ear; an­i­ma­tion-it­er­a­tion-count: in­fi­nite; }

12. Se­cond and third image

The se­cond and third image are set to an­i­mate in this code. They are given the re­spec­tive blend and colour modes so that they show up dif­fer­ently. The big­gest dif­fer­ence here is that they are given dif­fer­ent keyframe an­i­ma­tions to fol­low to mix up the ef­fects.

.im­gloaded .glitchit:nth-child(2) { back­ground-color: var(--blend-color-2); back­ground-blend-mode: var(--blend­mode-2);

an­i­ma­tion-name: glitch-1; }

.im­gloaded .glitchit:nth-child(3) { back­ground-color: var(--blend-color-3); back­ground-blend-mode: var(--blend­mode-3);

an­i­ma­tion-name: glitch-2; }

13. Fourth and fifth image

This time the next two im­ages are set up quite close to the oth­ers, but again this time there is dif­fer­ent blend­ing modes and an­i­ma­tions for th­ese im­ages to show up. The keyframes have not yet been cre­ated for some of th­ese an­i­ma­tions and that will come next.

.im­gloaded .glitchit:nth-child(4) { back­ground-color: var(--blend-color-4); back­ground-blend-mode: var(--blend­mode-4);

an­i­ma­tion-name: glitch-3; } .im­gloaded .glitchit:nth-child(5) { back­ground-color: var(--blend-color-5); back­ground-blend-mode: var(--blend­mode-5);

an­i­ma­tion-name: glitch-flash; }

14. The first set of keyframes

The keyframes work by grab­bing dif­fer­ent sec­tions of the image and clip­ping it down so only that will be vis­i­ble. The opac­ity is turned on and off at dif­fer­ent times so that parts of the image are vis­i­ble at dif­fer­ent times to the other an­i­ma­tions and thus cre­ates the glitch ef­fect. The image is moved slightly on the x-axis. @keyframes glitch-1 {

0% { opac­ity: 1; trans­form: trans­late3d(var(--gaphor­i­zon­tal), 0, 0);

clip-path: poly­gon(0 2%, 100% 2%, 100% 5%, 0 5%);

} 2% {

clip-path: poly­gon(0 15%, 100% 15%, 100% 15%, 0 15%);

}

15. Us­ing the clip-path

The clip path is tak­ing a rec­tan­gle so the first two num­bers are top-left, then top-right. This is fol­lowed by bot­tom-right and bot­tom-left. By mov­ing th­ese num­bers dif­fer­ent parts of the image be­come vis­i­ble at dif­fer­ent points.

4% { clip-path: poly­gon(0 10%, 100% 10%, 100% 20%, 0 20%); } 6% {

With all el­e­ments of the CSS com­pleted, the glitch ef­fect runs ev­ery few sec­onds to give a dis­tressed look to the image

clip-path: poly­gon(0 1%, 100% 1%, 100% 2%, 0 2%);

} 8% {

clip-path: poly­gon(0 33%, 100% 33%, 1 00% 33%, 0 33%); } 10% {

clip-path: poly­gon(0 44%, 100% 44%, 100% 44%, 0 44%);

}

16. Fast move­ment

By mov­ing the clip path so quickly over a num­ber of the keyframes, the ef­fect builds up and dif­fer­ent parts of the image ap­pear to flash around in an er­ratic fash­ion. Add that more lay­ers of im­ages are also do­ing this and the ef­fect works very well at what it does.

12% {

clip-path: poly­gon(0 50%, 100% 50%, 100% 20%, 0 20%); } 14% {

clip-path: poly­gon(0 70%, 100% 70%, 100% 70%, 0 70%); }16% {

clip-path: poly­gon(0 80%, 100% 80%, 100% 80%, 0 80%); }18% {

clip-path: poly­gon(0 50%, 100% 50%, 100% 55%, 0 55%);

}20% {

clip-path: poly­gon(0 70%, 100% 70%,

100% 80%, 0 80%);

}

17. Reach­ing the end

Af­ter 22% the image is turned off un­til the an­i­ma­tion plays back again. This com­pletes the ‘glitch-1’ ef­fect with ‘glitch-2’ and ‘glitch-3’ al­ready be­ing sup­plied in the code. The next sec­tion will glitch the text that is over the top of the image as well.

21.9% { opac­ity: 1; trans­form: trans­late3d(var(--gaphor­i­zon­tal), 0, 0);

} 22%, 100% { opac­ity: 0; trans­form: trans­late3d(0, 0, 0); clip-path: poly­gon(0 0, 0 0, 0 0, 0 0);

} }

18. Text glitch

This code works ex­tremely sim­i­larly to the pre­vi­ous code ex­cept that it flips the text up­side down and then clips it, to give a jump­ing ef­fect that is moved dra­mat­i­cally. Fol­low­ing that the clip path is re­veal­ing only smaller sec­tions, with the fast move­ment through the keyframes.

@keyframes glitch-text {

0% {

trans­form: trans­late3d(calc(-1 * var(--gap-hor­i­zon­tal)), 0, 0) scale3d(-1, -1,

1);

clip-path: poly­gon(0 20%, 100% 20%, 100% 21%, 0 21%); } 2% {

clip-path: poly­gon(0 33%, 100% 33%, 100% 33%, 0 33%); } 4% {

clip-path: poly­gon(0 44%, 100% 44%, 100% 44%, 0 44%); }

19. Clip­ping crazy

The ef­fect con­tin­ues in this sec­tion of code by rapidly chang­ing the shape of the clip­ping path. The clip-path also comes with the ‘-we­bkit-‘ pre­fix but for brevity this has not been shown in any of the code here. Clip path is cur­rently not sup­ported in IE, Edge or Opera Mini, but is in all other browsers, giv­ing it 88% global sup­port.

5% {

clip-path: poly­gon(0 50%, 100% 50%, 100% 20%, 0 20%); } 6% {

clip-path: poly­gon(0 70%, 100% 70%, 100% 70%, 0 70%); } 7% {

clip-path: poly­gon(0 80%, 100% 80%, 100% 80%, 0 80%); } 8% {

clip-path: poly­gon(0 50%, 100% 50%, 100% 55%, 0 55%);

}

20. Flip­ping back

In the fi­nal text an­i­ma­tion the text flips back to its orig­i­nal po­si­tion and waits for the keyframes to come around again. As you can see all of the an­i­ma­tion takes place in 10% while it stays dor­mant for 90% of the time, giv­ing the text the right amount of dis­tress and al­low­ing it to be read­able.

9% {

clip-path: poly­gon(0 70%, 100% 70%,

100% 80%, 0 80%);

} 9.9% {

trans­form: trans­late3d(calc(-1 * var(--gap-hor­i­zon­tal)), 0, 0) scale3d(-1, -1, 1); } 10%, 100% { trans­form: trans­late3d(0, 0, 0) scale3d(1, 1, 1); clip-path: poly­gon(0 0, 100% 0, 100% 100%, 0% 100%); } }

21. Quick flash

The fi­nal step is that one image is given the glitch-flash an­i­ma­tion, and this se­ries of keyframes just place the image on the screen with a 20% opac­ity for a short pe­riod just to give an off­set of the orig­i­nal. Save the CSS file now and the ef­fect should start play­ing once the con­tent loads in the browser.

@keyframes glitch-flash {

0%, 5% { opac­ity: 0.2; trans­form: trans­late3d(var(--gaphor­i­zon­tal), var(--gap-ver­ti­cal), 0);

} 5.5%, 100% { opac­ity: 0; trans­form: trans­late3d(0, 0, 0); } }

5

6

9

With the back­ground image added, the de­sign is fully fin­ished and the glitch ef­fects can run on this con­tent 10

16

The text glitch ef­fect can be seen run­ning here, and the text is be­ing clipped so only part of it is vis­i­ble. This only hap­pens for a brief spell al­low­ing the text to be read­able on the screen 18

21

Newspapers in English

Newspapers from UK

© PressReader. All rights reserved.