<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Joan León</title>
    <description>The latest articles on DEV Community by Joan León (@nucliweb).</description>
    <link>https://dev.to/nucliweb</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F92359%2F01aa6eab-e612-4d49-a7a1-6595a7dc7e4b.JPG</url>
      <title>DEV Community: Joan León</title>
      <link>https://dev.to/nucliweb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nucliweb"/>
    <language>en</language>
    <item>
      <title>CSS Community Dev Logo, CSS Houdini version</title>
      <dc:creator>Joan León</dc:creator>
      <pubDate>Sun, 06 Dec 2020 19:08:53 +0000</pubDate>
      <link>https://dev.to/nucliweb/css-community-dev-logo-css-houdini-version-3g40</link>
      <guid>https://dev.to/nucliweb/css-community-dev-logo-css-houdini-version-3g40</guid>
      <description>&lt;p&gt;&lt;a href="https://twitter.com/medellincss"&gt;&lt;strong&gt;Medellín CSS&lt;/strong&gt;&lt;/a&gt; community launched a &lt;a href="https://twitter.com/medellincss/status/1332729019830333441"&gt;challenge&lt;/a&gt; to make the &lt;a href="https://twitter.com/csscommunitydev"&gt;&lt;strong&gt;CSS Community Dev&lt;/strong&gt;&lt;/a&gt; logo with CSS code.&lt;/p&gt;

&lt;p&gt;And here my &lt;strong&gt;CSS Houdini&lt;/strong&gt; version.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/nucliweb/embed/QWKjZeY?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Source Code
&lt;/h2&gt;

&lt;p&gt;Take a look to the &lt;a href="https://github.com/nucliweb/csscommunitydev-logo"&gt;source code&lt;/a&gt;, this is the Paint Worlet code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;registerPaint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;csscommunitydev&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;paint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;geometry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;geometry&lt;/span&gt;

      &lt;span class="c1"&gt;// Background&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;beginPath&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#6F0E96&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

      &lt;span class="c1"&gt;// Shadow&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;grShadow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createRadialGradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;3.2&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;grShadow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addColorStop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rgba(0,0,0,0.6)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;grShadow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addColorStop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rgba(111, 14, 150, 1)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;beginPath&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;2.4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;grShadow&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

      &lt;span class="c1"&gt;// Semi circle&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;grSemicircle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createLinearGradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.133&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.47&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.47&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.864&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;grSemicircle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addColorStop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#975DF5&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;grSemicircle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addColorStop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#6F0E96&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;beginPath&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.47&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.37&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PI&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;grSemicircle&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shadowColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rgba(0,0,0,0.3)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shadowBlur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.06&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shadowOffsetX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.1&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shadowOffsetY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

      &lt;span class="c1"&gt;// First triangle&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;grFirstTriangle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createLinearGradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.56&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.327&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.786&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.456&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;grFirstTriangle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addColorStop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#43DCC9&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;grFirstTriangle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addColorStop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#05F2C7&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;beginPath&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;moveTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.56&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.327&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lineTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.786&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.197&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lineTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.786&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.456&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;grFirstTriangle&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shadowColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rgba(0,0,0,0.5)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shadowBlur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.06&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shadowOffsetX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.02&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shadowOffsetY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.08&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

      &lt;span class="c1"&gt;// Second triangle&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;grSecondTriangle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createLinearGradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.56&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.412&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.56&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.802&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;grSecondTriangle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addColorStop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#FFD900&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;grSecondTriangle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addColorStop&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#FF6A19&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;beginPath&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;moveTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.56&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.412&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lineTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.606&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lineTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.56&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.802&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fillStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;grSecondTriangle&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shadowColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rgba(0,0,0,0.5)&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shadowBlur&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.08&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shadowOffsetX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;w&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.04&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;shadowOffsetY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.08&lt;/span&gt;
      &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>codepen</category>
      <category>css</category>
      <category>houdini</category>
      <category>csshoudini</category>
    </item>
    <item>
      <title>CSS Houdini: Lines Worklet</title>
      <dc:creator>Joan León</dc:creator>
      <pubDate>Sun, 06 Dec 2020 18:30:31 +0000</pubDate>
      <link>https://dev.to/nucliweb/css-houdini-lines-worklet-4kda</link>
      <guid>https://dev.to/nucliweb/css-houdini-lines-worklet-4kda</guid>
      <description>&lt;p&gt;A CSS Houdini Worklet to show parallel lines and you can control the colors, widths, gaps and rotation via custom properties.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/nucliweb/embed/abmzjjK?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  An implementation sample
&lt;/h3&gt;

&lt;p&gt;In combination with &lt;code&gt;background-clip&lt;/code&gt; and &lt;code&gt;-webkit-text-fill-color&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/nucliweb/embed/vYXEaVq?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>codepen</category>
      <category>css</category>
      <category>houdini</category>
      <category>csshoudini</category>
    </item>
    <item>
      <title>Detect AVIF image support to use in your CSS</title>
      <dc:creator>Joan León</dc:creator>
      <pubDate>Sun, 06 Dec 2020 18:16:52 +0000</pubDate>
      <link>https://dev.to/nucliweb/detect-avif-image-support-to-use-in-your-css-4pen</link>
      <guid>https://dev.to/nucliweb/detect-avif-image-support-to-use-in-your-css-4pen</guid>
      <description>&lt;p&gt;AVIF is a next generation image format, in the moment to write this post, the support is only by Chrome 85 and Firefox 77 under a flag.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;W3C&lt;/strong&gt; are working in the &lt;a href="https://drafts.csswg.org/css-images-4"&gt;CSS Images Module Level 4&lt;/a&gt;, and the new module will have an interesting feature, &lt;code&gt;image-set&lt;/code&gt; and we'll can define the image type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.element&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;image-set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="s1"&gt;"image.avif"&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;"image/avif"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                               &lt;span class="s1"&gt;"image.webp"&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;"image/webp"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                               &lt;span class="s1"&gt;"image.jpg"&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;"image/jpeg"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With &lt;code&gt;image-set&lt;/code&gt; we'll can define different format and the browser render the first image format supported.&lt;/p&gt;

&lt;p&gt;Until we have this awesome feature in the browsers, we can use JavaScript to detect the support, we'll to do a sample with the AVIF format.&lt;/p&gt;

&lt;h2&gt;
  
  
  The CSS
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-repeat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;no-repeat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cover&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="nc"&gt;.avif&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url(./images/lions.avif)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="nc"&gt;.no-avif&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url(./images/lions.jpg)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;I know that you can put the image in JPEG format directly in the body and overwrite the background-image if the browser supports it, but for the example I think it's clearer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The JavaScript
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;supportsAvif&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createImageBitmap&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;avifData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data:image/avif;base64,AAAAFGZ0eXBhdmlmAAAAAG1pZjEAAACgbWV0YQAAAAAAAAAOcGl0bQAAAAAAAQAAAB5pbG9jAAAAAEQAAAEAAQAAAAEAAAC8AAAAGwAAACNpaW5mAAAAAAABAAAAFWluZmUCAAAAAAEAAGF2MDEAAAAARWlwcnAAAAAoaXBjbwAAABRpc3BlAAAAAAAAAAQAAAAEAAAADGF2MUOBAAAAAAAAFWlwbWEAAAAAAAAAAQABAgECAAAAI21kYXQSAAoIP8R8hAQ0BUAyDWeeUy0JG+QAACANEkA=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;blob&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;avifData&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;createImageBitmap&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blob&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;classAvif&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supportsAvif&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;avif&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no-avif&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;classList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;classAvif&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;iframe src="https://codesandbox.io/embed/condescending-colden-o1gse?module=/js/index.js&amp;amp;view=split"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks
&lt;/h2&gt;

&lt;p&gt;I want to thank &lt;a href="https://twitter.com/jonsneyers"&gt;Jon Sneyers&lt;/a&gt; and &lt;a href="https://twitter.com/kornelski"&gt;Kornel&lt;/a&gt;, true magicians of image coders/decoders, for their help with the option of a &lt;code&gt;base64&lt;/code&gt; of an image of &lt;strong&gt;AVIF&lt;/strong&gt; format as optimized as possible.&lt;/p&gt;

</description>
      <category>css</category>
      <category>avif</category>
      <category>images</category>
      <category>imageperf</category>
    </item>
    <item>
      <title>CSS Houdini: Connections Worklet</title>
      <dc:creator>Joan León</dc:creator>
      <pubDate>Mon, 23 Nov 2020 09:26:08 +0000</pubDate>
      <link>https://dev.to/nucliweb/css-houdini-connections-worklet-2k51</link>
      <guid>https://dev.to/nucliweb/css-houdini-connections-worklet-2k51</guid>
      <description>&lt;p&gt;A CSS Paint Worklet to load connected dots&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/nucliweb/embed/yLJdroy?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>codepen</category>
      <category>css</category>
      <category>houdini</category>
      <category>worklet</category>
    </item>
    <item>
      <title>CSS Dynamic Shadow</title>
      <dc:creator>Joan León</dc:creator>
      <pubDate>Tue, 29 Sep 2020 18:22:53 +0000</pubDate>
      <link>https://dev.to/nucliweb/css-dynamic-shadow-569o</link>
      <guid>https://dev.to/nucliweb/css-dynamic-shadow-569o</guid>
      <description>&lt;p&gt;Creates a shadow similar to box-shadow but based on the background inherit.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/nucliweb/embed/qBZGqyY?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>codepen</category>
      <category>css</category>
      <category>shadow</category>
    </item>
    <item>
      <title>Coding Potions</title>
      <dc:creator>Joan León</dc:creator>
      <pubDate>Thu, 17 Sep 2020 18:09:40 +0000</pubDate>
      <link>https://dev.to/nucliweb/coding-potions-2c43</link>
      <guid>https://dev.to/nucliweb/coding-potions-2c43</guid>
      <description>&lt;p&gt;Coding Potions avatar CSS Pixel Art&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/nucliweb/embed/WNrqKYV?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  You can follow me on...
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Twitter:&lt;/strong&gt; &lt;a href="https://twitter.com/nucliweb"&gt;@nucliweb&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;YouTube:&lt;/strong&gt; &lt;a href="https://www.youtube.com/c/JoanLeon"&gt;JoanLeon&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instagram:&lt;/strong&gt; &lt;a href="https://www.instagram.com/nucliweb/"&gt;@nucliweb&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/nucliweb"&gt;@nucliweb&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>codepen</category>
      <category>css</category>
      <category>pixelart</category>
    </item>
    <item>
      <title>CSS Pixel Art</title>
      <dc:creator>Joan León</dc:creator>
      <pubDate>Thu, 17 Sep 2020 17:50:21 +0000</pubDate>
      <link>https://dev.to/nucliweb/css-pixel-art-la6</link>
      <guid>https://dev.to/nucliweb/css-pixel-art-la6</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;El pixel art o arte de píxel es una forma de arte digital, creada a través de una computadora mediante el uso de programas de edición de gráficos rasterizados, donde las imágenes son editadas al nivel del píxel. - &lt;a href="https://es.wikipedia.org/wiki/Pixel_art"&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Siempre me ha gustado el &lt;strong&gt;pixel art&lt;/strong&gt;, me fascina que con tan poca información podamos reconocer objetos y personajes. Mucha gente cree que al ser con "cuadraditos" (aka pixels) es una técnica de dibujo muy fácil, nada más lejos de la realidad, creo que la dificultad es proporcional a la apariencia de sencillez.&lt;/p&gt;

