<?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: Mateusz Hadryś</title>
    <description>The latest articles on DEV Community by Mateusz Hadryś (@hadrysmateusz).</description>
    <link>https://dev.to/hadrysmateusz</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%2F181202%2Ffe857a32-d940-4cdb-9d8f-719b165dc573.png</url>
      <title>DEV Community: Mateusz Hadryś</title>
      <link>https://dev.to/hadrysmateusz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hadrysmateusz"/>
    <language>en</language>
    <item>
      <title>Gradient Text In CSS</title>
      <dc:creator>Mateusz Hadryś</dc:creator>
      <pubDate>Mon, 11 Jan 2021 15:29:06 +0000</pubDate>
      <link>https://dev.to/hadrysmateusz/gradient-text-in-css-38g6</link>
      <guid>https://dev.to/hadrysmateusz/gradient-text-in-css-38g6</guid>
      <description>&lt;p&gt;It can be hard to make a website stand out.&lt;/p&gt;

&lt;p&gt;So here’s a little trick that will improve any landing page or header: Use gradient text.&lt;/p&gt;

&lt;p&gt;Just make sure to not overuse it. Gradients should never be used for longer text. Instead, use them to make headings or specific words more eye-catching.&lt;/p&gt;

&lt;p&gt;What might surprise you — especially if you have prior experience with design tools — is that you can’t set a gradient as the text color directly. For example &lt;code&gt;color: linear-gradient(yellow, red);&lt;/code&gt; won’t work.&lt;/p&gt;

&lt;p&gt;But gradient text &lt;strong&gt;can&lt;/strong&gt; be achieved in CSS, it just requires a few extra steps.&lt;/p&gt;

&lt;p&gt;It’s best to start with some big, preferably bold text. This will make the gradient more visible and the text more readable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flj8eobfndkd23m46kaat.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flj8eobfndkd23m46kaat.png" alt="Starting Text - Big, bold and black"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The text I’ll be using is styled using the &lt;a href="https://dev.to/hadrysmateusz/full-text-styling-with-a-single-line-of-css-3kbd"&gt;font shorthand&lt;/a&gt; with the following values:&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="nt"&gt;font&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;bold&lt;/span&gt; &lt;span class="err"&gt;120&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="nt"&gt;Poppins&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;sans-serif&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 1: Add a Gradient
&lt;/h3&gt;

&lt;p&gt;First, we need to add the gradient as a background.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcf2zw7gtu2eepb3ddra5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcf2zw7gtu2eepb3ddra5.png" alt="Text with a top to bottom gradient background"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By default the gradient will go from top to bottom, but we can also specify a direction.&lt;/p&gt;

&lt;p&gt;If you want a horizontal gradient, &lt;code&gt;to right&lt;/code&gt; will do the trick, but a slight angle like &lt;code&gt;60deg&lt;/code&gt; looks more natural.&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="nt"&gt;background-image&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;linear-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;60&lt;/span&gt;&lt;span class="nt"&gt;deg&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;#E21143&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;#FFB03A&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpbc0a2dagfgqkpvmv318.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpbc0a2dagfgqkpvmv318.png" alt="Text with a left to right gradient background"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you want to learn how to create any gradient you want, or simply need a refresher, check out my &lt;a href="https://dev.to/hadrysmateusz/complete-guide-to-css-gradients-1eck"&gt;Ultimate Guide to CSS Gradients&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Clip It
&lt;/h3&gt;

&lt;p&gt;Now, we need to make the gradient only show where the text is. We can do that by using &lt;code&gt;background-clip&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvnxzpk142spn1xz6gjl3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvnxzpk142spn1xz6gjl3.png" alt="Four images showing effects of different background-clip values"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To learn more about this and other background properties, check out my article explaining &lt;a href="https://dev.to/hadrysmateusz/learn-all-8-background-css-properties-in-5-minutes-2lk4"&gt;all background properties&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You might already know that this property lets us clip the background to the border, padding, or content &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/The_box_model#parts_of_a_box" rel="noopener noreferrer"&gt;box&lt;/a&gt; of an element. &lt;/p&gt;

&lt;p&gt;But it can also clip the background to the text.&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;.gradient-text&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;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60deg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#E21143&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#FFB03A&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;background-clip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;text&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;If you try this code, it will look like the gradient just disappeared. That’s because the gradient is &lt;strong&gt;under&lt;/strong&gt; the text.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Reveal It
&lt;/h3&gt;

&lt;p&gt;To show the gradient underneath our text, we need to make the text transparent. We can do that by setting &lt;code&gt;color: transparent&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ft3rtrlucc4mwr6v1nzjb.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ft3rtrlucc4mwr6v1nzjb.gif" alt="gif showing a transition between black and gradient text"&gt;&lt;/a&gt;&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;.gradient-text&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;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60deg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#E21143&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#FFB03A&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;background-clip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;transparent&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;You might be tempted to use the &lt;a href="https://dev.to/hadrysmateusz/the-fastest-way-to-set-css-backgrounds-3m2j"&gt;background shorthand&lt;/a&gt; here. Don’t.&lt;/p&gt;

&lt;p&gt;Unfortunately, the &lt;code&gt;background&lt;/code&gt; shorthand version of &lt;code&gt;background-clip&lt;/code&gt; doesn’t support the &lt;code&gt;text&lt;/code&gt; keyword.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fallback
&lt;/h2&gt;

&lt;p&gt;If you must support Internet Explorer, you'll have to fallback to a flat color. &lt;/p&gt;

&lt;p&gt;Wrap everything we've written before in an &lt;code&gt;@supports&lt;/code&gt; rule. This way it'll only be rendered in modern browsers.&lt;/p&gt;

&lt;p&gt;Then, outside of the &lt;code&gt;@supports&lt;/code&gt; block, set a fallback color for the text. It should probably be a color that appears in your gradient and works well with the rest of the design.&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;.gradient-text&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@supports&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;background-clip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nc"&gt;.gradient-text&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;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;60deg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#E21143&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;#FFB03A&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nl"&gt;background-clip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;transparent&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;Make sure the fallback comes before the actual gradient styles.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Even though the @supports rule itself is also not supported in IE, everything inside will still be ignored, which is exactly what we want.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;em&gt;Thanks for reading. I hope you learned something useful. If you have any questions, ask in the comments. &lt;a href="https://twitter.com/HadrysMateusz" rel="noopener noreferrer"&gt;Follow me&lt;/a&gt; for more web development tips.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Some other articles you might enjoy
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/hadrysmateusz/custom-list-styles-using-marker-before-4gi4"&gt;Easy Custom List Styles with Modern CSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hadrysmateusz/full-text-styling-with-a-single-line-of-css-3kbd"&gt;Full Text Styling with a Single Line of CSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/hadrysmateusz/how-to-use-multiple-versions-of-node-on-windows-1op9"&gt;How to Use Multiple Versions of NodeJS on Windows&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>css</category>
    </item>
    <item>
      <title>Ultimate Guide to CSS Gradients</title>
      <dc:creator>Mateusz Hadryś</dc:creator>
      <pubDate>Tue, 29 Dec 2020 18:57:02 +0000</pubDate>
      <link>https://dev.to/hadrysmateusz/complete-guide-to-css-gradients-1eck</link>
      <guid>https://dev.to/hadrysmateusz/complete-guide-to-css-gradients-1eck</guid>
      <description>&lt;p&gt;Gradients are back.&lt;/p&gt;

&lt;p&gt;They are bold, eye-catching, and playful. When used correctly they can breathe life into a drab and lifeless design.&lt;/p&gt;

&lt;p&gt;In this article, I'll show you how to create gradients in CSS, so you can make your websites stand out.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this article is about
&lt;/h2&gt;

&lt;p&gt;This article aims to explain both the syntax and concepts behind CSS gradients. Topics covered include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Linear &amp;amp; Radial gradient syntax&lt;/li&gt;
&lt;li&gt;What are color stops?&lt;/li&gt;
&lt;li&gt;Changing the direction of linear gradients&lt;/li&gt;
&lt;li&gt;How CSS angles work?&lt;/li&gt;
&lt;li&gt;Changing the size, shape &amp;amp; position of radial gradients&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But first, let's get one thing out of the way…&lt;/p&gt;

&lt;h2&gt;
  
  
  Gradients are Images in CSS
&lt;/h2&gt;

&lt;p&gt;For this reason, we need to set gradients as a &lt;code&gt;background-image&lt;/code&gt;. You might think it's obvious, but I had trouble remembering that at first.&lt;/p&gt;

&lt;p&gt;I used to try and set gradients as &lt;code&gt;background-color&lt;/code&gt; all the time. If you have trouble remembering this like me, use the &lt;a href="https://dev.to/hadrysmateusz/the-fastest-way-to-set-css-backgrounds-3m2j"&gt;background shorthand&lt;/a&gt;. &lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/hadrysmateusz" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F181202%2Ffe857a32-d940-4cdb-9d8f-719b165dc573.png" alt="hadrysmateusz"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/hadrysmateusz/the-fastest-way-to-set-css-backgrounds-3m2j" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Fastest Way to Set CSS Backgrounds&lt;/h2&gt;
      &lt;h3&gt;Mateusz Hadryś ・ Dec 21 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#css&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;It lets us use the same property for colors and images. Including gradients.&lt;/p&gt;

&lt;h1&gt;
  
  
  Linear Gradients
&lt;/h1&gt;

&lt;p&gt;A linear gradient is made up of two basic components: direction and color-stops.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9kzoiwd1r9rasaay6g9u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9kzoiwd1r9rasaay6g9u.png" alt="Linear gradient structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Color Stops
&lt;/h2&gt;

&lt;p&gt;Color stops define what colors make up the gradient and optionally, where to put them.&lt;/p&gt;

&lt;p&gt;We can add as many color stops as we want. By default, they'll be spaced evenly along the gradient line.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4b28kw8muor8eps5hrp8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4b28kw8muor8eps5hrp8.gif" alt="Default distribution of multiple color stops"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Color stops also allow us to set the starting position of each color manually. We do so by adding a percentage  (with &lt;code&gt;0%&lt;/code&gt; being the start of the gradient and &lt;code&gt;100%&lt;/code&gt; its end ) after the color.&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="c"&gt;/* The GIF below animates between these 3 gradients */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;linear-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;yellow&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;red&lt;/span&gt; &lt;span class="err"&gt;10&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="nt"&gt;blue&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;linear-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;yellow&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;red&lt;/span&gt; &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="nt"&gt;blue&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;linear-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;yellow&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;red&lt;/span&gt; &lt;span class="err"&gt;90&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="nt"&gt;blue&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fay8wtxkpe5igx0v28v7v.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fay8wtxkpe5igx0v28v7v.gif" alt="Gradient with 3 color stops, where the middle color stop animates between 3 positions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can also set an ending position for a color, if we want a color to take up more space.&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="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;linear-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;yellow&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;red&lt;/span&gt; &lt;span class="err"&gt;25&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="err"&gt;75&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="nt"&gt;blue&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftvfg1izzsbto45xod0nd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftvfg1izzsbto45xod0nd.png" alt="Gradient with 3 color stops, where the middle color stop spans from 25% to 75% of the gradient line"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are a few examples of manually positioned color stops&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="c"&gt;/* Automatic Positions */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;linear-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;lightpink&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;crimson&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;indigo&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c"&gt;/* Manual Starting Positions */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;linear-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;lightpink&lt;/span&gt; &lt;span class="err"&gt;40&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="nt"&gt;crimson&lt;/span&gt; &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="nt"&gt;indigo&lt;/span&gt; &lt;span class="err"&gt;60&lt;/span&gt;&lt;span class="o"&gt;%);&lt;/span&gt;

&lt;span class="c"&gt;/* Manual Starting &amp;amp; Ending Positions */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;linear-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;lightpink&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;20&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="nt"&gt;crimson&lt;/span&gt; &lt;span class="err"&gt;35&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="err"&gt;65&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="nt"&gt;indigo&lt;/span&gt; &lt;span class="err"&gt;80&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp6fegzo3b985zovafenj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fp6fegzo3b985zovafenj.png" alt="3 gradients with 3 color stops each, where the first one is a smooth transition between all, the second has the middle color stop as a thin line in the middle, and the third has the middle color spanning the majority of the gradient area"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Direction
&lt;/h2&gt;

&lt;p&gt;By default, a gradient goes from top to bottom.&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="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;linear-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;yellow&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;red&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5xkali1yml4gltb2g7lb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5xkali1yml4gltb2g7lb.png" alt="a gradient with yellow on top and red at the bottom"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To get a gradient going from one side to the opposite side, write &lt;code&gt;to *&lt;/code&gt;, where &lt;code&gt;*&lt;/code&gt; is one of four keywords: &lt;code&gt;top&lt;/code&gt;, &lt;code&gt;bottom&lt;/code&gt;, &lt;code&gt;left&lt;/code&gt;, and &lt;code&gt;right&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example: &lt;code&gt;to left&lt;/code&gt; gives us a right-to-left gradient.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fznxxbgnq7ssozj6q8uaq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fznxxbgnq7ssozj6q8uaq.png" alt="4 boxes showing gradients going to four sides"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By using two keywords, we get a gradient going from one corner to the opposite corner.&lt;/p&gt;

&lt;p&gt;For example: &lt;code&gt;to bottom right&lt;/code&gt; gives us a gradient going from the top-left to the bottom-right corner.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk8lj8yfjobdigu6rbbxs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fk8lj8yfjobdigu6rbbxs.png" alt="4 boxes showing gradients going to four corners"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you need more precision than side-to-side or corner-to-corner, you can specify a custom angle.&lt;/p&gt;
&lt;h3&gt;
  
  
  CSS Angles
&lt;/h3&gt;