&lt;h2&gt;
  
  
  Motivación
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QCWOdW9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/f6064d56373cda188e20b6b079865311/30744/pixelart.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QCWOdW9c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/f6064d56373cda188e20b6b079865311/30744/pixelart.png" alt="Pixel Art"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hace un tiempo quise jugar con el pixel art, creo que la mejor manera de empezar algo nuevo es &lt;del&gt;copiar&lt;/del&gt; inspirarse en referencias que no sean muy complejas. Al mismo tiempo lo quería hacer con CSS, siempre quiero mostrar que, aun no siendo un lenguaje de programación &lt;em&gt;(como siempre nos recuerda nuestro amigo &lt;a href="https://twitter.com/carlosvillu"&gt;Carlos Villuendas&lt;/a&gt;)&lt;/em&gt;, se pueden hacer auténticas maravillas con él... ya dedicaré un post a hablar de &lt;a href="https://css-doodle.com/"&gt;&amp;lt; css-doodle /&amp;gt;&lt;/a&gt; 😊&lt;/p&gt;

&lt;h2&gt;
  
  
  A la sombra de CSS
&lt;/h2&gt;

&lt;p&gt;Una de la propiedades CSS que tenemos disponible desde hace mucho tiempo es &lt;code&gt;box-shadow&lt;/code&gt;, muy utilizada para resaltar elementos y dar sensación de profundidad o relieve.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WZFs0gZY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/9282f470e0a1c081b1ebd1e4c1751bb6/30744/developer.mozilla.org_en-US_docs_Web_CSS_box-shadow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WZFs0gZY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/9282f470e0a1c081b1ebd1e4c1751bb6/30744/developer.mozilla.org_en-US_docs_Web_CSS_box-shadow.png" alt="Ejemplo de box-shadow en MDN"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La sintaxis de &lt;strong&gt;box-shadow&lt;/strong&gt; tiene varias opciones, os invito a echar un vistazo a la documentación en &lt;a href="https://developer.mozilla.org/es/docs/Web/CSS/box-shadow"&gt;MDN&lt;/a&gt;. Si tenéis alguna duda, recordad que tengo un repositorio &lt;a href="https://github.com/nucliweb/ama"&gt;AMA&lt;/a&gt; &lt;em&gt;(Ask Me Anything)&lt;/em&gt; donde podéis hacerme llegar vuestras consultas.&lt;/p&gt;

&lt;p&gt;Vamos a centrarnos en las sintaxis que nos permitirá crear arte pixelado.&lt;/p&gt;

&lt;p&gt;Si nos fijamos en la definición de la propiedad, nos dice:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;La propiedad CSS box-shadow  añade efectos de sombra alrededor del marco de un elemento. Se pueden definir múltiples efectos separados por comas. La caja de la sombra se describe por los desplazamientos en X e Y, los radios de desenfoque y dispersión, y el color relativos al elemento.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;La parte que más nos interesa es la de &lt;strong&gt;Se pueden definir múltiples efectos separados por comas&lt;/strong&gt;. Esto nos va a permitir definir cada uno de los píxeles de nuestro personaje.&lt;/p&gt;

&lt;p&gt;En nuestro archivo HTML solo necesitamos un elemento HTML con una clase para aplicarle la magia del CSS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"es"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;http-equiv=&lt;/span&gt;&lt;span class="s"&gt;"X-UA-Compatible"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"ie=edge"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;CSS Pixel Art&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"styles.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"pixel-art"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Ahora vamos a añadir el CSS necesario para pintar algunos píxeles.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.pixel-art&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
              &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="no"&gt;green&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
              &lt;span class="m"&gt;3px&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h5&gt;
  
  
  Analicemos línea a línea este código
&lt;/h5&gt;

&lt;ol&gt;
&lt;li&gt;Como vamos a trabajar a nivel de píxel, lo primero que hacemos es definir un tamaño de 1px x 1px nuestro elemento HTML.&lt;/li&gt;
&lt;li&gt;Con la propiedad margin, simplemente lo estamos posicionando a 50px de la coordenada 0,0 del body.&lt;/li&gt;
&lt;li&gt;Esta propiedad es importante, al pintar a un tamaño de píxeles, escalamos el elemento para poder mostrarlo a un tamaño más adecuado, en este caso estamos escalando el elemento 20 veces.&lt;/li&gt;
&lt;li&gt;Por último, definimos la propiedad que nos aporta la magia para conseguir crear nuestra obra en pixel art.&lt;/li&gt;
&lt;/ol&gt;

&lt;h5&gt;
  
  
  Vamos a verlo en funcionamiento
&lt;/h5&gt;



&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/claireparker/embed/rNapgdM?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;p&gt;Lo que podemos ver son tres (tristes) píxeles, uno al lado del otro 😅. Pero con solo este simple ejemplo seguro que ya ves la "simplicidad" de lo que tenemos que hacer para dibujar nuestros dibujos con píxeles.&lt;/p&gt;

&lt;h5&gt;
  
  
  Crearemos otro ejemplo más ilustrativo.
&lt;/h5&gt;



&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/claireparker/embed/BayJePE?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;p&gt;En este otro ejemplo podéis ver que el tamaño del elemento es de &lt;code&gt;4px&lt;/code&gt; y el multiplicador de escala de 5 con &lt;code&gt;scale(5)&lt;/code&gt;, más tarde veremos el motivo 😊. Lo interesante es que con unos cuantos valores de sombra en nuestro CSS hemos conseguido una versión &lt;strong&gt;Pixel Art&lt;/strong&gt; del logo del blog.&lt;/p&gt;

&lt;h2&gt;
  
  
  A nivel de pixel
&lt;/h2&gt;

&lt;p&gt;Si analizamos de cerca (a nivel de pixel) cualquier obra de pixel art, podremos ver que se trata de una matriz de píxeles, donde cada uno de esos píxeles tiene la información del color con el que es representado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IuW5tvkS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/b870fed83156c06aff7d60c42f8e63e4/30744/lemming-pixels.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IuW5tvkS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/b870fed83156c06aff7d60c42f8e63e4/30744/lemming-pixels.png" alt="Lemming a nivel de pixel"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La imagen anterior se vería de la siguiente manera en una matriz donde estemos definiendo el color hexadecimal de cada uno de los píxeles. Obviamos los píxeles de "padding" que hemos dejado para mejorar la lectura de la imagen, así que tendremos una matriz de 10 x 10.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#00b0b0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#00b0b0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#00b0b0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#00b0b0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#00b0b0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#00b0b0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#00b0b0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#f0d0d0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#f0d0d0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#00b0b0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nn"&gt;#f0d0d0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#f0d0d0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#f0d0d0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#f0d0d0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nn"&gt;#f0d0d0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#f0d0d0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#f0d0d0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#f0d0d0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#4040e0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#4040e0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#f0d0d0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#f0d0d0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#f0d0d0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#f0d0d0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#4040e0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#4040e0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#4040e0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#4040e0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#4040e0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#4040e0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#4040e0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#4040e0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#4040e0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#4040e0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#f0d0d0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#f0d0d0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#f0d0d0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#f0d0d0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nn"&gt;#000000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Como si se tratase de punto de cruz, simplemente definimos un color por cada uno de los puntos que queremos pintar.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSS vitaminado
&lt;/h2&gt;

&lt;p&gt;Como estaréis imaginando, conseguir dibujos más complejos nos puede llevar mucho trabajo, y así es. Es por eso que nos vamos a apoyar en &lt;a href="https://sass-lang.com/"&gt;Sass&lt;/a&gt; para facilitar la generación de nuestras creaciones en pixel art.&lt;/p&gt;



&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/claireparker/embed/mdyxroR?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;h5&gt;
  
  
  Analicemos paso a paso lo que estamos haciendo
&lt;/h5&gt;

&lt;p&gt;Definimos en variables los diferentes colores que necesitamos para crear nuestro dibujo. También definimos una variable con la dimensión de la cuadrícula.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nv"&gt;$hair&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#00b0b0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$skin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#f0d0d0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$clothes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#4040e0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nv"&gt;$grid&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Después, utilizamos un &lt;a href="https://sass-lang.com/documentation/values/maps"&gt;Maps&lt;/a&gt; de Sass para poder utilizar las claves de índice del mapa, eso nos facilitará crear la matriz.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nv"&gt;$colors&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$hair&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$skin&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$clothes&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;El siguiente paso es definir la matriz con los colores de nuestro dibujo. Lo haremos con cada una de las claves del Maps que acabamos de crear, utilizaremos &lt;code&gt;1&lt;/code&gt; para hacer referencia a la variable &lt;code&gt;$hair&lt;/code&gt;, que a su vez es el valor hexadecimal &lt;code&gt;#00b0b0&lt;/code&gt;, el color del pelo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Lemming Blocker -------------------
$lemming-blocker: 0,0,0,0,1,1,0,0,0,0,
                  0,0,0,1,1,1,1,0,0,0,
                  0,0,0,1,2,2,1,0,0,0,
                  2,0,0,0,2,2,0,0,0,2,
                  2,2,2,2,3,3,2,2,2,2,
                  0,0,0,0,3,3,0,0,0,0,
                  0,0,0,0,3,3,0,0,0,0,
                  0,0,0,3,3,3,3,0,0,0,
                  0,0,0,3,0,0,3,0,0,0,
                  0,0,2,2,0,0,2,2,0,0;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Es difícil de apreciar, pero ahora mismo tenemos una matriz de 10 x 10 igual que la que hemos visto un poco más arriba, con la cuadrícula roja para ver los píxeles, con un valor numérico para cada uno de los colores. Para Sass esto es una lista, así podremos iterar sobre ella. Técnicamente es una sola línea, aquí la vemos en modo cuadrícula para facilitar la edición.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Habrás visto que para el color negro hemos utilizado el valor &lt;code&gt;0&lt;/code&gt;, el cual no tenemos definido en nuestro Maps, ahora veremos cómo lo vamos a utilizar.&lt;/p&gt;

&lt;h5&gt;
  
  
  Empecemos con la programación
&lt;/h5&gt;

&lt;p&gt;Sass nos provee, como definen, un lenguaje de extensión para CSS. Se trata de un preprocesador CSS con una sintaxis que nos ofrece funciones, listas, maps o bucles entre otros.&lt;/p&gt;

&lt;p&gt;El siguiente código contiene la "magia" necesaria para pintar todos los píxeles necesarios para dibujar el lemming.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@function&lt;/span&gt; &lt;span class="nf"&gt;pixeart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$lemming-list&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$shadow-count&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$grid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;$shadows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nv"&gt;$col&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;@for&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="ow"&gt;from&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="ow"&gt;through&lt;/span&gt; &lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$lemming-list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;@if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nf"&gt;nth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$lemming-list&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;$shadows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$shadows&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$col&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$row&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="nf"&gt;map-get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$colors&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nf"&gt;nth&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$lemming-list&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'comma'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;@if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nv"&gt;$grid&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nv"&gt;$col&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nv"&gt;$col&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$col&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;@return&lt;/span&gt; &lt;span class="nv"&gt;$shadows&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;h5&gt;
  
  
  Analicemos este código en Sass
&lt;/h5&gt;