&lt;p&gt;There are four different &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/angle#Units" rel="noopener noreferrer"&gt;angle units&lt;/a&gt; in CSS, but we're only going to focus on two: degrees &lt;code&gt;deg&lt;/code&gt; and turns &lt;code&gt;turn&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Degrees&lt;/strong&gt; - a value from 0 to 360 with a &lt;code&gt;deg&lt;/code&gt; unit, where &lt;code&gt;0deg&lt;/code&gt; = &lt;code&gt;to top&lt;/code&gt;, &lt;code&gt;90deg&lt;/code&gt; = &lt;code&gt;to right&lt;/code&gt;, etc.&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="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;linear-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;150&lt;/span&gt;&lt;span class="nt"&gt;deg&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;yellow&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;red&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgs7uwlu7yutbmxjp925h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgs7uwlu7yutbmxjp925h.png" alt="150 degree gradient"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Turns&lt;/strong&gt; are exactly what they sound like: 360 degree turns. This means that: &lt;code&gt;0.5turn&lt;/code&gt; = &lt;code&gt;180deg&lt;/code&gt;, &lt;code&gt;0.25turn&lt;/code&gt; = &lt;code&gt;90deg&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;There's one thing you need to remember. CSS angles work differently than the ones you remember from school. They resemble a clock. Starting at the top and going clockwise.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flfcbfheooqd4x8h1zq57.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flfcbfheooqd4x8h1zq57.gif" alt="animation showing how a gradient looks for every angle"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The gradient's direction is indicated by the spinning arm. The corresponding angle in degrees is shown in the center.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Negative Angles
&lt;/h3&gt;

&lt;p&gt;An angle can also be a negative number, like: &lt;code&gt;-90deg&lt;/code&gt; or &lt;code&gt;-0.25turn&lt;/code&gt;. Negative values represent counter-clockwise angles. So for example &lt;code&gt;-45deg&lt;/code&gt; is the same as &lt;code&gt;315deg&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1341791778521948161-227" src="https://platform.twitter.com/embed/Tweet.html?id=1341791778521948161"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1341791778521948161-227');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1341791778521948161&amp;amp;theme=dark"
  }



&lt;/p&gt;
&lt;h1&gt;
  
  
  Radial Gradients
&lt;/h1&gt;

&lt;p&gt;Radial gradients are different from linear gradients in one important way. Instead of progressing in a straight line, the colors radiate outwards from a single point.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhox3hw7thltaij91cdly.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhox3hw7thltaij91cdly.png" alt="radial gradient structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The area of a radial gradient is defined by the origin point's &lt;strong&gt;position&lt;/strong&gt;, the ending &lt;strong&gt;shape&lt;/strong&gt;, and its &lt;strong&gt;size&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu41uak26bquufr4ez55j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fu41uak26bquufr4ez55j.png" alt="default gradient area"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's look at these three components in more detail.&lt;/p&gt;
&lt;h3&gt;
  
  
  Position
&lt;/h3&gt;

&lt;p&gt;By default, the origin point is in the center of the element. We can change that by writing &lt;code&gt;at *&lt;/code&gt;, where &lt;code&gt;*&lt;/code&gt; is one or two length or percentage values indicating the origin point's coordinates.&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="c"&gt;/* These two declarations do the same */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;radial-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;at&lt;/span&gt; &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="nt"&gt;yellow&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;red&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;radial-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;at&lt;/span&gt; &lt;span class="nt"&gt;bottom&lt;/span&gt; &lt;span class="nt"&gt;right&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;yellow&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;red&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F86sheqccgxoxf25zirmg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F86sheqccgxoxf25zirmg.png" alt="radial gradient starting in the bottom right corner"&gt;&lt;/a&gt;&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="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;radial-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;at&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;70&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="nt"&gt;yellow&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;red&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fub7uqhskeja867xpwii1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fub7uqhskeja867xpwii1.png" alt="radial gradient starting near the bottom left corner"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Setting the origin's position works exactly like the &lt;code&gt;background-position&lt;/code&gt; property. You can read more about it in the article below.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/hadrysmateusz" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F181202%2Ffe857a32-d940-4cdb-9d8f-719b165dc573.png" alt="hadrysmateusz"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/hadrysmateusz/learn-all-8-background-css-properties-in-5-minutes-2lk4" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;All CSS Background Properties Explained in 5 Minutes&lt;/h2&gt;
      &lt;h3&gt;Mateusz Hadryś ・ Dec 16 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#css&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;h3&gt;
  
  
  Shape
&lt;/h3&gt;

&lt;p&gt;By default, the gradient spans the entire area of the element. This means that if the element is not a square, the gradient will stretch and become an ellipse.&lt;/p&gt;

&lt;p&gt;If we want the gradient to stay a circle - regardless of the container's proportions - we need to set the gradient's shape to &lt;code&gt;circle&lt;/code&gt;.&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="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;radial-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;circle&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;yellow&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;red&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fogjcgtq5v74vijwhv7dp.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fogjcgtq5v74vijwhv7dp.gif" alt="animation showing how circle and ellipse gradients change when the element's proportions change"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;color-stop positions are adjusted in this example to better illustrate the differences&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Size
&lt;/h3&gt;

&lt;p&gt;The ending shape's size is defined by where its edge meets the element.&lt;/p&gt;

&lt;p&gt;Which part of the element? That can be set with one of four keywords: &lt;code&gt;closest-side&lt;/code&gt;, &lt;code&gt;closest-corner&lt;/code&gt;, &lt;code&gt;farthest-side&lt;/code&gt;, and &lt;code&gt;farthest-corner&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can see all size &amp;amp; shape combinations below. The gradient area is marked using light ellipses and circles, and the 0% and 100% points are marked with a dark arrow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzd5hfz2cnqmpwsgblfuw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fzd5hfz2cnqmpwsgblfuw.gif" alt="a table showing all combinations of size &amp;amp; shapes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Even though farthest-corner and closest-corner might look identical, they produce very different results when the origin position is not in the center.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We can also specify an absolute value for the ending shape's size, using a length value (radius) in case of circles and two percentages (horizontal and vertical radius) in case of an ellipse.&lt;/p&gt;

&lt;h3&gt;
  
  
  Putting it all together
&lt;/h3&gt;

&lt;p&gt;We can combine changing the shape, size, and position. All three values make up the first parameter of &lt;code&gt;radial-gradient()&lt;/code&gt;. That's why we only put one comma after them.&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="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;radial-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;circle&lt;/span&gt; &lt;span class="nt"&gt;closest-side&lt;/span&gt; &lt;span class="nt"&gt;at&lt;/span&gt; &lt;span class="nt"&gt;bottom&lt;/span&gt; &lt;span class="nt"&gt;right&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;yellow&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;red&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All three values are optional and default to: &lt;code&gt;ellipse farthest-corner at center center&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here are a few examples of radial gradients, for you to get used to the syntax:&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="c"&gt;/* A */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;radial-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;lightpink&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;crimson&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;indigo&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="c"&gt;/* B */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;radial-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;closest-side&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;lightpink&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;crimson&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;indigo&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="c"&gt;/* C */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;radial-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;closest-side&lt;/span&gt; &lt;span class="nt"&gt;at&lt;/span&gt; &lt;span class="err"&gt;40&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="err"&gt;65&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="nt"&gt;lightpink&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;crimson&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;indigo&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fio9mvrf6scf6cdc4bbsu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fio9mvrf6scf6cdc4bbsu.png" alt="3 elliptical gradients"&gt;&lt;/a&gt;&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="c"&gt;/* D */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;radial-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;circle&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;lightpink&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;crimson&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;indigo&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="c"&gt;/* E */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;radial-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;circle&lt;/span&gt; &lt;span class="nt"&gt;closest-side&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;lightpink&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;crimson&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;indigo&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="c"&gt;/* F */&lt;/span&gt;
&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;radial-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;circle&lt;/span&gt; &lt;span class="err"&gt;120&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="nt"&gt;at&lt;/span&gt; &lt;span class="err"&gt;30&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="err"&gt;75&lt;/span&gt;&lt;span class="o"&gt;%,&lt;/span&gt; &lt;span class="nt"&gt;lightpink&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;crimson&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;indigo&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc5068geyjc6v2lehsxmw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fc5068geyjc6v2lehsxmw.png" alt="3 circular gradients"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This should be enough to craft almost any gradient you want. &lt;/p&gt;

&lt;p&gt;A few more advanced bits of info as well as conic and repeating gradients will be discussed in part 2. &lt;a href="https://twitter.com/HadrysMateusz" rel="noopener noreferrer"&gt;Follow me on Twitter&lt;/a&gt; to be notified when it's released.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks for reading. I hope you learned something useful. If you have any questions, ask in the comments. Follow me for more web development tips.&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Some other articles you might enjoy
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/hadrysmateusz/gradient-text-in-css-38g6"&gt;Create Gradient Text in CSS&lt;/a&gt; 🌈&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/hadrysmateusz/custom-list-styles-using-marker-before-4gi4"&gt;Easy Custom List Styles with Modern CSS&lt;/a&gt; 🎨&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/hadrysmateusz/full-text-styling-with-a-single-line-of-css-3kbd"&gt;Full Text Styling with a Single Line of CSS&lt;/a&gt; ✍&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>css</category>
      <category>tutorial</category>
      <category>webdev</category>
      <category>design</category>
    </item>
    <item>
      <title>Fastest Way to Set CSS Backgrounds</title>
      <dc:creator>Mateusz Hadryś</dc:creator>
      <pubDate>Mon, 21 Dec 2020 16:36:27 +0000</pubDate>
      <link>https://dev.to/hadrysmateusz/the-fastest-way-to-set-css-backgrounds-3m2j</link>
      <guid>https://dev.to/hadrysmateusz/the-fastest-way-to-set-css-backgrounds-3m2j</guid>
      <description>&lt;p&gt;Speed is essential in web development. Especially when prototyping. &lt;/p&gt;

&lt;p&gt;If you're not a 150WPM typing ninja, adding a background can be time consuming. And let's be honest...&lt;/p&gt;

&lt;p&gt;Who wants to type &lt;code&gt;background-*: value;&lt;/code&gt; &lt;strong&gt;8 times&lt;/strong&gt;?&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="nt"&gt;background-attachment&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;scroll&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;background-origin&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;padding-box&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;background-clip&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;border-box&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;background-color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;transparent&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;background-image&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;none&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;background-position&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="nt"&gt;background-size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;auto&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;background-repeat&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;repeat&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That's a lot of typing, and a lot of space. We can use the background shorthand to turn all of that into a single line:&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="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;scroll&lt;/span&gt; &lt;span class="nt"&gt;padding-box&lt;/span&gt; &lt;span class="nt"&gt;border-box&lt;/span&gt; &lt;span class="nt"&gt;transparent&lt;/span&gt; &lt;span class="nt"&gt;none&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="nt"&gt;auto&lt;/span&gt; &lt;span class="nt"&gt;repeat&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Neat, huh?&lt;/p&gt;

&lt;p&gt;In this article I want to show you how this shorthand works, and the rules you need to follow for it to work.&lt;/p&gt;

&lt;p&gt;If you're not familiar with all of the properties above, please take a minute to read my quick introduction to &lt;a href="https://dev.to/hadrysmateusz/learn-all-8-background-css-properties-in-5-minutes-2lk4"&gt;background properties&lt;/a&gt; before reading this article. It will help you understand what's going on.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/hadrysmateusz" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F181202%2Ffe857a32-d940-4cdb-9d8f-719b165dc573.png" alt="hadrysmateusz"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/hadrysmateusz/learn-all-8-background-css-properties-in-5-minutes-2lk4" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;All CSS Background Properties Explained in 5 Minutes&lt;/h2&gt;
      &lt;h3&gt;Mateusz Hadryś ・ Dec 16 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#css&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;h1&gt;
  
  
  Required Properties
&lt;/h1&gt;

&lt;p&gt;You might be thinking to yourself now:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Okay, it's nice that they're on the same line. But do I still need to write all of these values?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;No. Unlike the &lt;a href="https://dev.to/hadrysmateusz/full-text-styling-with-a-single-line-of-css-3kbd"&gt;font shorthand&lt;/a&gt;, all properties in the background shorthand are optional.&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/hadrysmateusz" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F181202%2Ffe857a32-d940-4cdb-9d8f-719b165dc573.png" alt="hadrysmateusz"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/hadrysmateusz/full-text-styling-with-a-single-line-of-css-3kbd" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Full Text Styling With a Single Line of CSS&lt;/h2&gt;
      &lt;h3&gt;Mateusz Hadryś ・ Nov 11 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#css&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Be careful though.&lt;/p&gt;

&lt;p&gt;If you don’t include a value for one of the properties, its default value will be used. Even if you’ve defined that property earlier.&lt;/p&gt;

&lt;h1&gt;
  
  
  Order of Properties
&lt;/h1&gt;

&lt;p&gt;The order of properties doesn't matter. With a few small exceptions:&lt;/p&gt;

&lt;h2&gt;
  
  
  Position &amp;amp; Size
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;background-size&lt;/code&gt; can only come immediately after &lt;code&gt;background-position&lt;/code&gt;, and the two have to be separated with a slash (&lt;code&gt;/&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fg0xj7qfjtwl8iqz07p2n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fg0xj7qfjtwl8iqz07p2n.png" alt="Position &amp;amp; Size Cheatsheet"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This means you can't set &lt;code&gt;background-size&lt;/code&gt; without &lt;code&gt;background-position&lt;/code&gt; using this shorthand. &lt;/p&gt;

&lt;p&gt;There are two ways to work around that though:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use the default &lt;code&gt;background-position&lt;/code&gt; value, which is: &lt;code&gt;0% 0%&lt;/code&gt;. For example &lt;code&gt;0% 0%/50%&lt;/code&gt; would set &lt;code&gt;background-size&lt;/code&gt; to &lt;code&gt;50%&lt;/code&gt; and keep &lt;code&gt;background-position&lt;/code&gt; unchanged.&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;background-size&lt;/code&gt; separately after the background shorthand. Like this:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;"cat.png"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;background-size&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;50&lt;/span&gt;&lt;span class="o"&gt;%;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;IMPORTANT:&lt;/strong&gt; If you try setting &lt;code&gt;background-size&lt;/code&gt;  in the shorthand using one of its keywords (&lt;code&gt;cover&lt;/code&gt; or &lt;code&gt;contain&lt;/code&gt;) without the &lt;code&gt;background-position&lt;/code&gt; the whole &lt;code&gt;background&lt;/code&gt; property will be treated as invalid and ignored.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  📦 Origin &amp;amp; Clip
&lt;/h2&gt;

&lt;p&gt;Because the values of &lt;code&gt;background-origin&lt;/code&gt; and &lt;code&gt;background-clip&lt;/code&gt; heavily overlap...&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;border-box&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;padding-box&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;content-box&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;text&lt;/code&gt; - This one's the exception. It's available only for &lt;code&gt;background-clip&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...setting them using the shorthand works a bit differently. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fykg06pex55dk8njut2y7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fykg06pex55dk8njut2y7.png" alt="Origin &amp;amp; Clip Cheatsheet"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you only include one of the box values, it will be used for both &lt;code&gt;background-origin&lt;/code&gt; and &lt;code&gt;background-clip&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;If you include two, the first one will be used for &lt;code&gt;background-origin&lt;/code&gt; and the second one for &lt;code&gt;background-clip&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;If you don't use any, both properties will keep their default values.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbarelj3ftz0jm0uxgk5u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fbarelj3ftz0jm0uxgk5u.png" alt="Origin &amp;amp; Clip Example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is why I've labeled them as &lt;strong&gt;box&lt;/strong&gt; in the images.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; As far as I know, &lt;code&gt;background-clip&lt;/code&gt;'s &lt;code&gt;text&lt;/code&gt; value is not supported by the background shorthand. So if you want to create &lt;a href="https://dev.to/hadrysmateusz/gradient-text-in-css-38g6"&gt;gradient text&lt;/a&gt;, you will have to set &lt;code&gt;background-clip&lt;/code&gt; separately.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Multi Value Syntax
&lt;/h2&gt;

&lt;p&gt;A few of the background properties can accept more than one value. It's important to keep those values next to each other and in the correct order.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;background-size&lt;/code&gt;&lt;/strong&gt; - If two values are provided, the first sets the width of the image, and the second its height.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;background-repeat&lt;/code&gt;&lt;/strong&gt; - If two values are provided, the first sets the repeat behavior for the horizontal (x) axis, and the second for the vertical (y) axis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;background-position&lt;/code&gt;&lt;/strong&gt; - If two values are provided, the first controls the image's horizontal position, and the second its vertical position.&lt;/p&gt;
&lt;h1&gt;
  
  
  🎨 Color &amp;amp; Image
&lt;/h1&gt;

&lt;p&gt;The background shorthand allows you to set a color or image as a background. You can even set both.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdrt7yag1ia74luims8ft.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fdrt7yag1ia74luims8ft.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Wait, why would I need both?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Setting a fallback &lt;code&gt;background-color&lt;/code&gt; can be useful in many cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the image URL is broken or the image takes a long time to load, the background color can be a good placeholder.&lt;/li&gt;
&lt;li&gt;If the image contains transparency the background color will be visible underneath.&lt;/li&gt;
&lt;li&gt;If the value of &lt;code&gt;background-repeat&lt;/code&gt; is other than &lt;code&gt;repeat&lt;/code&gt; or &lt;code&gt;round&lt;/code&gt;, there are likely to be areas not covered by the image. Those areas will be filled with the background color. You can see this above, in the &lt;code&gt;background-repeat&lt;/code&gt; example image.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Gradients
&lt;/h2&gt;

&lt;p&gt;Have you ever tried to set a &lt;a href="https://dev.to/hadrysmateusz/complete-guide-to-css-gradients-1eck"&gt;gradient&lt;/a&gt; as the &lt;code&gt;background-color&lt;/code&gt;, only to be surprised that it doesn't work?&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/hadrysmateusz" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F181202%2Ffe857a32-d940-4cdb-9d8f-719b165dc573.png" alt="hadrysmateusz"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/hadrysmateusz/complete-guide-to-css-gradients-1eck" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Ultimate Guide to CSS Gradients&lt;/h2&gt;
      &lt;h3&gt;Mateusz Hadryś ・ Dec 29 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#css&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#design&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;p&gt;That's because gradients are images in CSS. This is where the background shorthand comes in handy.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1341050093722603521-607" src="https://platform.twitter.com/embed/Tweet.html?id=1341050093722603521"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1341050093722603521-607');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1341050093722603521&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h1&gt;
  
  
  Layers
&lt;/h1&gt;

&lt;p&gt;Just like all other &lt;code&gt;background-*&lt;/code&gt; properties, the &lt;code&gt;background&lt;/code&gt; shorthand can accept multiple comma-separated layers.&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="nt"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;cat&lt;/span&gt;&lt;span class="nc"&gt;.png&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;no-repeat&lt;/span&gt; &lt;span class="nt"&gt;scroll&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
            &lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;grass-texture&lt;/span&gt;&lt;span class="nc"&gt;.jpg&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;repeat&lt;/span&gt; &lt;span class="nt"&gt;local&lt;/span&gt; &lt;span class="nt"&gt;green&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is just one thing you have to keep in mind. An element can only have one &lt;code&gt;background-color&lt;/code&gt;, and it has to be on the last (bottom) layer. Otherwise the entire property will be treated as invalid.&lt;/p&gt;

&lt;h1&gt;
  
  
  Cheatsheet
&lt;/h1&gt;

&lt;p&gt;If you ever need a reminder, here’s a handy cheatsheet 😃&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0luug0s4x0m5rp0r4eti.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0luug0s4x0m5rp0r4eti.png" alt="Full Background Shorthand Cheatsheet"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks for reading. I hope you learned something useful. If you have any questions, ask in the comments. &lt;a href="https://twitter.com/HadrysMateusz" rel="noopener noreferrer"&gt;Follow me&lt;/a&gt; for more web development tips.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Another article you might enjoy
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Some other articles you might enjoy
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/hadrysmateusz/custom-list-styles-using-marker-before-4gi4"&gt;Easy Custom List Styles with Modern CSS&lt;/a&gt; 🎨&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/hadrysmateusz/gradient-text-in-css-38g6"&gt;Create Gradient Text in CSS&lt;/a&gt; 🌈&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/hadrysmateusz/full-text-styling-with-a-single-line-of-css-3kbd"&gt;Full Text Styling with a Single Line of CSS&lt;/a&gt; ✍&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>css</category>
    </item>
    <item>
      <title>All CSS Background Properties Explained in 5 Minutes</title>
      <dc:creator>Mateusz Hadryś</dc:creator>
      <pubDate>Wed, 16 Dec 2020 21:02:22 +0000</pubDate>
      <link>https://dev.to/hadrysmateusz/learn-all-8-background-css-properties-in-5-minutes-2lk4</link>
      <guid>https://dev.to/hadrysmateusz/learn-all-8-background-css-properties-in-5-minutes-2lk4</guid>
      <description>&lt;p&gt;I remember when I first tried setting an image background in CSS.&lt;/p&gt;

&lt;p&gt;What I thought would be a simple task took me down a rabbit hole of learning 8 different &lt;code&gt;background-*&lt;/code&gt; properties. It took me hours to figure out what they all did and how they interacted.&lt;/p&gt;

&lt;p&gt;Now, I want to teach you everything you need to know about CSS background. In minutes instead of hours.&lt;/p&gt;

&lt;h1&gt;
  
  
  🎨 Color
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Property:&lt;/strong&gt; &lt;code&gt;background-color&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Default Value:&lt;/strong&gt; &lt;code&gt;transparent&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The most commonly used background property. It lets us change the color of an element's background.&lt;/p&gt;

&lt;p&gt;The color can be specified using rgb, hsl or hex notation.&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="c"&gt;/* Without Transparency */&lt;/span&gt;
&lt;span class="nt"&gt;background-color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;rgb&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;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;background-color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;hsl&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;0&lt;/span&gt;&lt;span class="o"&gt;%);&lt;/span&gt;
&lt;span class="nt"&gt;background-color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#000000&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;/* With 50% Transparency */&lt;/span&gt;
&lt;span class="nt"&gt;background-color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;rgba&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;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;5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;background-color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;hsla&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;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;5&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;background-color&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;#0000007&lt;/span&gt;&lt;span class="nt"&gt;F&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can also use one of the &lt;a href="https://htmlcolorcodes.com/color-names/" rel="noopener noreferrer"&gt;140 predefined colors&lt;/a&gt;, or the &lt;code&gt;transparent&lt;/code&gt; keyword.&lt;/p&gt;
&lt;h1&gt;
  
  
  📷 Image
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Property:&lt;/strong&gt; &lt;code&gt;background-image&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Default Value:&lt;/strong&gt; &lt;code&gt;none&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The star of the show. Almost all other background properties modify it in some way.&lt;/p&gt;

&lt;p&gt;It allows us to set an image as the element's background. &lt;/p&gt;

&lt;p&gt;To do it, use the &lt;code&gt;url()&lt;/code&gt; function with a relative or absolute URL as its parameter. The URL should be wrapped in quotes &lt;code&gt;"&lt;/code&gt; or apostrophes &lt;code&gt;'&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When you choose to go with a relative URL, remember that it's relative to the stylesheet, not the webpage.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;background-image&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;"image.png"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;But why can't we just write the URL without some fancy &lt;em&gt;function&lt;/em&gt;? Because there are other image sources in CSS. For example: &lt;a href="https://dev.to/hadrysmateusz/complete-guide-to-css-gradients-1eck"&gt;gradients&lt;/a&gt;.&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="nt"&gt;background-image&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;linear-gradient&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;red&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nt"&gt;yellow&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Yeah, gradients are images in CSS. If you find this hard to remember like me, use the &lt;a href="https://dev.to/hadrysmateusz/the-fastest-way-to-set-css-backgrounds-3m2j"&gt;background shorthand&lt;/a&gt;. It does the remembering for you 😄&lt;/p&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/hadrysmateusz" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F181202%2Ffe857a32-d940-4cdb-9d8f-719b165dc573.png" alt="hadrysmateusz"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/hadrysmateusz/the-fastest-way-to-set-css-backgrounds-3m2j" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Fastest Way to Set CSS Backgrounds&lt;/h2&gt;
      &lt;h3&gt;Mateusz Hadryś ・ Dec 21 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#css&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;h1&gt;
  
  
  Repeat
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Property:&lt;/strong&gt; &lt;code&gt;background-repeat&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Default Value:&lt;/strong&gt; &lt;code&gt;repeat&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;background-repeat&lt;/code&gt; determines what happens, if the image is smaller than the element it serves as a background for.&lt;/p&gt;

&lt;p&gt;The possible values of &lt;code&gt;background-repeat&lt;/code&gt; are better shown than told:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkw6a4mxpbpjd5xf7ofbq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkw6a4mxpbpjd5xf7ofbq.png" alt="Example showing the different background-repeat values"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Size
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Property:&lt;/strong&gt; &lt;code&gt;background-size&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Default Value:&lt;/strong&gt; &lt;code&gt;auto auto&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This property controls the size of the background image. Most of the time it's used with one of two keywords:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;cover&lt;/code&gt; - It fills (covers) the entire area of the element with the image, without stretching. Even if it means that parts of the image won't be visible.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;contain&lt;/code&gt; - The opposite of &lt;code&gt;cover&lt;/code&gt;. It makes sure that the entire image fits (is contained) in the element, without squashing. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unless &lt;code&gt;background-size&lt;/code&gt; is set to &lt;code&gt;no-repeat&lt;/code&gt;, setting &lt;code&gt;background-size: contain&lt;/code&gt; will result in image tiling.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3ycusgy7k8yzctvxp6sw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3ycusgy7k8yzctvxp6sw.png" alt="Example showing how the cover and contain values work"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The value of &lt;code&gt;background-size&lt;/code&gt; can also be a percentage or length (&lt;code&gt;px&lt;/code&gt;,&lt;code&gt;cm&lt;/code&gt;,&lt;code&gt;em&lt;/code&gt; etc.).&lt;/p&gt;

&lt;p&gt;A percentage value is relative to the element's size, or more specifically the area specified by &lt;code&gt;background-origin&lt;/code&gt;. More on that property later.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;background-size&lt;/code&gt; can be set using a &lt;strong&gt;one-value&lt;/strong&gt; or &lt;strong&gt;two-value&lt;/strong&gt; syntax.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When only one value is provided, it sets the image's width. Height is set automatically to preserve proportions.&lt;/li&gt;
&lt;li&gt;When two values are provided, the first one sets the width, and the second sets the height. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When using two values, the image might get stretched. To prevent stretching, set one value using a length/percentage and the other using the &lt;code&gt;auto&lt;/code&gt; keyword.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcmp50zyl3xdkeremylvd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fcmp50zyl3xdkeremylvd.png" alt="Six example values for background-size"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Position
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Property:&lt;/strong&gt; &lt;code&gt;background-position&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Default Value:&lt;/strong&gt; &lt;code&gt;0% 0%&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Maybe you've noticed that when we change an element's size, it stays glued to the top-left corner. We can change that by using &lt;code&gt;background-position&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There are four keywords we can use: &lt;code&gt;top&lt;/code&gt;, &lt;code&gt;bottom&lt;/code&gt;, &lt;code&gt;left&lt;/code&gt;, and &lt;code&gt;right&lt;/code&gt;. As well as any length or percentage value.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3hirghs6ih0bj6ojuln7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3hirghs6ih0bj6ojuln7.gif" alt="Animated example showing many possible background-position values"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just like &lt;code&gt;background-size&lt;/code&gt;, we can use a &lt;strong&gt;one-value&lt;/strong&gt; or &lt;strong&gt;two-value&lt;/strong&gt; syntax.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When using one value, it sets the image's horizontal (x-axis) position. The vertical (y-axis) position defaults to 50%.&lt;/li&gt;
&lt;li&gt;When using two values, the first sets the horizontal position and the second: vertical.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Length values set the distance of the image's top-left corner from the element's top-left corner. Percentage and keyword values set the position of the image's mid-point on a given axis.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Combining &lt;code&gt;background-position: center&lt;/code&gt; with &lt;code&gt;background-size: cover&lt;/code&gt; or &lt;code&gt;contain&lt;/code&gt; is an easy way to achieve responsive images, that scale well with the element and the page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqyu1ghsesmpsd0xitdr2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqyu1ghsesmpsd0xitdr2.gif" alt="Animated example showing how cover and contain combined with background-position: center react to resizing"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Attachment
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Property:&lt;/strong&gt; &lt;code&gt;background-attachment&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Default Value:&lt;/strong&gt; &lt;code&gt;scroll&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;background-attachment&lt;/code&gt; allows you to control how your background image reacts to scrolling. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Possible values are&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;scroll&lt;/code&gt; - Scrolls with the page, but not with the element's contents.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fixed&lt;/code&gt; - Fixed to the viewport. Acts like a window to something behind the page.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;local&lt;/code&gt; - Scrolls with the page and the element's contents.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're confused by that, don't worry. It's tricky to understand without examples. Play around with the demo below until you get a better feeling for how this property works.&lt;/p&gt;

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