&lt;p&gt;La función &lt;code&gt;pixelart&lt;/code&gt; acepta dos parámetros, el primero es una lista y el segundo la dimensión de la retícula, donde definimos un valor por defecto en el caso de no recibir ninguno.&lt;/p&gt;

&lt;p&gt;Al inicio del cuerpo de la función definimos una lista vacía con &lt;code&gt;$shadow&lt;/code&gt;, así como el valor inicial para las filas y columnas en &lt;code&gt;$row&lt;/code&gt; y &lt;code&gt;$col&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;En el siguiente bloque tenemos un &lt;code&gt;@for&lt;/code&gt; para iterar cada uno de los elementos de la lista (con nuestra matriz) que hemos recibido como argumento &lt;code&gt;$leming-list&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;En el primer &lt;code&gt;@if&lt;/code&gt;, donde comprobamos si seguimos teniendo elementos de la lista, lo que estamos haciendo es añadir un elemento a la lista &lt;code&gt;@shadows&lt;/code&gt; con &lt;em&gt;addend&lt;/em&gt;. A append le estamos pasando 3 parámetros: la lista a la que queremos añadir el elemento, el contenido del elemento y el separador, en este caso &lt;code&gt;'coma'&lt;/code&gt;, una palabra reservada de Sass para representar el carácter &lt;strong&gt;,&lt;/strong&gt;. Entrando en detalle del valor del elemento que estamos añadiendo vemos &lt;code&gt;($col * 1px) ($row * 1px) 0 map-get($colors,nth($lemming-list,$i))&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;($col * 1px)&lt;/strong&gt;, es la posición &lt;strong&gt;X&lt;/strong&gt; respecto al elemento HTML.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;($row * 1px)&lt;/strong&gt;, es la posición &lt;strong&gt;Y&lt;/strong&gt; respecto al elemento HTML.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;0&lt;/strong&gt;, es el valor que indica el degradado de sombra, nos interesa que sea un sombra sólida.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;map-get($colors,nth($lemming-list,$i))&lt;/strong&gt;, con la función &lt;code&gt;map-get&lt;/code&gt; de Sass estamos cogiendo el valor de la matriz de colores según la posición &lt;code&gt;$i&lt;/code&gt; de nuestra iteración.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En el segundo &lt;code&gt;@if&lt;/code&gt;, simplemente comprobamos si ya hemos llegado al máximo de columnas, 10 en este ejemplo, y si es así pasamos el valor de columna a &lt;strong&gt;0&lt;/strong&gt; y sumamos una a las filas &lt;code&gt;$row&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Por último, devolvemos el contenido de &lt;code&gt;$shadows&lt;/code&gt; con &lt;code&gt;@return $shadows&lt;/code&gt;.&lt;/p&gt;

&lt;h5&gt;
  
  
  Llamada desde CSS
&lt;/h5&gt;

&lt;p&gt;Ahora que tenemos disponible nuestra función, la podemos utilizar en CSS con &lt;code&gt;pixelart($lemming-blocker)&lt;/code&gt;, como podemos ver en la línea 7.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.lemming--blocker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;pixelart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$lemming-blocker&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;h2&gt;
  
  
  Dando vida a las sombras
&lt;/h2&gt;

&lt;p&gt;Ahora que ya tenemos nuestro lemming en pixel art, vamos a darle vida gracias a la animación CSS.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Como ya sabréis, una animación es la ilusión de movimiento al ver una secuencia de imágenes a cierta velocidad. Este tipo de imágenes en muchos juegos 2D son sprites, así que busqué &lt;strong&gt;Lemmings sprite animation&lt;/strong&gt; y dí con esta &lt;a href="http://pages.cs.wisc.edu/~zeppenfe/files/lemmings/lemming_anim.png"&gt;imagen&lt;/a&gt;. Eso me permitió poder ver la secuencia de imágenes para hacer la animación.&lt;/p&gt;
&lt;/blockquote&gt;



&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/claireparker/embed/doJXwM?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;p&gt;El lemming de la izquierda tiene solo 2 fotogramas, así que con dos matrices ya tenemos la animación resuelta.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.lemming--blocker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;blocker&lt;/span&gt; &lt;span class="mi"&gt;.65s&lt;/span&gt; &lt;span class="n"&gt;step-start&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;lemming&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$lemming-blocker-1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="nt"&gt;blocker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;50&lt;/span&gt;&lt;span class="nv"&gt;%&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;lemming&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$lemming-blocker-2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;p&gt;Para conseguir el efecto de andar del lemming de la derecha, requiere de  8 fotogramas, por lo que tenemos que definir 8 matrices (echad un vistazo al código de &lt;strong&gt;Codepen&lt;/strong&gt;). &lt;/p&gt;

&lt;p&gt;La asignación de la animación no tiene mucho misterio, la haremos tal y como lo hacemos en cualquier animación CSS con &lt;code&gt;@keyframes&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nc"&gt;.lemming--walker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;walker&lt;/span&gt; &lt;span class="mi"&gt;.65s&lt;/span&gt; &lt;span class="n"&gt;step-start&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;lemming&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$lemming-walker-1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="nt"&gt;walker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;12&lt;/span&gt;&lt;span class="nv"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;lemming&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$lemming-walker-2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;25&lt;/span&gt;&lt;span class="nv"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;lemming&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$lemming-walker-3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;37&lt;/span&gt;&lt;span class="nv"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;lemming&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$lemming-walker-4&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;50&lt;/span&gt;&lt;span class="nv"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;lemming&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$lemming-walker-5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;62&lt;/span&gt;&lt;span class="nv"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;lemming&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$lemming-walker-6&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;75&lt;/span&gt;&lt;span class="nv"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;lemming&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$lemming-walker-7&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;87&lt;/span&gt;&lt;span class="nv"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;lemming&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$lemming-walker-8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;h2&gt;
  
  
  Matrix no es para mí
&lt;/h2&gt;

&lt;p&gt;Llegados a este punto estarás pensando: &lt;em&gt;Tener que hacer una matriz de **n x n&lt;/em&gt;* de cada imagen, y multiplicarlo por el número de fotogramas necesario si quiero hacer una animación, en serio Joan, estás flipando.*&lt;/p&gt;

&lt;p&gt;Este tipo de ejercicios nos sirve para practicar y aprender, pero según lo que quieras hacer está claro que es una forma muy &lt;del&gt;tediosa&lt;/del&gt; artesana de hacerlo. Es por eso que te comparto el siguiente recurso.&lt;/p&gt;

&lt;h5&gt;
  
  
  CSS Sprite Animator
&lt;/h5&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DUsDqUF1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/nucliweb/image/upload/v1578696284/joanleon.dev/assets/css-pixel-art/CSS-Sprite-Animator.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DUsDqUF1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/nucliweb/image/upload/v1578696284/joanleon.dev/assets/css-pixel-art/CSS-Sprite-Animator.gif" alt="CSS Sprite Animator" title="CSS Sprite Animator"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se trata de una aplicación desarrollada por &lt;a href="https://twitter.com/pjkarlik"&gt;Paul Karlik&lt;/a&gt;, podéis encontrarla &lt;a href="http://css-sprite-animator.surge.sh/"&gt;aquí&lt;/a&gt; y el repositorio con el código fuente &lt;a href="https://github.com/pjkarlik/css-sprite-animatior"&gt;aquí&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Tiene una interfaz intuitiva y simple. En el momento que añadimos más de un fotograma, en la parte superior derecha, podemos ver una previsualización de la animación.&lt;/p&gt;

&lt;p&gt;El logo del blog en pixel art que hemos visto antes, está hecho con este editor, que está utilizando múltiples de 4 en la generación de los píxeles. Me he animado y también he creado la animación del lemming cuando está cayendo.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--n0CVjjnr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/nucliweb/image/upload/v1578696742/joanleon.dev/assets/css-pixel-art/lemming-falling.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--n0CVjjnr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/nucliweb/image/upload/v1578696742/joanleon.dev/assets/css-pixel-art/lemming-falling.gif" alt="Lemming Falling" title="Lemming Falling"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;La aplicación también está generando el código CSS necesario para la propiedad &lt;code&gt;box-shadow&lt;/code&gt;. Tiene una función de exportación que genera un array de objetos con los valores necesarios.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  [
    {"x":0,"y":0,"color":"transparent"},
    {"x":1,"y":0,"color":"transparent"},
    ...
  ],
  [ ... ]
]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;h2&gt;
  
  
  Curio&lt;span&gt;css&lt;/span&gt;idades
&lt;/h2&gt;

&lt;p&gt;Las animaciones las hemos definido con un valor de &lt;code&gt;step-start&lt;/code&gt; para la propiedad &lt;a href="https://developer.mozilla.org/es/docs/Web/CSS/animation-timing-function"&gt;animation-timing-function&lt;/a&gt;. Con &lt;strong&gt;step-start&lt;/strong&gt; estamos definiendo que el navegador no genere ninguna interpolación entre un fotograma y el siguiente. El valor por defecto de esta propiedad es &lt;code&gt;ease&lt;/code&gt; que deja al navegador la responsabilidad de calcular una interpolación entre fotogramas, y en este caso no conseguimos el efecto deseado, pero eso sí, la animación queda curiosa 😊.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--m0rmhD6_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/nucliweb/image/upload/v1578697955/joanleon.dev/assets/css-pixel-art/lemmings-ease.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--m0rmhD6_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/nucliweb/image/upload/v1578697955/joanleon.dev/assets/css-pixel-art/lemmings-ease.gif" alt="Lemming ease" title="Lemming ease"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Otros ejemplos
&lt;/h2&gt;

&lt;p&gt;En mi cuenta de &lt;a href="https://codepen.io/nucliweb"&gt;Codepen&lt;/a&gt; encontraréis este y otros ejemplos, algunos de ellos están hechos con &lt;a href="https://p5js.org/"&gt;p5.js&lt;/a&gt; &lt;em&gt;(ya hablaremos de esta librería en algún momento)&lt;/em&gt;, pero la base es la misma, utilizar una matriz para generar el dibujo pixel art.&lt;/p&gt;



&lt;h4&gt;
  
  
  Compartir, feedback y erratas
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Si te ha gustado el artículo, compártelo para llegar a más gente.&lt;/li&gt;
&lt;li&gt;Si tienes feedback que me pueda ayudar a mejorar, siéntete libre de pasarme un &lt;a href="https://twitter.com/nucliweb"&gt;DM&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Si ves alguna errata o hay algo que no planteo bien, también agradezco las correcciones &lt;a href="https://twitter.com/nucliweb"&gt;DM&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;



&lt;h4&gt;
  
  
  Sígueme en...
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Twitter:&lt;/strong&gt; &lt;a href="https://twitter.com/nucliweb"&gt;@nucliweb&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;YouTube:&lt;/strong&gt; &lt;a href="https://www.youtube.com/c/JoanLeon"&gt;JoanLeon&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instagram:&lt;/strong&gt; &lt;a href="https://www.instagram.com/nucliweb/"&gt;@nucliweb&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/nucliweb"&gt;@nucliweb&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>css</category>
      <category>pixelart</category>
      <category>pixel</category>
      <category>animation</category>
    </item>
    <item>
      <title>Animaciones CSS</title>
      <dc:creator>Joan León</dc:creator>
      <pubDate>Thu, 17 Sep 2020 17:30:44 +0000</pubDate>
      <link>https://dev.to/nucliweb/animaciones-css-33h9</link>
      <guid>https://dev.to/nucliweb/animaciones-css-33h9</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Este artículo es parte de una serie de artículos dedicados a la &lt;strong&gt;Animación Web&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/nucliweb/animacion-web-490k"&gt;Animación Web&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/nucliweb/transiciones-css-40po"&gt;Transiciones CSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Animaciones CSS&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Animaciones SVG (Próximamanete)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Animaciones JavaScript  (Próximamanete)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Animaciones Canvas  (Próximamanete)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;