&lt;h1&gt;
  
  
  Origin
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Property:&lt;/strong&gt; &lt;code&gt;background-origin&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Default Value:&lt;/strong&gt; &lt;code&gt;padding-box&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This property sets the background's origin. It uses three keywords:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;border-box&lt;/code&gt; -  The background starts at the outer edge of the border. It goes under it, which you can see if the border is semi-transparent, &lt;code&gt;dashed&lt;/code&gt;, or &lt;code&gt;dotted&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;padding-box&lt;/code&gt; - The background starts at the inner edge of the border.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;content-box&lt;/code&gt; - The background starts where the element's content does.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frgydlk4wvxm66jq5ogx6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frgydlk4wvxm66jq5ogx6.png" alt="3 Images showing the effects of different background-origin values"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Both &lt;code&gt;background-position&lt;/code&gt; and &lt;code&gt;background-size&lt;/code&gt; are relative to the box set by this property.&lt;/p&gt;
&lt;h1&gt;
  
  
  Clip
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Property:&lt;/strong&gt; &lt;code&gt;background-clip&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;Default Value:&lt;/strong&gt; &lt;code&gt;border-box&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Even though &lt;code&gt;background-clip&lt;/code&gt; shares most of its values with &lt;code&gt;background-origin&lt;/code&gt; and their results might look similar, they are actually quite different.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuz9fbg0jffncnkxv30lu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuz9fbg0jffncnkxv30lu.png" alt="4 Images showing the effects of different background-clip values"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This property doesn't modify the position of the background in any way. &lt;/p&gt;

&lt;p&gt;It &lt;strong&gt;clips&lt;/strong&gt; the background to the selected box. This means that any parts of the background outside the area set by this property will not be visible.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;border-box&lt;/code&gt; -  The background is clipped to the outer edge of the border. It will be visible under the border, padding and content.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;padding-box&lt;/code&gt; - The background is clipped to the inner edge of the border. It will be visible under the padding and content.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;content-box&lt;/code&gt; - The background is clipped to the content area. It will only be visible under the element's content.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;text&lt;/code&gt; - The background will only be visible under the element's text content. Make sure to set &lt;code&gt;color: transparent&lt;/code&gt; to see the background. This can be used to achieve some cool effects like: &lt;a href="https://dev.to/hadrysmateusz/gradient-text-in-css-38g6"&gt;gradient text&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; If the area set by &lt;code&gt;background-clip&lt;/code&gt; is smaller than the one set by &lt;code&gt;background-origin&lt;/code&gt; the outer parts of the image will be cut off. Make sure there's nothing important there.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;
  
  
  Layers
&lt;/h1&gt;

&lt;p&gt;All background properties, except &lt;code&gt;background-color&lt;/code&gt; accept multiple values, separated by commas. That's because every element can have multiple background layers.&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="nt"&gt;background-image&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;cat&lt;/span&gt;&lt;span class="nc"&gt;.png&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="nt"&gt;url&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;grass-texture&lt;/span&gt;&lt;span class="nc"&gt;.jpg&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nt"&gt;background-repeat&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;no-repeat&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;repeat&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;background-attachment&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;scroll&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;local&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="nt"&gt;background-image&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;green&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first (leftmost) value corresponds to the top layer. The last (rightmost) value, is the bottom layer.&lt;/p&gt;

&lt;p&gt;But managing layers across multiple properties can get messy pretty quickly. For example: &lt;em&gt;What if you decide to add another image layer at the top of the layer stack but forget to update other `background-&lt;/em&gt;` properties?*&lt;/p&gt;

&lt;p&gt;This problem can be prevented by using the &lt;a href="https://dev.to/hadrysmateusz/the-fastest-way-to-set-css-backgrounds-3m2j"&gt;background shorthand&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;I hope this introduction made this topic easier to understand, and can serve as a reference, if you ever need a refresher.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks for reading. If you have any questions, ask in the comments. &lt;a href="https://twitter.com/HadrysMateusz" rel="noopener noreferrer"&gt;Follow me&lt;/a&gt; for more web development tips.&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Other articles you might enjoy
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/hadrysmateusz/complete-guide-to-css-gradients-1eck"&gt;CSS Gradients, Ultimate Guide&lt;/a&gt; 🎓&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/hadrysmateusz/custom-list-styles-using-marker-before-4gi4"&gt;Easy Custom List Styles with Modern CSS&lt;/a&gt; 🎨&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://dev.to/hadrysmateusz/gradient-text-in-css-38g6"&gt;Create Gradient Text in CSS&lt;/a&gt; 🌈&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Full Text Styling With a Single Line of CSS</title>
      <dc:creator>Mateusz Hadryś</dc:creator>
      <pubDate>Wed, 11 Nov 2020 16:26:06 +0000</pubDate>
      <link>https://dev.to/hadrysmateusz/full-text-styling-with-a-single-line-of-css-3kbd</link>
      <guid>https://dev.to/hadrysmateusz/full-text-styling-with-a-single-line-of-css-3kbd</guid>
      <description>&lt;p&gt;Am I the only one who always thought the font shorthand was too confusing to use?&lt;/p&gt;

&lt;p&gt;Well, I finally decided to start using it.&lt;/p&gt;

&lt;p&gt;Now I want to share with you what I've learned. All the quirks, gotchas and use-cases.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It's a very useful tool, if you're willing to play by its rules.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h1&gt;
  
  
  What does it do?
&lt;/h1&gt;

&lt;p&gt;The font shorthand allows you to set almost all font-related properties with a single line of CSS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Including:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;font-style&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;font-variant&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;font-weight&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;font-size&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;line-height&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;font-family&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;font-stretch&lt;/code&gt; - this one is not used as often, and won't be discussed in this article&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Required properties
&lt;/h1&gt;

&lt;p&gt;Out of these, only &lt;code&gt;font-size&lt;/code&gt; and &lt;code&gt;font-family&lt;/code&gt; are required. If you omit either, the whole line will be ignored. All other properties can be omitted.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--N_-jHml1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hnj8vpx47qi39rc1enzo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--N_-jHml1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/hnj8vpx47qi39rc1enzo.png" alt="Optional &amp;amp; required properties" width="880" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Be careful though.&lt;/p&gt;

&lt;p&gt;If you don't specify a property, it will be reset to its default value. Even if you've defined that property earlier. Including in a parent element.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;font-kerning&lt;/code&gt; and &lt;code&gt;font-size-adjust&lt;/code&gt; will also be reset by this shorthand, even though they can't be set by it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Order of Properties
&lt;/h1&gt;

&lt;p&gt;The order of properties allows for some flexibility, but there are a few rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Style, Variant &amp;amp; Weight
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;font-style&lt;/code&gt;, &lt;code&gt;font-variant&lt;/code&gt;, and &lt;code&gt;font-weight&lt;/code&gt; have to come before &lt;code&gt;font-size&lt;/code&gt;. Their individual order doesn't matter though.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9fav159J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/x4hh1lx8naf4v9mn8ztq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9fav159J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/x4hh1lx8naf4v9mn8ztq.png" alt="Style, variant, and weight properties" width="880" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you don't remember what these properties do, here's a quick reminder:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;font-style&lt;/code&gt; - allows you to choose between &lt;code&gt;normal&lt;/code&gt;, &lt;code&gt;italic&lt;/code&gt;, and &lt;code&gt;oblique&lt;/code&gt; styles of the font. Oblique is basically the same as italic but uses the same glyphs as the normal font, just slanted.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;font-variant&lt;/code&gt; - allows you to choose between the &lt;code&gt;normal&lt;/code&gt;, and &lt;code&gt;small-caps&lt;/code&gt; variants of the font.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;font-weight&lt;/code&gt; - allows you to choose the thickness (weight) of the font. Either by using keywords like &lt;code&gt;normal&lt;/code&gt;, &lt;code&gt;bold&lt;/code&gt;, &lt;code&gt;lighter&lt;/code&gt;, &lt;code&gt;bolder&lt;/code&gt; or a numeric value from 100 to 900.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Font Family
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;font-family&lt;/code&gt; always has to be last.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1rn9sDl_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5bdg4x6u8zx7r9lzjdu8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1rn9sDl_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/5bdg4x6u8zx7r9lzjdu8.png" alt="Font family property" width="880" height="225"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It can be a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/font-family#Values"&gt;keyword&lt;/a&gt; or font name. If the font name contains spaces, it should be wrapped in quotation marks. &lt;/p&gt;

&lt;p&gt;You can also specify additional fallback fonts, separated by commas. They will be used (from left to right), if the preferred font is unavailable.&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="c"&gt;/* keyword */&lt;/span&gt;
&lt;span class="nt"&gt;font&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;15&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="nt"&gt;serif&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="c"&gt;/* font name */&lt;/span&gt;
&lt;span class="nt"&gt;font&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;15&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="s1"&gt;"Playfair Display"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="c"&gt;/* font name with keyword fallback */&lt;/span&gt;
&lt;span class="nt"&gt;font&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;15&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="s1"&gt;"Playfair Display"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;serif&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="c"&gt;/* font name with 2 fallbacks: font name and keyword */&lt;/span&gt;
&lt;span class="nt"&gt;font&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="err"&gt;15&lt;/span&gt;&lt;span class="nt"&gt;px&lt;/span&gt; &lt;span class="s1"&gt;"Playfair Display"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;Merriweather&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;serif&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Font Size &amp;amp; Line Height
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;font-size&lt;/code&gt; and &lt;code&gt;line-height&lt;/code&gt; are right in the middle. After &lt;code&gt;font-style&lt;/code&gt;, &lt;code&gt;font-variant&lt;/code&gt;, and &lt;code&gt;font-weight&lt;/code&gt;. But before &lt;code&gt;font-family&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;line-height&lt;/code&gt; has to come right after &lt;code&gt;font-size&lt;/code&gt;, separated with a slash (&lt;code&gt;/&lt;/code&gt;). If you don't specify &lt;code&gt;line-height&lt;/code&gt;, the slash should also be omitted.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--syhrP_33--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/n28xo9b95r8g2herpodm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--syhrP_33--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/n28xo9b95r8g2herpodm.png" alt="Font size and line height properties separated with a slash" width="880" height="302"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Gotchas &amp;amp; Use-Cases
&lt;/h1&gt;

&lt;p&gt;The overriding behavior of the font shorthand can make it a bit unpredictable. For this reason it's best suited for small websites, quick prototyping, and experimentation.&lt;/p&gt;
&lt;h1&gt;
  
  
  Cheatsheet
&lt;/h1&gt;

&lt;p&gt;If you ever forget the exact order and rules of this shorthand, here's a handy cheatsheet 😃&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--emv0Ib08--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/c9s1wh5hlx60kamsvb21.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--emv0Ib08--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/c9s1wh5hlx60kamsvb21.png" alt="Full font shorthand cheatsheet" width="880" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks for reading. I hope you learned something useful. If you have any questions, ask in the comments. Follow me for more web development tips.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Another article you might enjoy
&lt;/h3&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/hadrysmateusz" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0397EEEp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--Z4ccMCYS--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/181202/fe857a32-d940-4cdb-9d8f-719b165dc573.png" alt="hadrysmateusz"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/hadrysmateusz/custom-list-styles-using-marker-before-4gi4" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Beautiful Custom List Styles Using Modern CSS&lt;/h2&gt;
      &lt;h3&gt;Mateusz Hadryś ・ Oct 12 '20 ・ 7 min read&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#css&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#design&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



</description>
      <category>css</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Beautiful Custom List Styles Using Modern CSS</title>
      <dc:creator>Mateusz Hadryś</dc:creator>
      <pubDate>Mon, 12 Oct 2020 16:53:45 +0000</pubDate>
      <link>https://dev.to/hadrysmateusz/custom-list-styles-using-marker-before-4gi4</link>
      <guid>https://dev.to/hadrysmateusz/custom-list-styles-using-marker-before-4gi4</guid>
      <description>&lt;p&gt;Lists don't have to be boring.&lt;/p&gt;

&lt;p&gt;And with the new &lt;code&gt;::marker&lt;/code&gt; pseudo-element, making them interesting doesn't have to be painful either. The &lt;a href="https://caniuse.com/css-marker-pseudo" rel="noopener noreferrer"&gt;browser support&lt;/a&gt; for this pseudo-element used to be spotty, but with its addition in &lt;a href="https://developers.google.com/web/updates/2020/10/nic86" rel="noopener noreferrer"&gt;Chrome 86&lt;/a&gt;, it'll soon be universal.&lt;/p&gt;

&lt;p&gt;I'm going to show you how to make your lists stand out. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We're going to cover:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Built-in list styles&lt;/li&gt;
&lt;li&gt;Changing the color of list markers&lt;/li&gt;
&lt;li&gt;Emoji list bullets&lt;/li&gt;
&lt;li&gt;CSS counters&lt;/li&gt;
&lt;li&gt;Custom image bullets&lt;/li&gt;
&lt;li&gt;Fully custom list markers using &lt;code&gt;::before&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Built-In Styles
&lt;/h1&gt;

&lt;p&gt;Let's begin by changing the look of list markers using the built-in styles. We do so, by using the &lt;code&gt;list-style-type&lt;/code&gt; property. There are a few style options for both ordered and unordered lists to choose from:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4adroh4ihw5bc9kmjx8x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4adroh4ihw5bc9kmjx8x.png" alt="Ordered: decimal, lower-roman, upper-alpha, lower-latin. Unordered: disc, square, circle."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These are just the most common options. The &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/list-style-type#Values" rel="noopener noreferrer"&gt;full list&lt;/a&gt; can be found on MDN.&lt;/p&gt;

&lt;h1&gt;
  
  
  Custom Styles
&lt;/h1&gt;

&lt;p&gt;The &lt;code&gt;::marker&lt;/code&gt; pseudo-element lets us change the style of the list marker (bullet/number). using a subset of CSS properties. The allowed properties are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All &lt;code&gt;font&lt;/code&gt; properties (font-size, font-family etc.)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;color&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;animation&lt;/code&gt; and &lt;code&gt;transition&lt;/code&gt; properties&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;direction&lt;/code&gt;, &lt;code&gt;text-combine-upright&lt;/code&gt;, &lt;code&gt;unicode-bidi&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;and &lt;code&gt;content&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's see what it can do.&lt;/p&gt;

&lt;h2&gt;
  
  
  🌈 Changing the Color
&lt;/h2&gt;

&lt;p&gt;The most basic way to make your lists look better, is to change the color of the list markers. We can do that just like we would change the color of normal text.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhhhn912b4u4y1obceix4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhhhn912b4u4y1obceix4.png" alt="Code snippet with preview of ordered and unordered lists with colored markers."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What if you need to support older browsers? You can apply the color to the &lt;code&gt;li&lt;/code&gt; and wrap the text inside it in another element. Like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTML&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-wrapper"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Muffin candy canes&lt;span class="nt"&gt;&amp;lt;span&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-wrapper"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Fruitcake powder cookie&lt;span class="nt"&gt;&amp;lt;span&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt; 
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"text-wrapper"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Biscuit muffin liquorice&lt;span class="nt"&gt;&amp;lt;span&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;CSS&lt;/strong&gt;&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="nt"&gt;ul&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#0E6FC9&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.text-wrapper&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;black&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;Or create a fully custom marker with &lt;code&gt;::before&lt;/code&gt;. More on that later.&lt;/p&gt;
&lt;h1&gt;
  
  
  Custom Text
&lt;/h1&gt;

&lt;p&gt;You might be thinking: &lt;em&gt;Okay, but is changing color all that &lt;code&gt;::marker&lt;/code&gt; can do?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;No. Far from it. It lets us to change the content of the list marker, by using the aptly named &lt;code&gt;content&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1fuz3xvjl0tl3a1ul1ss.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1fuz3xvjl0tl3a1ul1ss.png" alt="Code snippet with preview with colored arrows instead of default bullets."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can use any text as &lt;code&gt;content&lt;/code&gt;, including Unicode symbols like the ones above or even emoji...&lt;/p&gt;
&lt;h2&gt;
  
  
  🔫 Emoji Bullets
&lt;/h2&gt;

&lt;p&gt;As I said above, you can use emoji as list markers.&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="nt"&gt;li&lt;/span&gt;&lt;span class="nd"&gt;::marker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"😁"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;But you probably don't want to use the same emoji for every list item. To fix that, we can set our emojis in a &lt;code&gt;data-*&lt;/code&gt; attribute in HTML.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;data-emoji=&lt;/span&gt;&lt;span class="s"&gt;"🤪"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Oat cake jelly beans&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;data-emoji=&lt;/span&gt;&lt;span class="s"&gt;"😴"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Croissant cotton candy&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt; 
  &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;data-emoji=&lt;/span&gt;&lt;span class="s"&gt;"🤠"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Jelly beans muffin tiramisu&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And retrieve them in CSS using the &lt;code&gt;attr()&lt;/code&gt; function.&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="nt"&gt;li&lt;/span&gt;&lt;span class="nd"&gt;::marker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;attr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data-emoji&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;We can even change the marker's content on hover using the &lt;code&gt;:hover&lt;/code&gt; &lt;a href="https://medium.com/web-dev-beyond/the-only-20-css-selectors-you-need-to-remember-ee78b90b3020#7594" rel="noopener noreferrer"&gt;pseudo-class&lt;/a&gt;.&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="nt"&gt;li&lt;/span&gt;&lt;span class="nd"&gt;:hover::marker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&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;And here's the result.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F35ylmw8dsgccfqgq84y9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F35ylmw8dsgccfqgq84y9.gif" alt="List with emojis instead of bullets, that changes the emoji when a list item is hovered"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okay, but what about ordered lists? Can we change their markers' content like this?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/xT0BKk9aPtLzKJiUi4/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/xT0BKk9aPtLzKJiUi4/giphy.gif" alt="Oh Fo Sho"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Custom Ordered Lists
&lt;/h2&gt;

&lt;p&gt;To change the content of an ordered list marker, we need to know which item it belongs to. We need to know its position in the list. That's where &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Lists_and_Counters/Using_CSS_counters" rel="noopener noreferrer"&gt;CSS counters&lt;/a&gt; come in.&lt;/p&gt;

&lt;p&gt;We need to create a counter on the list, and increment it on every list item. Then retrieve the current value of the counter using the &lt;code&gt;counter()&lt;/code&gt; CSS function. We use the result of this function as the value of the &lt;code&gt;content&lt;/code&gt; property.&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="c"&gt;/* Import fonts from Google Fonts */&lt;/span&gt;
&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="sx"&gt;url('https://fonts.googleapis.com/css2?family=Raleway&amp;amp;family=Sigmar+One&amp;amp;display=swap')&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nt"&gt;ol&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;list-style-position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;inside&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c"&gt;/* Start counter */&lt;/span&gt;
  &lt;span class="nl"&gt;counter-reset&lt;/span&gt;&lt;span class="p"&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="nt"&gt;li&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;'Raleway'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;sans-serif&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c"&gt;/* Increment counter on each list item */&lt;/span&gt;
  &lt;span class="nl"&gt;counter-increment&lt;/span&gt;&lt;span class="p"&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="nt"&gt;li&lt;/span&gt;&lt;span class="nd"&gt;::marker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;font-family&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"Sigmar One"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;cursive&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c"&gt;/* Use counter to display the current number */&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;"Step "&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s1"&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;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0mafhune48ihb0jg9u08.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F0mafhune48ihb0jg9u08.png" alt="List showing steps. Step 1: Use CSS Counters. Step 2: ??? Step 3: Profit"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's go through the code, to understand what's happening.&lt;/p&gt;

&lt;p&gt;We use &lt;code&gt;counter-reset&lt;/code&gt; to create a new counter named &lt;code&gt;list&lt;/code&gt;. The name is arbitrary and completely up to you. But why is the property called counter-&lt;strong&gt;reset&lt;/strong&gt;? Because the counter is actually global and we need to reset its value on every list. That's why we have to set it on the &lt;code&gt;ol&lt;/code&gt; and not the list items. &lt;/p&gt;

&lt;p&gt;We've created our counter, but it's useless if its value never changes. We need to increment it on every list item. To do that we set &lt;code&gt;counter-increment: list;&lt;/code&gt; on our &lt;code&gt;&amp;lt;li&amp;gt;&lt;/code&gt;'s.&lt;/p&gt;

&lt;p&gt;Now that we have an auto-incrementing value, we use it in the &lt;code&gt;content&lt;/code&gt; property of our marker. And here's where the magic happens. We can combine the value of our counter with other strings, optionally separated by whitespace.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A FEW NOTES:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the example, I imported some fonts from &lt;a href="https://fonts.google.com" rel="noopener noreferrer"&gt;Google Fonts&lt;/a&gt;. It's not necessary but I'm using it to distinguish between the list item's content and the marker.&lt;/li&gt;
&lt;li&gt;Because the marker's content in the example got pretty long, it was possible for it to go off the screen in some circumstances. That's why I used &lt;code&gt;list-style-position: inside;&lt;/code&gt; to move the marker inside the list item's box.&lt;/li&gt;
&lt;li&gt;You can put a number after the counter name to start from a different value. It would look something like this: &lt;code&gt;counter-reset: list 5;&lt;/code&gt; and the first three items of that list would have numbers 6, 7, and 8.&lt;/li&gt;
&lt;li&gt;Counters can be used on any html element, not just lists.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Custom Image Bullets
&lt;/h2&gt;

&lt;p&gt;Okay, we can change the color, style, and text content of list markers, but what if we want something completely custom? We'll have to use images. &lt;/p&gt;

&lt;p&gt;To do that, we set an image as the marker's content using the &lt;code&gt;url()&lt;/code&gt; CSS function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjkp22kkivuwl8bix7n56.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fjkp22kkivuwl8bix7n56.png" alt="Code snippet with preview of a list with stars and asterisks instead of default bullets."&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Fully Custom List Markers
&lt;/h1&gt;

&lt;p&gt;If all of the above options still aren't enough for you, there's still one more option. One that allows us to do anything we want with our list markers. It's more work and a bit of a hack, but it's useful if all else fails.&lt;/p&gt;

&lt;p&gt;We can use the &lt;code&gt;::before&lt;/code&gt; pseudo element to create our own markers. This method allows us to create custom backgrounds for our markers, easily scale image bullets and more.&lt;/p&gt;
&lt;h2&gt;
  
  
  Clear the defaults
&lt;/h2&gt;

&lt;p&gt;Before we can create our own markers, we have to get rid of the default ones.&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="nt"&gt;ol&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;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&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;list-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&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;This gives us a blank canvas to work with.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This can create accessibility issues, so you should add role="list" to the list in your HTML&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ol&lt;/span&gt; &lt;span class="na"&gt;role=&lt;/span&gt;&lt;span class="s"&gt;"list"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Latvia&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;China&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;Portugal&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ol&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Create the marker
&lt;/h2&gt;

&lt;p&gt;When using &lt;code&gt;::before&lt;/code&gt; you have access to all CSS properties and not just a subset like with &lt;code&gt;::marker&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/3o84sq21TxDH6PyYms/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3o84sq21TxDH6PyYms/giphy.gif" alt="Unlimited Power!"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You are however responsible for setting the marker’s content, spacing between the marker and the list item’s text, and proper alignment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F44w5i9e5n9gso0wv4l0l.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F44w5i9e5n9gso0wv4l0l.gif" alt="With great power, comes great responsibility"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As an example, here’s how to create the objectively best-looking list of all time. Explanations are included in the comments.&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="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;spin&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;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0deg&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;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;360deg&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="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;contain&lt;/span&gt; &lt;span class="nb"&gt;no-repeat&lt;/span&gt; &lt;span class="n"&gt;linear-gradient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;135deg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="no"&gt;orange&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="no"&gt;yellow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="no"&gt;green&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="no"&gt;blue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="no"&gt;violet&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;red&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;font&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;italic&lt;/span&gt; &lt;span class="nb"&gt;bold&lt;/span&gt; &lt;span class="m"&gt;3.2rem&lt;/span&gt; &lt;span class="nb"&gt;cursive&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;text-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;1px&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="m"&gt;2px&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;letter-spacing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;ol&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* Remove defaults */&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;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;padding&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;list-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c"&gt;/* Use CSS grid for spacing between list items */&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c"&gt;/* Create counter */&lt;/span&gt;
  &lt;span class="nl"&gt;counter-reset&lt;/span&gt;&lt;span class="p"&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="nt"&gt;li&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* Use CSS grid for spacing between marker and list item contents */&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;grid-template-columns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;min-content&lt;/span&gt; &lt;span class="m"&gt;500px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;column-gap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c"&gt;/* Increment counter */&lt;/span&gt;
  &lt;span class="nl"&gt;counter-increment&lt;/span&gt;&lt;span class="p"&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="nt"&gt;li&lt;/span&gt;&lt;span class="nd"&gt;::before&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* Set content to an empty string */&lt;/span&gt;
  &lt;span class="nl"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;counter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c"&gt;/* Add a background image for the marker */&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;contain&lt;/span&gt; &lt;span class="nb"&gt;no-repeat&lt;/span&gt; &lt;span class="sx"&gt;url("path/to/image.png")&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c"&gt;/* Add animation */&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3s&lt;/span&gt; &lt;span class="n"&gt;linear&lt;/span&gt; &lt;span class="m"&gt;1s&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt; &lt;span class="n"&gt;spin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c"&gt;/* Create the box and center its contents */&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;60px&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;60px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c"&gt;/* Additional text styles */&lt;/span&gt;
  &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&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;The above code results in this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb059zelehm4getq4g59t.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fb059zelehm4getq4g59t.gif" alt="List with spinning stars with numbers as markers. Red Comic Sans text: "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A few notes:&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/background" rel="noopener noreferrer"&gt;background&lt;/a&gt; property for the marker's image allows us to scale and adjust it more easily.&lt;/li&gt;
&lt;li&gt;If you want to create custom image bullets for an unordered list using &lt;code&gt;::before&lt;/code&gt; &amp;amp; &lt;code&gt;background&lt;/code&gt;, you have to set &lt;code&gt;content: ""&lt;/code&gt; in order for the marker to be rendered. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's all, you're now a master of list styling.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks for reading. I hope you learned something useful. If you have any questions, ask in the comments.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Other articles you might enjoy
&lt;/h3&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/hadrysmateusz" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F181202%2Ffe857a32-d940-4cdb-9d8f-719b165dc573.png" alt="hadrysmateusz"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/hadrysmateusz/complete-guide-to-css-gradients-1eck" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Ultimate Guide to CSS Gradients&lt;/h2&gt;
      &lt;h3&gt;Mateusz Hadryś ・ Dec 29 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#css&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#design&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;