&lt;h4&gt;
  
  
  Animación CSS con @keyframes
&lt;/h4&gt;

&lt;p&gt;En CSS, a parte de poder animar cambios de estados con &lt;a href="https://dev.to/transiciones-css/"&gt;Transiciones CSS&lt;/a&gt;, tenemos disponible la propiedad &lt;code&gt;animate&lt;/code&gt; que junto con la regla arroba (at-rule) &lt;code&gt;@keyframes&lt;/code&gt; nos permite poder definir una animación controlando el tiempo, múltiples estados (keyframes o fotogramas), número de repeticiones, dirección de la animación y la función de tiempo, para conseguir una animación más natural.&lt;/p&gt;

&lt;p&gt;Antes de entrar en detalles, analizando cada una de las propiedades y sus valores, veamos un ejemplo de una animación.&lt;/p&gt;



&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/claireparker/embed/KKpoYVr?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;h3&gt;
  
  
  ¿Qué podemos animar en una web?
&lt;/h3&gt;

&lt;p&gt;La propiedad &lt;code&gt;animation&lt;/code&gt; nos permite animar muchas de las propiedades CSS: color, posición, márgenes, paddings (no puedo llamarle rellenos 😅), opacidad o tamaños. Tanto en la &lt;a href="https://www.w3.org/"&gt;W3C&lt;/a&gt;, como en la &lt;a href="https://developer.mozilla.org/"&gt;MDN&lt;/a&gt; encontraremos una tabla de características de la propiedad. Una de esas características nos informa del &lt;a href="https://drafts.csswg.org/web-animations/#animation-type"&gt;Animation Type&lt;/a&gt;, que nos indica el tipo de animación que soporta esa propiedad &lt;code&gt;not animatable&lt;/code&gt;, &lt;code&gt;discrete&lt;/code&gt;, &lt;code&gt;by computed value&lt;/code&gt; o &lt;code&gt;repeatable list&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;En &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties"&gt;este enlace&lt;/a&gt; de la MDN encontrarás una lista de las propiedades CSS que se pueden animar. O &lt;a href="https://parrot-tutorial.com/cssref/css_animatable.html"&gt;este otro&lt;/a&gt; donde además hay un ejemplo de cada una de ellas.&lt;/p&gt;



&lt;h3&gt;
  
  
  La propiedad animation
&lt;/h3&gt;

&lt;p&gt;Hay varias propiedades para definir y configurar una animación, como en muchas de las propiedades CSS, lo podemos hacer con shorcut o definiendo cada una de ellas.&lt;/p&gt;

&lt;p&gt;Creo que es mejor conocer las propiedades, y qué hacen, que memorizar el orden de los valores... así que vamos a ver todas la propiedades &lt;code&gt;animation-*&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.logo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation-name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;logoAnimation&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-timing-function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ease-in-out&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-iteration-count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-fill-mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;forwards&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;animation-play-state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;initial&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;h4&gt;
  
  
  animation-name
&lt;/h4&gt;

&lt;p&gt;Con esta propiedad definimos el nombre o nombres de la animación o animaciones que queremos aplicar al elemento, este nombre debe coincidir con uno de los &lt;code&gt;@keyframes&lt;/code&gt; que tengamos definidos, pero en un rato lo vemos.&lt;/p&gt;

&lt;h4&gt;
  
  
  animation-duration
&lt;/h4&gt;

&lt;p&gt;Bueno, no es difícil intuir que con esta propiedad podemos definir la duración de la animación o animaciones, lo podemos hacer indicándola en segundos o milisegundos.&lt;/p&gt;

&lt;h4&gt;
  
  
  animation-timing-function
&lt;/h4&gt;

&lt;p&gt;En mi opinión, esta es la propiedad de animación más interesante. No permite indicar una función de tiempo que se aplicará ajustándose a la duración de la animación. Tenemos unas cuantas funciones predefinidas, que harán que nuestras animaciones tengan un aspecto más natural.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Creo que esta propiedad merece un artículo y vídeo dedicado para ver todo su potencial, así que hoy solo veremos los aspectos más básicos.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Acepta valores de "keyword" y de funciones:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Keyword values */&lt;/span&gt;
&lt;span class="nt"&gt;animation-timing-function&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;ease&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;animation-timing-function&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;ease-in&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;animation-timing-function&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;ease-out&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;animation-timing-function&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;ease-in-out&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;animation-timing-function&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;linear&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;animation-timing-function&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;step-start&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;animation-timing-function&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;step-end&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;/* Function values */&lt;/span&gt;
&lt;span class="nt"&gt;animation-timing-function&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;cubic-bezier&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;7&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="err"&gt;1&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;animation-timing-function&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;4&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;end&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;El valor por defecto es &lt;code&gt;ease&lt;/code&gt; y se representa así:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--RjPXH3lN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/c7c6775d9ee39ad531e5f36e6d791580/368d4/ease.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RjPXH3lN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/c7c6775d9ee39ad531e5f36e6d791580/368d4/ease.png" alt="ease timing function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;El eje horizontal representa el tiempo de la animación y el vertical representa los valores que se están cambiando en la animación.&lt;/p&gt;

&lt;p&gt;De esta forma conseguimos una animación más fluida, en lugar de una animación lineal. Pero ojo, que una animación lineal puede tener sentido en algunas ocasiones, pero lo veremos con ejemplos en el capítulo específico de las &lt;strong&gt;&lt;a href="https://www.w3.org/TR/css-easing-1/"&gt;CSS Easing Functions&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;De momento nos quedamos con que esta propiedad nos permite tener control de cómo se va a calcular la línea temporal de la animación.&lt;/p&gt;

&lt;h4&gt;
  
  
  animation-delay
&lt;/h4&gt;

&lt;p&gt;De igual forma que tenemos una propiedad para definir el tiempo de la animación, también podemos definir cuanto tiempo debe pasar hasta que empiece la animación. También podemos definir el tiempo con segundos y milisegundos, eso sí, podemos definir un delay negativo, lo que afecta a la línea de tiempo de la animación.&lt;/p&gt;

&lt;p&gt;Si tenemos una animación de 2 segundos y definimos un &lt;code&gt;animation-delay: -1s&lt;/code&gt; la animación empezará a ejecutarse de forma inmediata y además empezará en el segundo 1.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DqX8gS62--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/8b79bf0a8923c9ff35d0038bbaae99f1/30744/animation-delay.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DqX8gS62--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/8b79bf0a8923c9ff35d0038bbaae99f1/30744/animation-delay.png" alt="animation-delay"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  animation-iteration-count
&lt;/h4&gt;

&lt;p&gt;Con &lt;code&gt;animation-iteration-count&lt;/code&gt; podemos definir el número de veces que se ejecutará la animación, acepta un número de valor positivo o la palabra clave &lt;code&gt;infinite&lt;/code&gt;, como en el ejemplo, esto hace que la animación se ejecute de forma infinita.&lt;/p&gt;

&lt;h4&gt;
  
  
  animation-direction
&lt;/h4&gt;

&lt;p&gt;Esta propiedad nos permite indicar la dirección de la animación, acepta 4 valores, veamos las definiciones para entender mejor en qué nos puede ayudar esta propiedad.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;normal&lt;/code&gt;&lt;br&gt;
Cada vez que termina un ciclo, la animación se reinicia al estado inicial y comienza desde el principio. Este es el comportamiento por defecto.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;alternate&lt;/code&gt;&lt;br&gt;
La animación, al terminar un ciclo, invierte su dirección. Es decir, los pasos de la animación se ejecutan al revés. Además, las funciones de tiempo también se invierten; por ejemplo una animación ease-in se convierte en una animación con ease-out cuando se reproduce al revés.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;reverse&lt;/code&gt;&lt;br&gt;
Cada ciclo de la animación se reproduce al revés . Cada vez que comienza un ciclo de animación, ésta se posiciona en el estado final y comienza desde ahí.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;alternate-reverse&lt;/code&gt;&lt;br&gt;
Es similar a alternate pero la animación se reproduce al revés. Es decir la animación se posiciona en el estado final, comienza a reproducirse al revés y, cuando llega al inicio vuelve a reproducirse de forma normal hasta llegar al final de la secuencia.&lt;/p&gt;
&lt;h4&gt;
  
  
  animation-fill-mode
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;animation-fill-mode&lt;/code&gt; es la propiedad que nos permite definir el estado después de la animación, y también el estado antes de la animación si existiese delay. Por defecto vuelve a su estado inicial, con el valor normal.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4nfv9F1p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/496c3887f1007594f961e5f107a447f5/4884b/animation-fill-mode.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4nfv9F1p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/496c3887f1007594f961e5f107a447f5/4884b/animation-fill-mode.jpg" alt="animation-fill-mode"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Dibujo de &lt;a href="https://twitter.com/ancoar"&gt;Ángel Corral&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;



&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/claireparker/embed/WNryWxw?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;p&gt;Aquí podemos ver qué pasa si aplicamos un valor de &lt;code&gt;forwards&lt;/code&gt;.&lt;/p&gt;



&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/claireparker/embed/ExPRJgE?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;p&gt;Otro de los valores interesantes de esta propiedad es &lt;code&gt;both&lt;/code&gt;, funcionará igual que &lt;code&gt;forwards&lt;/code&gt; pero tendrá en cuenta el sentido de la animación. ¿Recordáis que con &lt;code&gt;animation-direction&lt;/code&gt; podemos hacer que la animación sea invertida?, pues este valor nos ayudará a definir el comportamiento que deseemos en nuestras animaciones.&lt;/p&gt;

&lt;h4&gt;
  
  
  animation-play-state
&lt;/h4&gt;

&lt;p&gt;Esta propiedad también es muy interesante, ya que nos permite dotar de interactividad nuestra animación desde CSS, sin utilizar JavaScript. Ya veremos más adelante cómo trabajar las animaciones con JavaScript, la API de animación es genial... bueno no nos despistemos 😊.&lt;/p&gt;

&lt;p&gt;Los valores disponibles son:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Single animation */&lt;/span&gt;
&lt;span class="nt"&gt;animation-play-state&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;running&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;animation-play-state&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;paused&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;/* Global values */&lt;/span&gt;
&lt;span class="nt"&gt;animation-play-state&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;inherited&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;animation-play-state&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;initial&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;animation-play-state&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;unset&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;El valor por defecto es &lt;code&gt;running&lt;/code&gt;, y podemos hacer una pausa cambiando su estado. Pero mejor veamos un ejemplo:&lt;/p&gt;