&lt;div class="ltag__link"&gt;
  &lt;a href="/hadrysmateusz" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F181202%2Ffe857a32-d940-4cdb-9d8f-719b165dc573.png" alt="hadrysmateusz"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/hadrysmateusz/how-to-use-multiple-versions-of-node-on-windows-1op9" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;How to use multiple versions of node on Windows&lt;/h2&gt;
      &lt;h3&gt;Mateusz Hadryś ・ Jun 15 '19&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#node&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>css</category>
      <category>tutorial</category>
      <category>webdev</category>
      <category>design</category>
    </item>
    <item>
      <title>4 Ways to Get All Characters in a String in JavaScript</title>
      <dc:creator>Mateusz Hadryś</dc:creator>
      <pubDate>Mon, 17 Aug 2020 19:01:26 +0000</pubDate>
      <link>https://dev.to/hadrysmateusz/how-to-get-all-characters-in-a-string-57c7</link>
      <guid>https://dev.to/hadrysmateusz/how-to-get-all-characters-in-a-string-57c7</guid>
      <description>&lt;p&gt;&lt;em&gt;How to get all characters in a string?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This question might sound simple at first, but in JavaScript nothing is ever what it seems.&lt;/p&gt;

&lt;p&gt;If you google &lt;em&gt;"How to get all characters in a string"&lt;/em&gt; or &lt;em&gt;"How to get an array of characters from string"&lt;/em&gt;, you will most likely find something like:&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;chars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Some string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// or...&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Some string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&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="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;charAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&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;...and people arguing if you should use &lt;code&gt;str.charAt()&lt;/code&gt; or the bracket notation.&lt;/p&gt;

&lt;p&gt;However, these answers are usually pretty old and don't take into account one important issue...&lt;/p&gt;
&lt;h2&gt;
  
  
  Emoji 🔥☠️
&lt;/h2&gt;

&lt;p&gt;Or more generally: surrogate pairs. Most characters in javascript are encoded using 2 bytes, but that’s not enough to encode every symbol. To deal with this problem, emoji and some other rare symbols are encoded with a pair of 2-byte characters — a surrogate pair.&lt;/p&gt;

&lt;p&gt;Surrogate pairs didn’t exist when JavaScript was created, so some parts of the language still treat these symbols like 2 separate characters. You can copy this snippet into your browser console to see for yourself:&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;💩&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;
&lt;span class="c1"&gt;// returns 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This can make the above methods sometimes return incorrect results, like this:&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;💩&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// returns ["�", "�"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  ES6 to the rescue!
&lt;/h2&gt;

&lt;p&gt;ES6 introduced the concept of iterators and along with it, a solution to the surrogate pairs problem.&lt;/p&gt;
&lt;h3&gt;
  
  
  Array.from()
&lt;/h3&gt;

&lt;p&gt;The simplest way to create an array from any iterable, including strings.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;✨𝄞💩&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;chars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// chars is now: ["✨","𝄞","💩"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Spread operator
&lt;/h3&gt;

&lt;p&gt;The shortest way to do it, but sacrificing readability.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;✨𝄞💩&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;chars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;// chars is now: ["✨","𝄞","💩"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  For...of loop
&lt;/h3&gt;

&lt;p&gt;The most versatile and performant of the bunch.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;✨𝄞💩&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;char&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// Logs to the console:&lt;/span&gt;
&lt;span class="c1"&gt;// "✨"&lt;/span&gt;
&lt;span class="c1"&gt;// "𝄞"&lt;/span&gt;
&lt;span class="c1"&gt;// "💩"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  RegExp unicode flag
&lt;/h3&gt;

&lt;p&gt;If you're feeling fancy you can also use a regular expression with the unicode flag.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;✨𝄞💩&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;chars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/./gu&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// chars is now: ["✨","𝄞","💩"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Browser support
&lt;/h2&gt;

&lt;p&gt;All of the above are ES6 features, which at this point, is supported pretty much everywhere, with the exception of internet explorer. If you need to support internet explorer you should transpile your code with a tool like Babel. Or just use one of the old methods, but be aware of their limitations.&lt;/p&gt;



&lt;p&gt;&lt;em&gt;Thanks for reading.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you know other clever ways to turn strings into character arrays, let me know in the comments, I always like learning new things.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Other articles you might enjoy
&lt;/h3&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/hadrysmateusz" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0397EEEp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--Z4ccMCYS--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/181202/fe857a32-d940-4cdb-9d8f-719b165dc573.png" alt="hadrysmateusz"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/hadrysmateusz/ultimate-guide-to-file-handling-in-client-side-javascript-4ki3" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Read, Edit &amp;amp; Write Files in Client-Side JavaScript&lt;/h2&gt;
      &lt;h3&gt;Mateusz Hadryś ・ Dec 19 '19 ・ 15 min read&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#programming&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;




&lt;div class="ltag__link"&gt;
  &lt;a href="/hadrysmateusz" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0397EEEp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://res.cloudinary.com/practicaldev/image/fetch/s--Z4ccMCYS--/c_fill%2Cf_auto%2Cfl_progressive%2Ch_150%2Cq_auto%2Cw_150/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/181202/fe857a32-d940-4cdb-9d8f-719b165dc573.png" alt="hadrysmateusz"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/hadrysmateusz/learn-all-8-background-css-properties-in-5-minutes-2lk4" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;All CSS Background Properties Explained in 5 Minutes&lt;/h2&gt;
      &lt;h3&gt;Mateusz Hadryś ・ Dec 16 '20 ・ 6 min read&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#css&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Read, Edit &amp; Write Files in Client-Side JavaScript</title>
      <dc:creator>Mateusz Hadryś</dc:creator>
      <pubDate>Thu, 19 Dec 2019 22:40:04 +0000</pubDate>
      <link>https://dev.to/hadrysmateusz/ultimate-guide-to-file-handling-in-client-side-javascript-4ki3</link>
      <guid>https://dev.to/hadrysmateusz/ultimate-guide-to-file-handling-in-client-side-javascript-4ki3</guid>
      <description>&lt;p&gt;Lately I've been working on a &lt;a href="https://vivaldi-thumbnails.netlify.com/" rel="noopener noreferrer"&gt;side-project&lt;/a&gt;, which was based around reading and manipulating files to generate custom thumbnails for &lt;a href="https://vivaldi.com/" rel="noopener noreferrer"&gt;Vivaldi browser&lt;/a&gt;'s speed dials. I was able to do it all inside the browser, without any server-side processing, and I want to share with you everything that I've learned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This guide covers:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;using &lt;strong&gt;objectURLs&lt;/strong&gt; and &lt;strong&gt;FileReader&lt;/strong&gt; to read files from the user's filesystem&lt;/li&gt;
&lt;li&gt;getting a file's information like: size, type and more&lt;/li&gt;
&lt;li&gt;showing previews of selected image files&lt;/li&gt;
&lt;li&gt;handling errors and loading states&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CHEATSHEET AT THE END&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It also acts as an introduction to my guide on using the &lt;code&gt;Canvas&lt;/code&gt; API, which is coming very soon, so stay tuned for that!&lt;/p&gt;




&lt;h1&gt;
  
  
  Selecting files from the filesystem
&lt;/h1&gt;

&lt;p&gt;To allow your users to select a file from their device, you will first have to create an &lt;code&gt;input&lt;/code&gt; with the type of &lt;strong&gt;file&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"inputElement"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To actually get the files from this input, you will need to access the &lt;code&gt;files&lt;/code&gt; property of the input element. It's best to do that by registering a &lt;strong&gt;change&lt;/strong&gt; event listener on the input element. This way a callback function will be called every time a user selects a file.&lt;/p&gt;

&lt;p&gt;The way you do that will depend on the framework you're using. To make this guide as widely applicable as possible, we will be using vanilla JS.&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="c1"&gt;// get a reference to the inputElement in any way you choose&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inputElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inputElement&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// get the value once&lt;/span&gt;
&lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&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="c1"&gt;// get the value every time the user selects a new file&lt;/span&gt;
&lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;change&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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="c1"&gt;// e.target points to the input element&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;selectedFile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&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="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The resulting &lt;strong&gt;selectedFile&lt;/strong&gt; is a &lt;code&gt;File&lt;/code&gt; object.&lt;/p&gt;


&lt;h1&gt;
  
  
  Properties of files
&lt;/h1&gt;

&lt;p&gt;The file input gives us &lt;code&gt;File&lt;/code&gt; objects, so in addition to the contents of the file itself, we have access to some additional information, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;name&lt;/code&gt; - the file's name, including the extension but without the path (e.g. "cat_photo.png")&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;size&lt;/code&gt; - the file's size in bytes. To get the size in a more human readable format, you can use a library like &lt;a href="https://www.npmjs.com/package/filesize" rel="noopener noreferrer"&gt;filesize&lt;/a&gt; or &lt;a href="https://www.npmjs.com/package/bytes" rel="noopener noreferrer"&gt;bytes&lt;/a&gt;. For simple use cases, you can even write your own conversion logic.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;type&lt;/code&gt; - the file's &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types" rel="noopener noreferrer"&gt;MIME type&lt;/a&gt; (e.g. "text/plain", "image/png")&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;lastModified&lt;/code&gt; - the last modified date of the file, represented as the number of milliseconds since the Unix epoch (January 1, 1970 at midnight). You can use the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date" rel="noopener noreferrer"&gt;Date constructor&lt;/a&gt; to convert this timestamp to a more useful javascript &lt;code&gt;Date&lt;/code&gt; object.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;File&lt;/code&gt;s also have two other properties: &lt;code&gt;File.lastModifiedDate&lt;/code&gt; and &lt;code&gt;File.webkitRelativePath&lt;/code&gt;, the first of which is deprecated and the other non-standard, so you should probably avoid using them. Keep in mind that all of these properties are read-only.&lt;/p&gt;
&lt;h2&gt;
  
  
  Files &amp;amp; Blobs
&lt;/h2&gt;

&lt;p&gt;In addition to &lt;code&gt;File&lt;/code&gt;, javascript has another way of representing files, called &lt;code&gt;Blob&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Blob&lt;/code&gt; contains a generic file's data, along with information about its size and type. &lt;code&gt;File&lt;/code&gt; is actually just a more specialised &lt;code&gt;Blob&lt;/code&gt;, used to represent specifically files in a user's filesystem. It inherits all of Blob's methods and properties and contains some additional information about the file's name and last modified date.&lt;/p&gt;

&lt;p&gt;These two are basically interchangeable, and you can use one almost everywhere you can use the other. If you absolutely need to convert them though, you can do so using the other type's constructor.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;File&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fileName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&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;type&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;blob&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Blob&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Reading the contents of files
&lt;/h1&gt;

&lt;p&gt;Okay, so we know how to select and get information about files, but how do we actually read what's inside them? Well, that depends on what kind of file it is and what you want to do with it. For the purposes of this article, we will only focus on images and text files.&lt;/p&gt;

&lt;p&gt;The most flexible and well-supported method of reading a file's contents is the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/FileReader" rel="noopener noreferrer"&gt;FileReader API&lt;/a&gt;. It's an event driven API, so instead of simply calling a function and getting the file's contents, we must take some extra steps.&lt;/p&gt;

&lt;p&gt;Let's start with reading a text file:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inputElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inputElement&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onchange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&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="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="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileReader&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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="c1"&gt;// e.target points to the reader&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`The content of &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; is &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onerror&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Error occured while reading &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readAsText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&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;ol&gt;
&lt;li&gt;First we get the file input element, and register a &lt;strong&gt;change&lt;/strong&gt; event listener on it by assigning a callback function to its &lt;code&gt;onchange&lt;/code&gt; property&lt;/li&gt;
&lt;li&gt;We get the selected file&lt;/li&gt;
&lt;li&gt;We check if a file was actually selected and if not, (which might happen for example if a user clicks 'cancel' in the selection window) we exit the function&lt;/li&gt;
&lt;li&gt;Next, we create an instance of FileReader&lt;/li&gt;
&lt;li&gt;Then we register any event handlers we might need. To access the file contents we only really need the &lt;strong&gt;load&lt;/strong&gt; event, which triggers when the read operation has finished &lt;strong&gt;succesfully&lt;/strong&gt;. However it's usually a good idea to register an error handler as well. A full list of possible events is available a bit further into the article, along with some error handling tips, so keep reading 😉&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;After&lt;/strong&gt; all event listeners are registered, we initiate the read operation by calling one of the &lt;strong&gt;readAs&lt;/strong&gt; methods, in this case &lt;code&gt;readAsText&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;After the reading operation is finished, the file contents will be available in the &lt;code&gt;reader.result&lt;/code&gt; property, which we can access inside the &lt;strong&gt;load&lt;/strong&gt; event handler (the &lt;code&gt;reader.onload&lt;/code&gt; callback function).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Quick tip:&lt;/strong&gt; You can access the reader inside an event handler in multiple ways: &lt;code&gt;reader === e.target === this&lt;/code&gt;. Keep in mind that &lt;code&gt;this&lt;/code&gt; is not available in arrow functions.&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;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onchange&lt;/span&gt; &lt;span class="o"&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// closure&lt;/span&gt;
&lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onchange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// event target&lt;/span&gt;
&lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onchange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&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;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 'this'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Error Handling
&lt;/h2&gt;

&lt;p&gt;In case of an error, the &lt;em&gt;error&lt;/em&gt; event handler is called, and you can find the Error object in &lt;code&gt;reader.error&lt;/code&gt;. Possible error codes are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;FileError.NOT_FOUND_ERR&lt;/code&gt; - the file was not found&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;FileError.NOT_READABLE_ERR&lt;/code&gt; - the file could not be read&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;FileError.SECURITY_ERR&lt;/code&gt; - there was a security issue&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;FileError.ABORT_ERR&lt;/code&gt; - thrown when &lt;code&gt;reader.abort()&lt;/code&gt; is called while there's no read operation in progress&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most of the time there is no need to differentiate between these error types, maybe except for &lt;code&gt;ABORT_ERR&lt;/code&gt; which is generally harmless and can be ignored.&lt;/p&gt;
&lt;h2&gt;
  
  
  Ready State
&lt;/h2&gt;

&lt;p&gt;The read operation is &lt;strong&gt;asynchronous&lt;/strong&gt;, so don't try accessing &lt;code&gt;reader.result&lt;/code&gt; right after the &lt;strong&gt;readAs&lt;/strong&gt; call. If you really need to check the &lt;code&gt;reader.result&lt;/code&gt; value outside of the &lt;strong&gt;load&lt;/strong&gt; event handler, make sure to first check the value of &lt;code&gt;reader.readyState&lt;/code&gt;, which will be one of 3 values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;0&lt;/code&gt; - The reader has been created, but no &lt;strong&gt;readAs&lt;/strong&gt; method was called yet. (EMPTY)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;1&lt;/code&gt; - One of the &lt;strong&gt;readAs&lt;/strong&gt; methods has been called. A read operation is in progress, and no errors have occurred yet. (LOADING)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2&lt;/code&gt; - The operation has finished. This could mean one of three things: the &lt;code&gt;File&lt;/code&gt; has been read succesfully, a read error has occured, or &lt;code&gt;reader.abort()&lt;/code&gt; was called and the operation was canceled. (DONE)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;reader.result&lt;/code&gt; property will be populated only in case of a successful read operation. In all other cases it will be &lt;code&gt;null&lt;/code&gt;.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileReader&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;// readyState is 0, result is null&lt;/span&gt;
&lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&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="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// readyState is 2, result is the file's content&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onerror&lt;/span&gt; &lt;span class="o"&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="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// readyState is 2, result is null&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// readyState is 0, result is null&lt;/span&gt;
&lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readAsText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// readyState is 1, result is null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The same applies to &lt;code&gt;reader.error&lt;/code&gt; which should be accessed inside the &lt;strong&gt;error&lt;/strong&gt; event handler.&lt;/p&gt;
&lt;h2&gt;
  
  
  FileReader Event Types
&lt;/h2&gt;

&lt;p&gt;We've already explored the two most common read event types, now let's quickly cover the rest. FileReader has six event types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;load&lt;/code&gt; - triggered when a read operation is &lt;strong&gt;successfully&lt;/strong&gt; completed&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;error&lt;/code&gt; - triggered when a read operation encounters an error&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;progress&lt;/code&gt; - triggered periodically while a &lt;code&gt;File&lt;/code&gt; or &lt;code&gt;Blob&lt;/code&gt; is being read and contains information about the progress of the operation. Can be used to implement loading bars.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;abort&lt;/code&gt; - triggered when a read operation is cancelled, i.e. when &lt;code&gt;reader.abort()&lt;/code&gt; is called&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;loadstart&lt;/code&gt; - triggered when a read operation starts&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;loadend&lt;/code&gt; - triggered when a read operation is finished, regardless of if it succeeded or failed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You've probably noticed that FileReader events work similarly to regular DOM events. I find that thinking about them as such makes it a lot easier to understand their non-linear, asynchronous nature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sidenote:&lt;/strong&gt; Just as with DOM events, it's possible to register event handlers by using &lt;code&gt;addEventListener&lt;/code&gt;, or by assigning a callback function to the "oneventname" property of a reader.&lt;/p&gt;
&lt;h2&gt;
  
  
  Blob.text()
&lt;/h2&gt;

&lt;p&gt;It's also worth noting that for reading text files there exists a newer and simpler method: &lt;code&gt;Blob.text()&lt;/code&gt;. Remember that &lt;code&gt;File&lt;/code&gt; is just a &lt;code&gt;Blob&lt;/code&gt; with some added functionality, so it inherits all of Blob's methods, including this one. This means you can use this method on both Blobs and Files.&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="c1"&gt;// using promise.then()&lt;/span&gt;
&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="cm"&gt;/* do something */&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// using async/await&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&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;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Doesn't it look nicer? I think it does, but there's a catch. This API is quite new and the &lt;a href="https://caniuse.com/#feat=mdn-api_blob_text" rel="noopener noreferrer"&gt;browser support&lt;/a&gt; is still pretty poor.&lt;/p&gt;


&lt;h1&gt;
  
  
  Working with images
&lt;/h1&gt;

&lt;p&gt;Now that we know how to read text files, let's move on to something more exciting: images. To illustrate this topic, we're going to build a simple preview of the selected image.&lt;/p&gt;
&lt;h2&gt;
  
  
  File types
&lt;/h2&gt;

&lt;p&gt;First let's make sure that the selected file is actually an image. We can do that with the help of the &lt;code&gt;accept&lt;/code&gt; attribute.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- any image type will be accepted --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt; &lt;span class="na"&gt;accept=&lt;/span&gt;&lt;span class="s"&gt;"image/*"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- only .png, .jpg, and .gif files will be accepted --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt; &lt;span class="na"&gt;accept=&lt;/span&gt;&lt;span class="s"&gt;"image/png, image/jpeg, image/gif"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;accept&lt;/code&gt; attribute, allows you to specify what kind of files the user will be allowed to select. It uses a comma-separated list of unique file type specifiers. Each type specifier can be in one of the following formats:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A case-insensitive filename extension, starting with a period (".") character. For example: &lt;code&gt;.jpg&lt;/code&gt;, &lt;code&gt;.JPEG&lt;/code&gt;, &lt;code&gt;.gif&lt;/code&gt;, &lt;code&gt;.doc&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types" rel="noopener noreferrer"&gt;MIME type&lt;/a&gt;, for example: &lt;code&gt;image/jpeg&lt;/code&gt;, &lt;code&gt;image/png&lt;/code&gt;, &lt;code&gt;text/plain&lt;/code&gt;, &lt;code&gt;audio/wav&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;image/*&lt;/code&gt; which means "any image file"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;audio/*&lt;/code&gt; which means "any audio file"&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;video/*&lt;/code&gt; which means "any video file"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can mix and match these to suite your particular use-case.&lt;/p&gt;

&lt;p&gt;HTML validation isn't perfect though. For example, on Windows it will only hide the files not matching your criteria, but you can still select "All files (*.*)" or use drag-and-drop to select any file you want. All of this means that it's also a good idea to check the file type inside your javascript 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="c1"&gt;// allows any image file&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/* handle the files */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// only allows specified types&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image/png&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="s2"&gt;image/jpeg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/* handle the files */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Or you could set up separate processing flows for different file types&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="c1"&gt;// assuming that processImage and processText are functions&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;processImage&lt;/span&gt;
  &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readAsDataURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;processText&lt;/span&gt;
  &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readAsText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&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;Unfortunately &lt;code&gt;startsWith()&lt;/code&gt; and &lt;code&gt;includes()&lt;/code&gt; don't work in older browsers like Internet Explorer, so if you need to support them, you might want to look into some workarounds or polyfills.&lt;/p&gt;

&lt;p&gt;Also, keep in mind that "any image file" will match (among others):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;images with less-than-perfect browser support, like &lt;code&gt;webp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;images with transparency, like &lt;code&gt;png&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;animated images, like &lt;code&gt;gif&lt;/code&gt;'s&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So make sure you support all of these functionalities, or explicitly specify only the types you plan on supporting.&lt;/p&gt;
&lt;h2&gt;
  
  
  Data URLs &amp;amp; Object URLs
&lt;/h2&gt;

&lt;p&gt;To display a selected image, we will need an HTML img and a URL for the &lt;code&gt;img.src&lt;/code&gt; attribute. There are two different ways to represent an image file as a URL: a &lt;strong&gt;dataURL&lt;/strong&gt; and &lt;strong&gt;objectURL&lt;/strong&gt;. There are some important differences between the two, so let's quickly run through them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DataURL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's the result of &lt;code&gt;reader.readAsDataURL()&lt;/code&gt;. It's a string containing the file's type and the actual binary data of the file, encoded using base64.&lt;/p&gt;

&lt;p&gt;It's format can vary a bit depending on the type of data it represents, but for most files it looks like this: &lt;code&gt;data:&amp;lt;mediatype&amp;gt;;base64,&amp;lt;data&amp;gt;&lt;/code&gt;, where &lt;code&gt;&amp;lt;mediatype&amp;gt;&lt;/code&gt; is a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types" rel="noopener noreferrer"&gt;MIME type&lt;/a&gt; and &lt;code&gt;&amp;lt;data&amp;gt;&lt;/code&gt; is the base64-encoded file.&lt;/p&gt;

&lt;p&gt;Because it actually contains the file's data, it can be used anywhere after it's generated, without the need for the original file. Pretty cool!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ObjectURL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Also known as &lt;strong&gt;blob URL&lt;/strong&gt;. It's the result of &lt;code&gt;URL.createObjectURL()&lt;/code&gt;. It is a newer API, but still &lt;a href="https://caniuse.com/#feat=bloburls" rel="noopener noreferrer"&gt;pretty well supported&lt;/a&gt;. It won't however work in IE version 9 and lower.&lt;/p&gt;

&lt;p&gt;It's faster and more concise than &lt;code&gt;FileReader&lt;/code&gt; but it comes with its own set of headaches and limitations. In contrast to dataURL, it doesn't contain any file data. It's just a reference to a file. Another important difference is the fact that &lt;code&gt;URL.createObjectURL()&lt;/code&gt; is &lt;strong&gt;synchronous&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The objectURL has to be revoked when it is no longer needed. The browser will do it automatically when the document is unloaded, however for optimal performance and memory usage, you shouldn't rely on that behavior, especially in large applications with many objectURLs. Instead you should explicitly call &lt;code&gt;URL.revokeObjectURL()&lt;/code&gt; when the url is no longer needed, for example in the &lt;code&gt;image.onload&lt;/code&gt; event handler, which we will discuss later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sidenote&lt;/strong&gt; - to get the base64-encoded file data from a dataURL, simply extract the part of the string after the comma, like this: &lt;code&gt;dataUrl.slice(dataUrl.indexOf(",") + 1)&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Displaying selected images
&lt;/h2&gt;

&lt;p&gt;Most of the time objectURLs and dataURLs can be used interchangeably, but they each have their own strengths and weaknesses. This means you should probably learn both and choose which one to use on a case-by-case basis. Let's look at examples of both of them, to get a better feeling for how each one works.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- HTML markup for the next two examples --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"inputElement"&lt;/span&gt; &lt;span class="na"&gt;accept=&lt;/span&gt;&lt;span class="s"&gt;"image/*"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"previewContainer"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- The preview will go here --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Using FileReader &amp;amp; dataURLs&lt;/strong&gt;&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inputElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inputElement&lt;/span&gt;&lt;span class="dl"&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;previewContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;previewContainer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onchange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&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="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="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileReader&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;img&lt;/span&gt;&lt;span class="dl"&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;dataURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;
    &lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dataURL&lt;/span&gt;
    &lt;span class="nx"&gt;previewContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readAsDataURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&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;ol&gt;