&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/claireparker/embed/ZEQRZeX?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;p&gt;Seguro que has visto que no hay ninguna animación, eso es porque he definido un estado inicial de la animación pausada &lt;code&gt;animation-play-state: paused;&lt;/code&gt;, y con un hover en el &lt;code&gt;body&lt;/code&gt; cambio el estado de la animación a &lt;code&gt;running&lt;/code&gt;. Prueba a poner el cursor, &lt;strong&gt;perdón a la gente que esté leyendo esto desde un dispositivo móvil&lt;/strong&gt; 😅, en área de &lt;strong&gt;Result&lt;/strong&gt;. Verás que la animación se ejecuta y pausa según haces hover o no sobre el body del documento.&lt;/p&gt;

&lt;h3&gt;
  
  
  Los shorthands y valores por defecto
&lt;/h3&gt;

&lt;h4&gt;
  
  
  El shorthands animation
&lt;/h4&gt;

&lt;p&gt;Por norma general cuando veamos un código CSS con una animación veremos algo como esto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.logo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;scale&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt; &lt;span class="n"&gt;ease-in&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Es la forma abreviada de definir una animación. La especificación define un orden para los parámetros, así se facilita la compatibilidad entre los navegadores a la hora de su implementación.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.logo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'animation-name'&lt;/span&gt;
             &lt;span class="s2"&gt;'animation-duration'&lt;/span&gt;
             &lt;span class="s2"&gt;'animation-timing-function'&lt;/span&gt;
             &lt;span class="s2"&gt;'animation-delay'&lt;/span&gt;
             &lt;span class="s2"&gt;'animation-iteration-count'&lt;/span&gt;
             &lt;span class="s2"&gt;'animation-direction'&lt;/span&gt;
             &lt;span class="s2"&gt;'animation-fill-mode'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Los pongo uno bajo el otro para mejorar la legibilidad, pero se definen todos en la misma línea y sin separarlos por una coma. Aunque ese es el orden definido por la W3C, si se cambia el orden, los navegadores son lo suficientemente inteligentes para entender cada uno de los valores a qué hace referencia. Una cosa a tener en cuenta es el &lt;code&gt;duration&lt;/code&gt; y el &lt;code&gt;delay&lt;/code&gt;, si solo hay un valor de tiempo, el navegador interpretará que es &lt;code&gt;duration&lt;/code&gt; y si hay dos, el primero será &lt;code&gt;duration&lt;/code&gt; y el segundo será para definir el &lt;code&gt;delay&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Los valores por defecto
&lt;/h4&gt;

&lt;p&gt;En los ejemplos que hemos ido viendo, he definido valor a todas las propiedades por temas docentes, pero hemos de tener en cuenta que la ausencia de alguna de esas propiedades se representarán con su valor por defecto.&lt;/p&gt;

&lt;p&gt;Por ejemplo, no hace falta definir &lt;code&gt;animation-timing-function: ease&lt;/code&gt; o &lt;code&gt;animation-delay: 0s&lt;/code&gt;, ya que son los valores por defecto.&lt;/p&gt;

&lt;h3&gt;
  
  
  Los @keyframes
&lt;/h3&gt;

&lt;p&gt;Hasta ahora hemos visto todas las propiedades de tiempo, función, iteraciones, etc... para añadir la animación a una clase, pero, ¿dónde creamos o definimos la animación?&lt;/p&gt;

&lt;p&gt;Aquí entran en escena los &lt;code&gt;@keyframes&lt;/code&gt;. Como vimos en el artículo de las &lt;a href="https://dev.to/transiciones-css/"&gt;Transiciones CSS&lt;/a&gt;, con las transiciones podemos hacer que el navegador haga una interpolación entre dos estados y conseguir así, una animación. Pero cuando queremos tener una animación con más de 2 estados tenemos que utilizar los &lt;code&gt;@keyframes&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PxquGeaH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/51cd092a48a33973bee04051e0484028/30744/animation.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PxquGeaH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/51cd092a48a33973bee04051e0484028/30744/animation.png" alt="Animación Web"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Los keyframes hacen referencia a los fotogramas de la animación, y podemos definir los que necesitemos, vamos a ver el códico de la animación que hemos estado utilizando como ejemplo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;logoAnimation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-100px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;20&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt;&lt;span class="err"&gt;80&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Lo primero que vemos es que no estamos definiendo un selector, sino un &lt;a href="https://developer.mozilla.org/es/docs/Web/CSS/At-rule"&gt;at-rule&lt;/a&gt; &lt;em&gt;(como @media, @support, @font-face, etc...)&lt;/em&gt;, es &lt;code&gt;@keyframe&lt;/code&gt; segido del nombre que queremos que tenga la animación. Ese nombre es el identificador que estamos utilizando en la propiedad &lt;code&gt;animation-name&lt;/code&gt;. Seguimos con un bloque, como también hacemos en las clases, pero en esta ocasión no definimos propiedades CSS, definimos bloques de keyframes donde en su interior escibiremos las propiedades CSS que queremos animar... ahora es cuando empieza lo emocionante 😊.&lt;/p&gt;

&lt;p&gt;Para definir los keyframes (fotogramas), tenemos dos maneras de hacerlo, mediante palabras clave o con porcentajes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;identifier&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nt"&gt;to&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;percentage&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;[,&lt;/span&gt; &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nt"&gt;to&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;percentage&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;]*&lt;/span&gt; &lt;span class="nt"&gt;block&lt;/span&gt; &lt;span class="o"&gt;]*&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;from&lt;/code&gt; equivale al &lt;strong&gt;0%&lt;/strong&gt; y &lt;code&gt;to&lt;/code&gt; equivale al &lt;strong&gt;100%&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Estas dos animaciones son equivalentes, es totalmente indiferente desde el punto de vista del navegador.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;logoAnimation_keyworks&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-100px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;to&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;logoAnimation_percentage&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;0&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-100px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Incluso podemos mezclar las palabras clave y los porcentajes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;logoAnimation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;from&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;-100px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="err"&gt;20&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt;&lt;span class="err"&gt;80&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;to&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;opacity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;translateX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Animaciones múltiples
&lt;/h3&gt;

&lt;p&gt;Igual que en las transiciones, la animaciones admiten definir múltiples animaciones. Esto nos permite tener un mayor control si queremos hacer una animación secuencial.&lt;/p&gt;



&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/claireparker/embed/XWXBJWa?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;p&gt;En este ejemplo he creado una secuencia de 4 animaciones.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.logo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;fadeIn&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt; &lt;span class="n"&gt;ease-in&lt;/span&gt; &lt;span class="n"&gt;forwards&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="n"&gt;growth&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt; &lt;span class="n"&gt;ease-in&lt;/span&gt; &lt;span class="n"&gt;forwards&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="n"&gt;fadeOut&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt; &lt;span class="m"&gt;2s&lt;/span&gt; &lt;span class="n"&gt;ease-out&lt;/span&gt; &lt;span class="n"&gt;forwards&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="n"&gt;logoAnimation&lt;/span&gt; &lt;span class="m"&gt;500ms&lt;/span&gt; &lt;span class="m"&gt;3s&lt;/span&gt; &lt;span class="n"&gt;ease-in&lt;/span&gt; &lt;span class="n"&gt;forwards&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KlMrM49N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/nucliweb/image/upload/v1594553060/joanleon.dev/assets/animaciones-css/animations.gif" class="article-body-image-wrapper"&gt;&lt;img alt="Secuencia de animaciones" src="https://res.cloudinary.com/practicaldev/image/fetch/s--KlMrM49N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://res.cloudinary.com/nucliweb/image/upload/v1594553060/joanleon.dev/assets/animaciones-css/animations.gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Controlamos la secuencia de las animaciones con la propiedad &lt;code&gt;animation-delay&lt;/code&gt;, sumando el tiempo de las animaciones anteriores.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Esto es un trabajo muy artesanal y nada escalable, pero eso ya lo veremos cuando trabajemos con las animaciones con JavaScript.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;Hasta aquí hemos visto lo básico de la animación con CSS, en la implementación encontraremos algunos casos donde hay que conocer bien las posibilidades de las propiedades CSS. En futuros capítulos veremos ejemplos de implementación, depuración, optimización y buenas prácticas.&lt;/p&gt;



&lt;h4&gt;
  
  
  Compartir, feedback y erratas
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Si te ha gustado el artículo, compártelo para llegar a más gente.&lt;/li&gt;
&lt;li&gt;Si tienes feedback que me pueda ayudar a mejorar, siéntete libre de pasarme un &lt;a href="https://twitter.com/nucliweb"&gt;DM&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Si ves alguna errata o hay algo que no planteo bien, también agradezco las correcciones &lt;a href="https://twitter.com/nucliweb"&gt;DM&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;



&lt;h4&gt;
  
  
  Sígueme en...
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Twitter:&lt;/strong&gt; &lt;a href="https://twitter.com/nucliweb"&gt;@nucliweb&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;YouTube:&lt;/strong&gt; &lt;a href="https://www.youtube.com/c/JoanLeon"&gt;JoanLeon&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instagram:&lt;/strong&gt; &lt;a href="https://www.instagram.com/nucliweb/"&gt;@nucliweb&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/nucliweb"&gt;@nucliweb&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>web</category>
      <category>animation</category>
      <category>css</category>
    </item>
    <item>
      <title>Transiciones CSS</title>
      <dc:creator>Joan León</dc:creator>
      <pubDate>Thu, 17 Sep 2020 17:22:45 +0000</pubDate>
      <link>https://dev.to/nucliweb/transiciones-css-40po</link>
      <guid>https://dev.to/nucliweb/transiciones-css-40po</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Este artículo es parte de una serie de artículos dedicados a la &lt;strong&gt;Animación Web&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/nucliweb/animacion-web-490k"&gt;Animación Web&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Transiciones CSS&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/nucliweb/animaciones-css-33h9"&gt;Animaciones CSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Animaciones SVG (Próximamanete)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Animaciones JavaScript  (Próximamanete)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Animaciones Canvas  (Próximamanete)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Aquí encontrarás una explicación teórica y detallada de las &lt;strong&gt;Transiciones CSS&lt;/strong&gt;, si quieres ver ejemplos de implementación y casos de uso, echa un vistazo al &lt;a href="https://youtu.be/iRAVt8gsIbM"&gt;vídeo&lt;/a&gt;.&lt;/p&gt;



&lt;h3&gt;
  
  
  Cambios de estado de propiedades CSS
&lt;/h3&gt;

&lt;p&gt;Normalmente, cuando cambiamos el valor de una o varias propiedades CSS, el resultado representado por el navegador se actualiza instantáneamente. Lo podemos ver en el siguiente ejemplo, donde los valores de &lt;code&gt;width&lt;/code&gt; y &lt;code&gt;box-shadow&lt;/code&gt; cambian inmediatamente al poner el cursor sobre el logo, o un tap si estás en un dispositivo táctil.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/claireparker/embed/ExjxdzL?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;p&gt;Las transiciones son un efecto de presentación. El motor de renderizado del navegador hace una &lt;a href="https://es.wikipedia.org/wiki/Interpolaci%C3%B3n"&gt;interpolación&lt;/a&gt;, calculando los valores intermedios entre un valor y otro.&lt;/p&gt;

&lt;p&gt;Aquí tenemos el mismo ejemplo aplicando la transición.&lt;/p&gt;



&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/claireparker/embed/OJVJBeV?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;h3&gt;
  
  
  Así funciona la transición
&lt;/h3&gt;

&lt;p&gt;Si tenemos un elemento en nuestra página que queremos desplazar 200px a la derecha, lo podemos hacer con la propiedad &lt;code&gt;transform&lt;/code&gt;.&lt;/p&gt;



&lt;blockquote&gt;
&lt;p&gt;En el ejemplo usaremos un poco de Javascript para añadir la interacción, en este caso añadiremos una clase para indicarle al elemento su nuevo estado. &lt;em&gt;Podríamos hacer esto mismo sin Javascript, con un checkbox y combinación de selectores CSS, pero yo creo que Javascript nos sirve para añadir la interacción con las usuarias. Pero si hay interés ya veremos en un artículo de CSS cómo hacer este tipo de cosas sin Javascript.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;



&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/claireparker/embed/abOOKeL?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;p&gt;Como hemos visto, la propiedad &lt;code&gt;transition&lt;/code&gt; indica al navegador que haga la interpolación. El navegador intentará, según los recursos disponibles, actualizar el renderizado de la página a 60 fotogramas por segundo.&lt;/p&gt;

&lt;p&gt;Si tenemos en cuenta que el desplazamiento es de 200px en un tiempo de 0.5 segundos, en un caso ideal de 60 fotogramas/segundo, la interpolación será de 30 fotogramas. El navegador hará el cálculo para la interpolación: &lt;code&gt;200px/30fps = 6.666px&lt;/code&gt;, así que desplazará el elemento 6.666px a la derecha en cada ciclo de la animación.&lt;/p&gt;

&lt;p&gt;En la siguiente imagen podemos ver la representación que hace Chrome en el Developer Tools de la transición.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4qlRPU2S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/957f4a1dbdabcc8b31917c32d9910812/30744/devtools-transition.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4qlRPU2S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/957f4a1dbdabcc8b31917c32d9910812/30744/devtools-transition.png" alt="Developer Tools: Transición"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tenemos una representación gráfica del número de fotogramas en la línea de tiempo, y también podemos ver el tiempo que ha tardado en hacer la transición &lt;strong&gt;502,29 ms&lt;/strong&gt;.&lt;/p&gt;



&lt;blockquote&gt;
&lt;p&gt;En las herramientas de desarrollos, tanto Chrome como Firefox, tenemos mucha información y herramientas. Ya lo analizaremos en detalle en un futuro artículo, y conocer cómo las podemos utilizar para depurar nuestras animaciones o analizar las animaciones de otras páginas web (se aprende mucho analizando el desarrollo de otras personas).&lt;/p&gt;
&lt;/blockquote&gt;



&lt;h2&gt;
  
  
  Propiedades CSS para las transiciones
&lt;/h2&gt;

&lt;p&gt;Analicemos en detalle cada una de las propiedades CSS que tenemos para definir y controlar las transiciones.&lt;/p&gt;

&lt;h3&gt;
  
  
  transition-property
&lt;/h3&gt;

&lt;p&gt;En esta propiedad podemos definir la &lt;strong&gt;propiedad&lt;/strong&gt; CSS a la que queremos aplicar la transición.&lt;/p&gt;

&lt;p&gt;Si queremos aplicar una transición entre el cambio de color de fondo de un elemento, deberíamos definirlo de la siguiente forma: &lt;code&gt;transition-property: background-color&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Si echamos un vistazo a la documentación de la &lt;strong&gt;W3C&lt;/strong&gt; veremos la siguiente tabla.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Values&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;none OR [ all OR &lt;code&gt;&amp;lt;property-name&amp;gt;&lt;/code&gt; ]#&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Initial value&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;all&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Applies to&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;All elements and :before and :after pseudo-elements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Computed value&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;As specified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Inherited&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Animatable&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Esta tabla la veremos en casi todas la propiedades CSS en la documentación oficial de la &lt;strong&gt;W3C&lt;/strong&gt;, nos informa de los posibles valores que podemos definir para esa propiedad, el valor inicial que tiene si no definimos uno nosotras, a los elementos que aplica, el valor calculado, si hereda el valor del elemento ancestro y si es un valor que se puede animar.&lt;/p&gt;

&lt;p&gt;Un valor destacable de esta información es el valor inicial, &lt;code&gt;all&lt;/code&gt; lo que hace que podamos obviar la definición de la propiedad que queremos animar. Otra información interesante es el hashtag &lt;code&gt;#&lt;/code&gt; que vemos al final de los valores, esto indica que la propiedad admite una lista de valores separados por comas.&lt;/p&gt;

&lt;p&gt;Así que podríamos definir lo siguiente para hacer referencia a varias propiedades.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.logo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transition-property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;blockquote&gt;
&lt;p&gt;Dedicaré un artículo a la performance en la animación, y analizaremos si tiene impacto definir las propiedades que queremos animar de forma explícita en lugar de dejar el valor predeterminado &lt;code&gt;all&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;



&lt;h3&gt;
  
  
  transition-duration
&lt;/h3&gt;