&lt;li&gt;We register a &lt;strong&gt;change&lt;/strong&gt; event listener on the file input&lt;/li&gt;
&lt;li&gt;Inside the &lt;code&gt;onchange&lt;/code&gt; callback, we get the selected file and create an instance of &lt;code&gt;FileReader&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;We register a &lt;strong&gt;load&lt;/strong&gt; event listener on the reader&lt;/li&gt;
&lt;li&gt;Inside the &lt;code&gt;onload&lt;/code&gt; callback we create a new image element,&lt;/li&gt;
&lt;li&gt;Then we get the dataURL from &lt;code&gt;reader.result&lt;/code&gt; (remember, &lt;code&gt;e.target&lt;/code&gt; points to the &lt;code&gt;reader&lt;/code&gt;) and assign it to the &lt;code&gt;img.src&lt;/code&gt; attribute like we would in HTML&lt;/li&gt;
&lt;li&gt;Once the &lt;strong&gt;src&lt;/strong&gt; attribute is set, we append the entire &lt;code&gt;img&lt;/code&gt; element to the DOM as a child of our &lt;strong&gt;previewContainer&lt;/strong&gt;. (We actually could have just created the &lt;code&gt;img&lt;/code&gt; tag in HTML and updated the &lt;strong&gt;src&lt;/strong&gt; attribute in javascript, but doing it this way actually prepares us for working with multiple images at once, and manipulating images in a &lt;code&gt;Canvas&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;When everything is set, we start the read operation using &lt;code&gt;reader.readAsDataURL(file)&lt;/code&gt;, which will trigger our &lt;code&gt;onload&lt;/code&gt; listener when it finishes reading the file.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Using objectURLs&lt;/strong&gt;&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inputElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inputElement&lt;/span&gt;&lt;span class="dl"&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;previewContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;previewContainer&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onchange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&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="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="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;img&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;revokeObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// optional, but recommended&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;objectURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createObjectURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;objectURL&lt;/span&gt;
  &lt;span class="nx"&gt;previewContainer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img&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;ol&gt;
&lt;li&gt;We register a &lt;strong&gt;change&lt;/strong&gt; event listener on the file input&lt;/li&gt;
&lt;li&gt;Inside the &lt;code&gt;onchange&lt;/code&gt; callback, we get the selected file and create a new image element&lt;/li&gt;
&lt;li&gt;We register a &lt;strong&gt;load&lt;/strong&gt; event handler on the image&lt;/li&gt;
&lt;li&gt;Inside the &lt;code&gt;onload&lt;/code&gt; callback, &lt;code&gt;URL.revokeObjectURL()&lt;/code&gt; will revoke the objectURL once the image is fully loaded and the url is no longer needed. This step is not necessary, but highly recommended. Keep in mind that if you are going to need that url somewhere else later, you shouldn't revoke it yet.&lt;/li&gt;
&lt;li&gt;Once the image is fully loaded, we won't need the objectURL anymore. So inside the &lt;code&gt;onload&lt;/code&gt; callback, we revoke that url. To do that, we pass it as an argument to &lt;code&gt;URL.revokeObjectURL()&lt;/code&gt;. We can get the url straight from the image's &lt;strong&gt;src&lt;/strong&gt; attribute.&lt;/li&gt;
&lt;li&gt;We create the objectURL, by passing the selected file as an argument to &lt;code&gt;URL.createObjectURL()&lt;/code&gt; and assign it to the &lt;code&gt;img.src&lt;/code&gt; attribute.&lt;/li&gt;
&lt;li&gt;Once the &lt;strong&gt;src&lt;/strong&gt; attribute is set, we append the entire &lt;code&gt;img&lt;/code&gt; element to the DOM as a child of our &lt;strong&gt;previewContainer&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Sidenote:&lt;/strong&gt; Elsewhere you might see images created by using the Image constructor i.e. &lt;code&gt;const img = new Image()&lt;/code&gt;. Most of the time it's equivalent to &lt;code&gt;document.createElement("img")&lt;/code&gt; and I've never had any problems with either of them. However there might be some edge cases (described in this &lt;a href="https://stackoverflow.com/questions/6241716/is-there-a-difference-between-new-image-and-document-createelementimg" rel="noopener noreferrer"&gt;StackOverflow thread&lt;/a&gt;), which seem to make the latter a more reliable option.&lt;/p&gt;


&lt;h2&gt;
  
  
  FileList
&lt;/h2&gt;

&lt;p&gt;Before we move on to reading multiple files, let's clear something up. The &lt;code&gt;files&lt;/code&gt; property isn't actually an &lt;code&gt;Array&lt;/code&gt;, even though it looks like one 😮. It's a special &lt;code&gt;FileList&lt;/code&gt; data type. This means it doesn't have access to the normal array methods (like &lt;code&gt;map&lt;/code&gt;, &lt;code&gt;forEach&lt;/code&gt;, &lt;code&gt;reduce&lt;/code&gt;), so to iterate over the list you will have to get creative. I will show you a few different ways to do this, but if you want to know more, check out this &lt;a href="https://stackoverflow.com/questions/40902437/cant-use-foreach-with-filelist" rel="noopener noreferrer"&gt;StackOverflow thread&lt;/a&gt;.&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="c1"&gt;// use a 'for' loop&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&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="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/* ... */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// use a 'for...of' loop&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="cm"&gt;/* ... */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// below, I used 'forEach' as an example but it'll work with any array method&lt;/span&gt;

&lt;span class="c1"&gt;// call the function with a bound 'this'&lt;/span&gt;
&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;[].&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// use ES6 spread syntax to transform it into an Array&lt;/span&gt;
&lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="c1"&gt;// use Array.from() to transform it into an Array (equivalent to spread syntax)&lt;/span&gt;
&lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/* ... */&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You might also have noticed that even though we've only been working with a singe file (until now), we always had to write &lt;code&gt;files[0]&lt;/code&gt;. That's because regardless of whether the &lt;code&gt;multiple&lt;/code&gt; attribute is set or not, &lt;code&gt;inputElement.files&lt;/code&gt; is always a &lt;code&gt;FileList&lt;/code&gt;. This means that even if the input only accepts a single file, you still have to provide the index, which in the case of an only item is 0.&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="c1"&gt;// get number of selected files&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;numFiles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;
&lt;span class="c1"&gt;// get a single file&lt;/span&gt;
&lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&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="c1"&gt;// or using the special 'FileList.item()' method&lt;/span&gt;
&lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;item&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Sidenote&lt;/strong&gt; - According to the &lt;a href="https://w3c.github.io/FileAPI/#filelist-section" rel="noopener noreferrer"&gt;w3c working draft&lt;/a&gt;, &lt;code&gt;FileList&lt;/code&gt; might be replaced by a regular &lt;code&gt;Array&lt;/code&gt; in the near future. Fingers crossed 🤞&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The FileList interface should be considered "at risk" since the general trend on the Web Platform is to replace such interfaces with the Array platform object in ECMAScript [ECMA-262]. In particular, this means syntax of the sort filelist.item(0) is at risk; most other programmatic use of FileList is unlikely to be affected by the eventual migration to an Array type.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h1&gt;
  
  
  Reading Multiple Files
&lt;/h1&gt;

&lt;p&gt;By default the file input only allows us to select a single file. To allow selecting multiple files at once, add the &lt;code&gt;multiple&lt;/code&gt; attribute to the html element.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt; &lt;span class="na"&gt;multiple&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In this example I'll be using &lt;code&gt;FileReader&lt;/code&gt; because it's asynchronous and won't block the UI when processing many files. But if you want to you can use objectURLs instead and in most cases you should be fine.&lt;/p&gt;

&lt;p&gt;Because we've already done most of this before, I'll only use comments to call out important bits of the code. If you skipped the previous sections, I recommend you go back and catch up, I'll wait 😉&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- Modified HTML from the previous example. Notice the 'multiple' attribute --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"inputElement"&lt;/span&gt; &lt;span class="na"&gt;accept=&lt;/span&gt;&lt;span class="s"&gt;"image/*"&lt;/span&gt; &lt;span class="na"&gt;multiple&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"previewList"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- The previews will go here, inside individual list items --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inputElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;inputElement&lt;/span&gt;&lt;span class="dl"&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;previewList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;previewList&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;inputElement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onchange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;files&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// transform FileList into an Array&lt;/span&gt;

  &lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;file&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="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="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="c1"&gt;// if you use a regular 'for' loop, use continue instead&lt;/span&gt;

    &lt;span class="c1"&gt;// if the file isn't an image, we skip it&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="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startsWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;image/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;

    &lt;span class="c1"&gt;// create a separate reader for every file to avoid conflicts&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reader&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;FileReader&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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;listItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;li&lt;/span&gt;&lt;span class="dl"&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;img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;img&lt;/span&gt;&lt;span class="dl"&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;dataURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;
      &lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;dataURL&lt;/span&gt;
      &lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="c1"&gt;// set a uniform height for all images (optional)&lt;/span&gt;

      &lt;span class="nx"&gt;listItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;img&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nx"&gt;previewList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;listItem&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;reader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readAsDataURL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&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;As you can see, we create a separate &lt;code&gt;FileReader&lt;/code&gt; instance for every file. The same could probably be achieved by calling &lt;code&gt;readAsDataURL&lt;/code&gt; inside a &lt;code&gt;loadend&lt;/code&gt; event handler, but this does the job and is probably faster anyway.&lt;/p&gt;
&lt;h2&gt;
  
  
  Cheatsheet
&lt;/h2&gt;

&lt;p&gt;Here’s a cheatsheet of the entire file-handling flow, including all classes and methods involved.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmbqinhsy64qi5h68gkl0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmbqinhsy64qi5h68gkl0.png" alt="Cheatsheet"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;I hope this guide was clear and got you the answers you needed. If something was unclear, or you would like me to expand on some topic, let me know in the comments 💬 All constructive criticism is welcome.&lt;/p&gt;

&lt;p&gt;Like I said at the beginning I'm currently working on part 2 of this guide, which will cover the Canvas API, so consider following me here, or on&lt;a href="https://twitter.com/HadrysMateusz" rel="noopener noreferrer"&gt;my twitter&lt;/a&gt; 🐦 to know when it comes out.&lt;/p&gt;

&lt;p&gt;Also, if you're a &lt;a href="https://vivaldi.com/" rel="noopener noreferrer"&gt;Vivaldi&lt;/a&gt; fan like I am, check out my &lt;a href="https://vivaldi-thumbnails.netlify.com/" rel="noopener noreferrer"&gt;Vivaldi Thumbnail Generator&lt;/a&gt;, it's a free tool I created because I was tired of creating thumbnails manually. It uses a lot of the concepts from this post and you can check out the entire source code on &lt;a href="https://github.com/ematte/vivaldi-thumbnail-generator" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Other articles you might enjoy
&lt;/h3&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/hadrysmateusz" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F181202%2Ffe857a32-d940-4cdb-9d8f-719b165dc573.png" alt="hadrysmateusz"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/hadrysmateusz/how-to-get-all-characters-in-a-string-57c7" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;4 Ways to Get All Characters in a String in JavaScript&lt;/h2&gt;
      &lt;h3&gt;Mateusz Hadryś ・ Aug 17 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#programming&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;




&lt;div class="ltag__link"&gt;
  &lt;a href="/hadrysmateusz" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F181202%2Ffe857a32-d940-4cdb-9d8f-719b165dc573.png" alt="hadrysmateusz"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/hadrysmateusz/complete-guide-to-css-gradients-1eck" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Ultimate Guide to CSS Gradients&lt;/h2&gt;
      &lt;h3&gt;Mateusz Hadryś ・ Dec 29 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#css&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#design&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to use multiple versions of node on Windows</title>
      <dc:creator>Mateusz Hadryś</dc:creator>
      <pubDate>Sat, 15 Jun 2019 22:20:02 +0000</pubDate>
      <link>https://dev.to/hadrysmateusz/how-to-use-multiple-versions-of-node-on-windows-1op9</link>
      <guid>https://dev.to/hadrysmateusz/how-to-use-multiple-versions-of-node-on-windows-1op9</guid>
      <description>&lt;p&gt;Whether you're coming from linux, or are new to node. You're probably going to need to work with multiple versions of node at some point. Whether you're working on multiple projects or want it for testing purposes, a node version manager is a very useful tool. On linux it's easy, just install nvm and you're set. On windows it's not that simple... or is it?&lt;/p&gt;

&lt;h3&gt;
  
  
  nvm-windows to the rescue!
&lt;/h3&gt;

&lt;p&gt;It's a fully-featured command line node version manager for Windows. It even comes with a simple gui installer, which is great.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzker9f3u6799gu374780.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzker9f3u6799gu374780.png" width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Here are the steps to getting up and running with nvm-windows
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;If you have any version of node installed already, make sure to uninstall it first. Make sure to also remove any remaining node and npm directories (e.g. "C:\Program Files\nodejs" and "C:\Users&amp;lt;user_name&amp;gt;\AppData\Roaming\npm")&lt;/li&gt;
&lt;li&gt;Get the installer from the releases page: &lt;a href="https://github.com/coreybutler/nvm-windows/releases" rel="noopener noreferrer"&gt;https://github.com/coreybutler/nvm-windows/releases&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Go through the installation process, nvm will be added to your PATH automatically&lt;/li&gt;
&lt;li&gt;Run cmd or any terminal emulator you might be using&lt;/li&gt;
&lt;li&gt;Use the command &lt;code&gt;nvm install version_number&lt;/code&gt;  where version_number is the version of node you want to install (e.g. 8 or 10)&lt;/li&gt;
&lt;li&gt;Repeat the above command for every version you need&lt;/li&gt;
&lt;li&gt;Finally, run &lt;code&gt;nvm use full_version_number&lt;/code&gt; where full_version_number is the full version of node you want to currently use (e.g. 8.16.0 or 10.0.0)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Can I use Yarn with nvm-windows?
&lt;/h3&gt;

&lt;p&gt;Yes... but... Unfortunately, there are some issues with using yarn alongside nvm-windows. Basically, if you want to use yarn with nvm-windows, you will have to uninstall yarn (If you installed it using the gui installer). Then you will have to install it using &lt;code&gt;npm install --global yarn&lt;/code&gt; every time you switch the node version. There are also issues when installing packages globally with yarn (&lt;a href="https://stackoverflow.com/questions/43108816/can-yarn-and-nvm-coexist-on-windows" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/43108816/can-yarn-and-nvm-coexist-on-windows&lt;/a&gt;), so you may have to use npm for that anyway.&lt;/p&gt;

&lt;h3&gt;
  
  
  What about WSL?
&lt;/h3&gt;

&lt;p&gt;If you're coming from linux you might be tempted to try running the regular nvm on WSL. It might work for you, but I personally had many issues with it, so I don't recommend it. WSL2 might solve those issues though, so fingers crossed.&lt;/p&gt;

&lt;h3&gt;
  
  
  More info
&lt;/h3&gt;

&lt;p&gt;If you need further information, run &lt;code&gt;nvm&lt;/code&gt; without any arguments to show the list of available commands or visit the GitHub page of the project: &lt;a href="https://github.com/coreybutler/nvm-windows" rel="noopener noreferrer"&gt;https://github.com/coreybutler/nvm-windows&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Thanks for reading
&lt;/h3&gt;

&lt;p&gt;When I first found nvm-windows I thought it would be hacky and difficult to set up, but it surprised me, so I decided to write this to show others how easy node version management actually is on Windows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Other articles you might enjoy
&lt;/h3&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/hadrysmateusz" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F181202%2Ffe857a32-d940-4cdb-9d8f-719b165dc573.png" alt="hadrysmateusz"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/hadrysmateusz/how-to-get-all-characters-in-a-string-57c7" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;4 Ways to Get All Characters in a String in JavaScript&lt;/h2&gt;
      &lt;h3&gt;Mateusz Hadryś ・ Aug 17 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#beginners&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#programming&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;



&lt;div class="ltag__link"&gt;
  &lt;a href="/hadrysmateusz" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F181202%2Ffe857a32-d940-4cdb-9d8f-719b165dc573.png" alt="hadrysmateusz"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="/hadrysmateusz/custom-list-styles-using-marker-before-4gi4" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Beautiful Custom List Styles Using Modern CSS&lt;/h2&gt;
      &lt;h3&gt;Mateusz Hadryś ・ Oct 12 '20&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#css&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#design&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>node</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