&lt;p&gt;Con la propiedad &lt;code&gt;transition-duration&lt;/code&gt; definimos el tiempo de la transición, o transiciones si definimos una lista separada por comas &lt;em&gt;(aquí también podemos ver el #)&lt;/em&gt;. Acepta valores positivos con unidades de segundos (s) o milisegundos (ms).&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Values&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;&amp;lt;time&amp;gt;&lt;/code&gt;#&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Initial value&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Applies to&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;All elements and :before and :after pseudo-elements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Computed value&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;As specified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Inherited&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Animatable&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;p&gt;Si definimos un valor en negativo, el navegador ignora la regla y los cambios se aplicarían sin ninguna transición.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NUNlL-Gm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/eefabaac5bd61f5de60b60a7905813aa/4caf9/negative.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NUNlL-Gm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/eefabaac5bd61f5de60b60a7905813aa/4caf9/negative.png" alt="Negative values"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  transition-timing-function
&lt;/h3&gt;

&lt;p&gt;Con la propiedad &lt;code&gt;transition-timing-function&lt;/code&gt; tenemos la opción de definir las funciones de tiempo. Se trata de una serie de valores: ease, linear, ease-in, ease-out, ease-in-out, step-start, step-end, steps(n, start) predefinidos de funciona de &lt;a href="https://es.wikipedia.org/wiki/Curva_de_B%C3%A9zier"&gt;Curvas de Bécier&lt;/a&gt; &lt;code&gt;cubic-bezier(x1, y1, x2, y2)&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Las Curvas de Bézier merecen un artículo específico y detallado, ya que tenemos una especificación dedicada a su definición, &lt;a href="https://www.w3.org/TR/css-easing-1/"&gt;CSS Easing Functions Leve 1&lt;/a&gt;, así que lo trataremos en futuros artículos analizando los aspectos técnicos y casos de uso de su implementación.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Aquí tenemos la tabla con la información básica.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Values&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;&amp;lt;timing-function&amp;gt;&lt;/code&gt;#&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Initial value&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ease&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Applies to&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;All elements and :before and :after pseudo-elements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Computed value&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;As specified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Inherited&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Animatable&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;p&gt;Podemos ver que el valor por defecto es &lt;code&gt;ease&lt;/code&gt; que equivale a la Curva de Bézier &lt;code&gt;cubic-bezier(0.25, 0.1, 0.25, 1)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bRIu5LvR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/1db08aff35dbdb61adbfd89f572290b8/5d4b2/ease.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bRIu5LvR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/1db08aff35dbdb61adbfd89f572290b8/5d4b2/ease.png" alt="ease function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esta es su representación gráfica. Como ya he comentado, veremos todas con más detalle en un futuro artículo.&lt;/p&gt;

&lt;h3&gt;
  
  
  transition-delay
&lt;/h3&gt;

&lt;p&gt;Como su propio nombre indica, la propiedad &lt;code&gt;transition-delay&lt;/code&gt; nos permite definir un valor para indicar el timpo de espera antes de empezar la transición.&lt;/p&gt;

&lt;p&gt;La tabla de valores es idéntica a la de &lt;code&gt;transition-duration&lt;/code&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Values&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;&amp;lt;time&amp;gt;&lt;/code&gt;#&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Initial value&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Applies to&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;All elements and :before and :after pseudo-elements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Computed value&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;As specified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Inherited&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Animatable&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;p&gt;Esta propiedad sí que permite definir un valor negativo. Por ejemplo, si tenemos un valor de &lt;code&gt;-250ms&lt;/code&gt; en una transición de una duración de &lt;code&gt;500ms&lt;/code&gt; la animación tendrá la mitad del recorrido. Y si el valor negativo es superior a su equivalente positivo de &lt;code&gt;transition-duration&lt;/code&gt; no obtendremos una transición, sino un cambio inmediato entre los dos estados.&lt;/p&gt;

&lt;p&gt;Aquí podemos ver un ejemplo de definir un valor negativo en la propiedad &lt;code&gt;transition-delay&lt;/code&gt;.&lt;/p&gt;



&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/claireparker/embed/jOPrvMP?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;h3&gt;
  
  
  transition (shorthand)
&lt;/h3&gt;

&lt;p&gt;Muchas de las propiedades CSS tienen un &lt;em&gt;shorthand&lt;/em&gt; (abreviado). Nos permite utilizar una propiedad con múltiples valores, veamos un ejemplo que creo que es mucho más fácil de entender.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Transición con múltiples propiedades */&lt;/span&gt;
&lt;span class="nc"&gt;.logo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transition-property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.5s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-timing-function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ease-out&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-delay&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.25s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* Transición con shorthand */&lt;/span&gt;
&lt;span class="nc"&gt;.logoJL&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="m"&gt;0.5s&lt;/span&gt; &lt;span class="n"&gt;ease-out&lt;/span&gt; &lt;span class="m"&gt;0.25s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;p&gt;En el código anterior, las dos clases aplicarían la misma transición. Cuando definimos una transición como shorthand en nuestro código, si la inspeccionamos con el DevTools podremos verlo así.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_7jdwT3v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/e1a9bb019f40fb83cc2ea853af152d00/10c3b/devtools-transition-shothand.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_7jdwT3v--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/e1a9bb019f40fb83cc2ea853af152d00/10c3b/devtools-transition-shothand.png" alt="DevTools: Transición abreviada"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Podemos ver que hay un triángulo, nos indica que hay más información disponible en esa propiedad CSS. Si hacemos clic en él, podremos observar que internamente el navegador las interpreta por separado.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8mQG75xs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/ec092c3663ce20e67330f48defd9f3ee/10c3b/devtools-transition-shothand-open.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8mQG75xs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/ec092c3663ce20e67330f48defd9f3ee/10c3b/devtools-transition-shothand-open.png" alt="DevTools: Transición abreviada desplegada"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Como en las propiedades anteriores, en &lt;code&gt;transition&lt;/code&gt; también tenemos la tabla informativa de la especificación.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Values&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;&amp;lt;single-transition&amp;gt;&lt;/code&gt;#&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Initial value&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;all 0s ease 0s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Applies to&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;All elements and :before and :after pseudo-elements&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Computed value&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;As specified&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Inherited&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Animatable&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&amp;lt;single-transition&amp;gt;&lt;/strong&gt; = [ [ none &amp;amp;Vert; &amp;lt;transition-property&amp;gt; ] &amp;amp;Vert; &amp;lt;time&amp;gt; &amp;amp;Vert; &amp;lt;transition-timingfunction&amp;gt; &amp;amp;Vert; &amp;lt;time&amp;gt; ]#&lt;/p&gt;

&lt;p&gt;En los ejemplos que hemos ido viendo he estado utilizando la transición como shorthand, ya que es lo más habitual.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trabajando con transiciones
&lt;/h2&gt;



&lt;h3&gt;
  
  
  Valores por defecto
&lt;/h3&gt;

&lt;p&gt;A la hora de trabajar con transiciones hay que entender cómo el navegador hace la interpretación de la sintaxis.&lt;/p&gt;

&lt;p&gt;El valor por defecto de &lt;code&gt;transition-property&lt;/code&gt; o como valor en el shorthand &lt;code&gt;transition&lt;/code&gt; es &lt;code&gt;all&lt;/code&gt;, eso quiere decir que la transición que apliquemos afectará a todas la propiedades (que lo permitan) de la clase CSS donde lo estemos indicando.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.logo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transition-property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;250ms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-timing-function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.logoJL&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="m"&gt;250ms&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;En el código anterior las dos clases hacen lo mismo, pero hay un detalle que debemos tener en cuenta. Si miramos cúales son los valores por defecto de cada una de esas propiedades podremos ver que estamos definiendo valores que el navegador ya los tiene por defecto.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.logo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transition-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;250ms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.logoJL&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;250ms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Este código tendrá exactamente el mismo comportamiento, aunque no le hayamos definido valores a &lt;code&gt;transition-property&lt;/code&gt; y &lt;code&gt;transition-timing-function&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Por temas de semántica y posterior interpretación del código, ya sea por nosotras mismas en el futuro, o por otra persona, lo habitual es (como mínimo) encontrarnos con el valor de la &lt;code&gt;transition-property&lt;/code&gt; definido.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Transiciones múltiples
&lt;/h3&gt;

&lt;p&gt;Ya lo hemos visto desde el primer ejemplo del artículo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.logo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="m"&gt;0.25s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;box-shadow&lt;/span&gt; &lt;span class="m"&gt;0.25s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="err"&gt;...;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Hemos definido transiciones de forma independiente para &lt;code&gt;width&lt;/code&gt; y &lt;code&gt;box-shadow&lt;/code&gt;. En este caso lo podríamos haber hecho con un valor de &lt;code&gt;all .25s&lt;/code&gt;, tendría el mismo efecto. Pero hacerlo de forma separada nos permite poder definir diferentes tiempos, retardo o funciones de tiempo a cada una de las propiedades.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.logo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="nl"&gt;transition-property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.25s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;250ms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-timing-function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ease-in-out&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="err"&gt;...;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.logoJL&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt; &lt;span class="m"&gt;0.25s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;box-shadow&lt;/span&gt; &lt;span class="m"&gt;0.25s&lt;/span&gt; &lt;span class="n"&gt;ease-in-out&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="err"&gt;...;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;A modo de ejemplo he utilizado las unidades en segundo y mili segundos, para mostrar que pueden convivir sin problemas.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;En el caso de que definamos varias propiedades, donde el número de propiedades es mayor al número de valores en la propiedad duración, este se repite.&lt;/p&gt;

&lt;p&gt;En el siguiente código los valores de &lt;code&gt;transition-duration&lt;/code&gt; y &lt;code&gt;transition-timing-function&lt;/code&gt; se repetirán hasta coincidir con el número de valores de &lt;code&gt;transition-property&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.logo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="nl"&gt;transition-property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.25s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;250ms&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-timing-function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ease-in-out&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="err"&gt;...;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Quedando así:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.logo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="nl"&gt;transition-property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;color&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-duration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.25s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;250ms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.25s&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;250ms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.25s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition-timing-function&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ease-in-out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ease-in-out&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="err"&gt;...;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vRbgfO5O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/0271db5f2caf322db107ee8eca447cef/30744/css-transitions-canonical-order.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vRbgfO5O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/0271db5f2caf322db107ee8eca447cef/30744/css-transitions-canonical-order.png" alt="CSS Transtions Canonical Order"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  El orden de los valores
&lt;/h2&gt;

&lt;p&gt;Como la propia documentación de la &lt;em&gt;W3C&lt;/em&gt; nos indica, el orden de los valores en la propiedad &lt;code&gt;transition&lt;/code&gt; es importante. Como hemos visto en las tablas más arriba nos dicen &lt;code&gt;&amp;lt;single-transition&amp;gt; = [ none | &amp;lt;single-transition-property&amp;gt; ] || &amp;lt;time&amp;gt; || &amp;lt;timing-function&amp;gt; || &amp;lt;time&amp;gt;&lt;/code&gt;. Eso quiere decir que el navegador está esperando: &lt;strong&gt;none&lt;/strong&gt; o una &lt;strong&gt;propiedad&lt;/strong&gt;, seguido de la duración, la función de tiempo y por último el tiempo de retardo.&lt;/p&gt;

&lt;p&gt;He estado probando varias combinaciones, el navegador es lo suficientemente inteligente como para saber corregir un error en el orden.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.logo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ease-in&lt;/span&gt; &lt;span class="n"&gt;opacity&lt;/span&gt; &lt;span class="m"&gt;250ms&lt;/span&gt; &lt;span class="m"&gt;3s&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;En el código anterior el navegador será capaz de interpretar la transición a pesar de que los valores no estén ordenados siguiendo el estándar. Incluso si el primer valor de tiempo es negativo, interpreta que estamos indicando el valor de &lt;code&gt;transition.delay&lt;/code&gt; ya que en &lt;code&gt;transition-duration&lt;/code&gt; no podemos tener un valor negativo. Os invito a que probéis combinaciones para entender cómo funciona.&lt;/p&gt;

&lt;h2&gt;
  
  
  ¿Cómo funcionan por dentro las transiciones?
&lt;/h2&gt;

&lt;p&gt;Más allá de saber cómo definir nuestras transiones para poder añadir animaciones e interacciones, podemos ver en los códigos de los navegadores cómo están aplicando lo que podemos ver en las especificaciones de la &lt;em&gt;W3C&lt;/em&gt;, que de hecho es una documentación para los desarrolladores de los navegadores, todo sea dicho.&lt;/p&gt;

&lt;p&gt;Tenemos la suerte de tener disponible el código fuente, de la mayoría de los navegadores, accesible.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/chromium/chromium"&gt;Chromium&lt;/a&gt; el motor utilizado en Google Chrome, Opera y recientemente por el navegador de Microsoft&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/mozilla/gecko-dev"&gt;Geko&lt;/a&gt; el motor que utiliza Mozilla para Firefox.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/WebKit/webkit"&gt;Webkit&lt;/a&gt; fue el motor de Chrome y Opera, pero ahora solo lo utiliza Safari.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Es curioso ver código como el &lt;a href="https://github.com/chromium/chromium/blob/master/third_party/blink/renderer/core/css/properties/shorthands/shorthands_custom.cc#L2819-L2857"&gt;siguiente&lt;/a&gt;, donde podemos ver que justamente cómo crea la lista de valores de una transición en modo shorthand &lt;code&gt;transition&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;CSSValue&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;Transition&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CSSValueFromComputedStyleInternal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;ComputedStyle&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;SVGComputedStyle&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;LayoutObject&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;allow_visited_style&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;CSSTransitionData&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;transition_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Transitions&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transition_data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;CSSValueList&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;transitions_list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CSSValueList&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CreateCommaSeparated&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wtf_size_t&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;transition_data&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;PropertyList&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;CSSValueList&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CSSValueList&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CreateSpaceSeparated&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ComputedStyleUtils&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CreateTransitionPropertyValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="n"&gt;transition_data&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;PropertyList&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]));&lt;/span&gt;
      &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;CSSNumericLiteralValue&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="n"&gt;CSSTimingData&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;GetRepeated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transition_data&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;DurationList&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;CSSPrimitiveValue&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;UnitType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;kSeconds&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ComputedStyleUtils&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CreateTimingFunctionValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="n"&gt;CSSTimingData&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;GetRepeated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transition_data&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;TimingFunctionList&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
              &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;
      &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;CSSNumericLiteralValue&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="n"&gt;CSSTimingData&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;GetRepeated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;transition_data&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;DelayList&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;CSSPrimitiveValue&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;UnitType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;kSeconds&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="n"&gt;transitions_list&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;transitions_list&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="n"&gt;CSSValueList&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CSSValueList&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CreateSpaceSeparated&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// transition-property default value.&lt;/span&gt;
  &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;CSSIdentifierValue&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CSSValueID&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;kAll&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;CSSNumericLiteralValue&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CSSTransitionData&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;InitialDuration&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                                      &lt;span class="n"&gt;CSSPrimitiveValue&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;UnitType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;kSeconds&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;ComputedStyleUtils&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CreateTimingFunctionValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;CSSTransitionData&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;InitialTimingFunction&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;
  &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;CSSNumericLiteralValue&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CSSTransitionData&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;InitialDelay&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
                                      &lt;span class="n"&gt;CSSPrimitiveValue&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;UnitType&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;kSeconds&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;h2&gt;
  
  
  Conclusiones
&lt;/h2&gt;

&lt;p&gt;Las transiciones fueron el primer paso para tener animaciones en la web, son tan básicas como potentes. Nos permiten definir unas animaciones muy optimizadas. Combinando varias propiedades, tiempos de duración y tiempos de retardo podemos hacer pequeñas animaciones, pero cuando necesitamos hacer animaciones con mas de dos estados ya tenemos que pasar a utilizar las propiedades &lt;code&gt;animation&lt;/code&gt; junto con &lt;code&gt;@keyframes&lt;/code&gt;, pero eso lo veremos en el siguiente artículo de esta serie.&lt;/p&gt;



&lt;h4&gt;
  
  
  Compartir, feedback y erratas
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Si te ha gustado el artículo, compártelo para llegar a más gente.&lt;/li&gt;
&lt;li&gt;Si tienes feedback que me pueda ayudar a mejorar, siéntete libre de pasarme un &lt;a href="https://twitter.com/nucliweb"&gt;DM&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Si ves alguna errata o hay algo que no planteo bien, también agradezco las correcciones &lt;a href="https://twitter.com/nucliweb"&gt;DM&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;



&lt;h4&gt;
  
  
  Sígueme en...
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Twitter:&lt;/strong&gt; &lt;a href="https://twitter.com/nucliweb"&gt;@nucliweb&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;YouTube:&lt;/strong&gt; &lt;a href="https://www.youtube.com/c/JoanLeon"&gt;JoanLeon&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instagram:&lt;/strong&gt; &lt;a href="https://www.instagram.com/nucliweb/"&gt;@nucliweb&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/nucliweb"&gt;@nucliweb&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>web</category>
      <category>animation</category>
      <category>css</category>
      <category>transitions</category>
    </item>
    <item>
      <title>Animación Web</title>
      <dc:creator>Joan León</dc:creator>
      <pubDate>Thu, 17 Sep 2020 16:56:39 +0000</pubDate>
      <link>https://dev.to/nucliweb/animacion-web-490k</link>
      <guid>https://dev.to/nucliweb/animacion-web-490k</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Este es el primero de una serie de artículos para ver tecnologías, herramientas, ejemplos y performance en animación web.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Animación Web&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/nucliweb/transiciones-css-40po"&gt;Transiciones CSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/nucliweb/animaciones-css-33h9"&gt;Animaciones CSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Animaciones SVG (Próximamanete)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Animaciones JavaScript (Próximamanete)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Animaciones Canvas (Próximamanete)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Todas sabemos que las animaciones, ya sea en un logo, como transiciones entre estados, informativas o animación en microinteracciones, aportan valor al producto y a la experiencia.&lt;/p&gt;

&lt;p&gt;Tenemos varias técnicas o vías de desarrollo a la hora de implementar animaciones en la web, así que vamos a conocerlas.&lt;/p&gt;

&lt;h3&gt;
  
  
  Opciones para hacer animaciones en la Web
&lt;/h3&gt;

&lt;p&gt;Lo primero que hemos de tener en cuenta es el &lt;strong&gt;tipo de elemento&lt;/strong&gt; que vamos a animar. Podemos animar un elemento del DOM, un SVG o parte de él, un atributo de un elemento del DOM &lt;em&gt;(como el color)&lt;/em&gt; o finalmente elementos gráficos representados en un elemento &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  1.CSS
&lt;/h4&gt;

&lt;p&gt;La animación con CSS se puede considerar que es la base de la animación web. Tanto para elementos del DOM como para SVG.&lt;/p&gt;

&lt;h5&gt;
  
  
  Transiciones
&lt;/h5&gt;

&lt;p&gt;La animación básica en CSS es una transición entre 2 estados:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zCsm9ZFI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/533de9cb58d7474a89d46c30890ae919/30744/transition.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zCsm9ZFI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/533de9cb58d7474a89d46c30890ae919/30744/transition.png" alt="Transiciones"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;En el siguiente ejemplo podemos ver un cambio de estado en el tamaño de la imagen al poner el cursor sobre ella (hover).&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/nucliweb/embed/ExjxdzL?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;p&gt;Como véis, el cambio de estado es instantáneo, un poco brusco.&lt;/p&gt;

&lt;p&gt;En CSS tenemos disponible la propiedad &lt;code&gt;transition&lt;/code&gt; y si la utilizamos, podemos ver que cambia totalmente el efecto:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/nucliweb/embed/OJVJBeV?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;h5&gt;
  
  
  ¿Qué está pasando ahora?
&lt;/h5&gt;

&lt;p&gt;Al añadir la propiedad &lt;code&gt;transition&lt;/code&gt; podemos ver que ahora tenemos una animación. Esto se debe a que el navegador está interpolando (calculando los pasos intermedios) entre los dos estados, en este caso un cambio de tamaño de la imagen y una sombra.&lt;/p&gt;

&lt;h5&gt;
  
  
  Transitions
&lt;/h5&gt;

&lt;p&gt;En el ejemplo he utilizado la propiedad &lt;code&gt;transition&lt;/code&gt; como shorthand, pero veamos en detalles las propiedades que tenemos disponibles.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Propiedad&lt;/th&gt;
&lt;th&gt;Función&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt; transition-property&lt;/td&gt;
&lt;td&gt;Propiedad CSS a la que queremos aplicar la transición&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt; transition-duration&lt;/td&gt;
&lt;td&gt;Tiempo transcurrido entre los estados&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt; transition-timing-function&lt;/td&gt;
&lt;td&gt;Función que define cómo se calcula la transición&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt; transition-delay&lt;/td&gt;
&lt;td&gt;Tiempo transcurrido hasta que empieza la transición&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt; transition&lt;/td&gt;
&lt;td&gt;Funciona como shorthand para definir las propiedades anteriores en una sola línea&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;h5&gt;
  
  
  @keyframes
&lt;/h5&gt;

&lt;p&gt;Las transiciones son muy útiles para controlar la animación entre dos estados, pero si queremos poder animar más de 2 estados, tenemos que utilizar los &lt;code&gt;@keyframes&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PxquGeaH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/51cd092a48a33973bee04051e0484028/30744/animation.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PxquGeaH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/51cd092a48a33973bee04051e0484028/30744/animation.png" alt="Animación"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/nucliweb/embed/zYGYMdM?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;p&gt;En el ejemplo podemos ver que hay una propiedad &lt;code&gt;animation: scale 2s infinite ease;&lt;/code&gt; en la clase &lt;code&gt;.logo&lt;/code&gt; y después una función &lt;code&gt;@keyframes&lt;/code&gt; donde definimos 3 estados a la animación. Lo estamos haciendo con porcentajes &lt;code&gt;0%&lt;/code&gt;, &lt;code&gt;50%&lt;/code&gt; y &lt;code&gt;100%&lt;/code&gt;, hacen referencia a la línea temporal que hemos definido de 2 segundos en la propiedad &lt;code&gt;animate&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Al igual que &lt;code&gt;transition&lt;/code&gt;, he utilizado la propiedad &lt;code&gt;animate&lt;/code&gt; como shorthand, las propiedades que podemos utilizar para definir una animación son:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Propiedad&lt;/th&gt;
&lt;th&gt;Función&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;animation-name&lt;/td&gt;
&lt;td&gt;Nombre de la animación, que hemos definido en &lt;code&gt;@keframes&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;animation-duration&lt;/td&gt;
&lt;td&gt;Duración de la animación&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;animation-timing-function&lt;/td&gt;
&lt;td&gt;Especifica cómo una animación CSS debe avanzar sobre la duración de cada ciclo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;animation-delay&lt;/td&gt;
&lt;td&gt;Tiempo transcurrido hasta que empieza la animación&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;animation-iteration-count&lt;/td&gt;
&lt;td&gt;Número de repeticiones de la animación&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;animation-direction&lt;/td&gt;
&lt;td&gt;Indica si la animación debe retroceder hasta el fotograma de inicio al finalizar la secuencia&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;animation-fill-mode&lt;/td&gt;
&lt;td&gt;Especifica el modo en que una animación CSS aplica sus estilos, estableciendo su persistencia y estado final tras su ejecución&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;animation-play-state&lt;/td&gt;
&lt;td&gt;Determina si una animación está en ejecución o en pausa&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;No te preocupes si no entiendes algo, en siguientes artículos entraremos en detalle del funcionamiento de la propiedad &lt;code&gt;animation&lt;/code&gt; y &lt;code&gt;@keyframe&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;



&lt;h4&gt;
  
  
  2.SVG
&lt;/h4&gt;

&lt;p&gt;Los gráficos SVG (en el HTML) acaba siendo representado en el navegador como elementos que forman parte de DOM, por lo que los podemos animar también con CSS.&lt;/p&gt;

&lt;p&gt;En este ejemplo animamos el color de dos de los elementos del logo con CSS.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/nucliweb/embed/GRJgpMp?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;p&gt;SVG tiene su propia especificación para animar elementos, pero está obsoleta, así que no voy a comentarla. Pero os dejo este enlace "&lt;a href="https://developer.mozilla.org/en-US/docs/Web/SVG/SVG_animation_with_SMIL"&gt;SVG animation with SMIL&lt;/a&gt;" por si tenéis curiosidad &lt;em&gt;(yo la tuve y estuve mirando cómo funciona&lt;/em&gt; 🤪&lt;em&gt;)&lt;/em&gt;.&lt;/p&gt;



&lt;h4&gt;
  
  
  3.JavaScript
&lt;/h4&gt;

&lt;p&gt;Para la animación web con JavaScript, de forma nativa, tenemos a nuestra disposición &lt;a href="https://www.w3.org/TR/web-animations-1/"&gt;Web Animation API&lt;/a&gt; (WAAPI).&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/nucliweb/embed/LYVEdEg?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;p&gt;En el ejemplo con WAAPI conseguimos el mismo efecto que la versión anterior, pero en esta ocasión la animación está definida en JavaScript, con todo el potencial programático que ello conlleva.&lt;/p&gt;

&lt;p&gt;Esto tiene muy buena pinta, pero la mala noticia es el soporte actual en los navegadores.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5ky4uH_J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/de8483b6020b4cc6f449ed22bda3ef97/30744/web-animation.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5ky4uH_J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://joanleon.dev/static/de8483b6020b4cc6f449ed22bda3ef97/30744/web-animation.png" alt="Web Animations API"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Como podemos ver en &lt;a href="https://caniuse.com/#feat=web-animation"&gt;Can I Use&lt;/a&gt; nos queda lejos de poder implementar de forma nativa. Podemos utilizar un &lt;a href="https://web-animations.github.io/web-animations-demos/"&gt;polyfill&lt;/a&gt;, pero eso ya lo veremos en un artículo dedicado a Web Animation API.&lt;/p&gt;

&lt;p&gt;Es por eso que las librerías JavaScript se basan en su propia API de animación y transformación con CSS. Lo veremos en detalle cuando veamos las librerías JS.&lt;/p&gt;



&lt;h4&gt;
  
  
  4.Canvas
&lt;/h4&gt;

&lt;p&gt;El elemento &lt;code&gt;canvas&lt;/code&gt; tiene una API para poder pintar gráficos. En realidad las animaciones en el &lt;code&gt;canvas&lt;/code&gt; las definimos y controlamos con JavaScript, pero lo he querido tratar a parte por ser muy diferente la manera de animar dentro de este lienzo.&lt;/p&gt;

&lt;p&gt;Aquí os dejo un ejemplo de &lt;a href="https://twitter.com/anatudor"&gt;Ana Tudor&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/nucliweb/embed/MWYRaKa?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;



&lt;p&gt;Ya veremos en más detalle cómo animar en este elemento en futuros artículos, ya que da mucho juego... y ni os lo imagináis si ya metemos en escena la API &lt;strong&gt;WebGL&lt;/strong&gt; o los &lt;strong&gt;Sahders&lt;/strong&gt;, veréis que bien nos lo vamos a pasar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recursos
&lt;/h2&gt;

&lt;p&gt;Al nivel tan general que he hablado de la Animación Web, tendría que poner muchas referencias. Todos estos temas los vamos a ver en detalle uno a uno, así que ya tendremos los recursos detallados en los siguientes artículos.&lt;/p&gt;

&lt;p&gt;Pero os dejo enlace a &lt;a href="https://github.com/nucliweb/People-You-Should-Follow-on-CodePen"&gt;People You Should Follow on CodePen&lt;/a&gt;, una lista de artistas a los que creo que es muy interesante seguir en &lt;strong&gt;CodePen&lt;/strong&gt;.&lt;/p&gt;



&lt;h4&gt;
  
  
  Compartir, feedback y erratas
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Si te ha gustado el artículo, compártelo para llegar a más gente.&lt;/li&gt;
&lt;li&gt;Si tienes feedback que me pueda ayudar a mejorar, siéntete libre de pasarme un &lt;a href="https://twitter.com/nucliweb"&gt;DM&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Si ves alguna errata o hay algo que no planteo bien, también agradezco las correcciones &lt;a href="https://twitter.com/nucliweb"&gt;DM&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;



&lt;h4&gt;
  
  
  Sígueme en...
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Twitter:&lt;/strong&gt; &lt;a href="https://twitter.com/nucliweb"&gt;@nucliweb&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;YouTube:&lt;/strong&gt; &lt;a href="https://www.youtube.com/c/JoanLeon"&gt;JoanLeon&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Instagram:&lt;/strong&gt; &lt;a href="https://www.instagram.com/nucliweb/"&gt;@nucliweb&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/nucliweb"&gt;@nucliweb&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>web</category>
      <category>animation</category>
      <category>css</category>
      <category>svg</category>
    </item>
  </channel>
</rss>
