The State of CSS 2019

The State of CSS 2019

The State of CSS 2019

We surveyed over 11,000 CSS developers. Here’s what we learned.

➡️ View the Survey Results

The Story

It all started three years ago when I was faced with a tough choice: deciding which JavaScript library to learn next. Picking the wrong option could potentially mean investing hundreds of hours into a doomed technology, so I thought I'd ask around before committing to a new framework.

Asking around turned into launching a small developer survey, which in turn got a surprising amount of interest from the community. Fast-forward three years and we're now onto our third State of JavaScript survey, with a reach of over 20,000 developers!

But as the survey has grown in depth and length, we've also realized just how complex the web ecosystem truly is. And that while JavaScript is a big part of it, it's by no means the only one.

Which is why it only made sense to expand horizontally into new territories, the first of which is CSS, a.k.a. JavaScript's arch-nemesis and/or best friend depending on who you ask.

And after a few months of data processing and visualizing, I'm happy to finally be able to share with you the first ever State of CSS survey results!

The Trends

I definitely encourage you to check out the full results, but in the meantime here are a few trends we noticed looking at the data.

Flexbox is “Winning”… But for How Long?

Layout Features Overview

While Flexbox and CSS Grid both have near-total awareness (in other words, everybody knows what they are), it's interesting to see that only about 55% of developers have actually used Grid.

There are a few probably reasons for this. Flexbox has been around for longer, and came around at a time where we desperately needed an alternative to floats for layout. Also, Grid is admittedly a little bit more complex (but also much more powerful!).

The truth is that both Grid and Flexbox have their pros and cons, and they should both be part of a developer's toolbox. So it wouldn't surprise us if those two circles become much more similar over the next couple years!

Utility-First CSS is on the Rise; Bootstrap is in a Slump

Ranking CSS frameworks for awareness, interest, and satisfaction

For years Bootstrap was the uncontested king of UI frameworks. This shows up clearly in our data, with a whopping 99% of respondents being aware of it. No other competitor comes close in terms of awareness, with second-best Foundation coming in at “just” 79%.

It shouldn't be surprising that this high awareness corresponds with a low interest ratio, since developers who haven't yet used Bootstrap for whatever reason are probably not that keen to start now. More worrying is the comparatively low satisfaction ratio, at just 52%.

Contrast this with Tailwind, which boasts a 81% satisfaction ratio! It might have a low awareness score (only 34% of respondents knew about it), but it's making its users very happy and at the end of the day that's the most important factor. And right behind it with 74% is Bulma, which shares a lot of the same “utility-first” concepts as Tailwind.

Are we moving away from big, monolithic frameworks like Bootstrap towards more nimble, pick-what-you-want libraries like Tailwind? In any case, it'll definitely be interesting to keep an eye on this trend over the next few years.

There's Still a lot of Uncertainty in CSS Land

Plotting satisfaction percentages vs user counts

The above chart of CSS technologies is divided into four quadrants, and as you can see the “Assess” quadrant (corresponding to up-and-coming technologies with low user counts but high satisfaction) is by far the busiest.

In fact there are only three “established” technologies in the “Adopt” quadrant (high usage, high satisfaction): BEM, Sass, and Bootstrap. And Bootstrap is getting dangerously close to falling off…

This goes to show that things are still very much in flux in the CSS world, which can be surprising for an ecosystem that has been around for so long. But this is the world of web development after all: as soon as you think you've finally figured it out, something new comes along and makes you question everything you thought you knew!

Catch Up on the State of JavaScript

Speaking of other surveys, you should check out our 2018 State of JavaScript survey results if you haven't already. We promise you'll learn a thing or two!

The State of JavaScript 2018

The State of CSS on The Changelog

If you're a podcast listener, keep an eye out for my appearance on The Changelog, where I talk more about the data, address some controversies about our data collection process, and give you a behind-the-scenes look at our tech stack.

Stay Tuned

Finally, if you want to make sure you don't miss a chance to take part in upcoming survey (or know when we publish additional data), be sure to sign up for our (very infrequent) mailing list. After all the more respondents we have, the more useful our data will be!

7 Best Vue CSS Component for Your App

7 Best Vue CSS Component for Your App

Vue CSS frameworks are great for many reasons; code is more universally understood, web applications are easier to maintain, and prototyping becomes less of an extra step.

Vue CSS frameworks are great for many reasons; code is more universally understood, web applications are easier to maintain, and prototyping becomes less of an extra step and more part of the development process.

1. Tailwindcss-Vue

Tailwindcss-Vue is a library of UI components for Vue.js built using the Tailwind CSS utility-first CSS framework.


2. @zeit-ui/vue

Vue implementation for Zeit Style, originating from Zeit Design.

@zeit-ui/vue is a Vue implementation for zeit style, originating from Zeit Design. Lean more at GITHUB.

The design of the Zeit is concise and aesthetic feeling, this is an important reason for popular of Zeit. Now you can use them through the @zeit-ui/vue.


3. CSSeffectsSnippets

Click on the animation to copy it to your clipboard



4. Vue Cirrus

A fully responsive and comprehensive CSS framework with beautiful controls and simplistic structure. Cirrus is designed to be adaptable to existing themes or when starting fresh. These are the Vue Components for this CSS framework.



5. Vue CSS Modules

Seamless mapping of class names to CSS modules inside of Vue components.


6. BG MixMaster 90 — CSS Background Grid /Pattern Generator

make a background grid (like graph paper) using only one background gradient property and ended up with this killer mix tape for making all kinds of background grids and patterns.



CSS Rules from JS, change rules dynamically, CSSOM, css modules, auto vendor prefixer, media query for old browsers.

CSS in JS solution, create CSSOM and CSS rules from js, features:

  • CSS Rules create and diff
  • CSS modules with local class
  • Auto vendor prefixer
  • Media query for old browsers
  • Dynamically change CSS



Using CSS Quickies - CSS variables

Using CSS Quickies - CSS variables

Quickies CSS Tutorial: CSS Variables - How to create white - dark themes easily

What is CSS Quickes?

I started to ask my beloved community on Instagram: "what CSS properties are confusing for you?"

In "CSS Quickies" I will explain one CSS property in deep. These are community requested properties.

I'm also live streaming while coding on if you want to spend some fun time or you can ask me any question!

Let's talk about Custom properties aka CSS Variables.

Finally! If you ever have worked with CSS and wanted to keep your design consistent? Or was it more like at some pages, your website had different padding, margin or colors?

Maybe you wanted to implement a dark theme? It was possible, but now it has become easier!

Of course, if you have used LESS or SASS, then you know variables, and now they are finally supported natively. 😁

Let's have a look at it!

Defining a CSS variable

You define a CSS variable with prefixing a CSS property with --. Let's look at some examples.

  --example-color: #ccc;
  --example-align: left;
  --example-shadow: 10px 10px 5px 0px rgba(0,0,0,0.75);

Your first question is: "What is that ':root' pseudo-class?".

Good question! The :root pseudo-class is as you would use the html selector except that the specificity is higher of the ':root' pseudo-class. This means that if you set properties in the :root pseudo-class it will win over the html selector.

Okay, the rest is pretty simple. The custom property --example-color has the value of #ccc. When we use the custom property, for example, on the background-color property, the background of that element will be a light gray. Cool right?

You can give the custom property, aka CSS variable every value you could give any other property in CSS. It is okay to use left for example or 10px and so on.

Using CSS variables

Now that we know how to set CSS variables, we need to learn how to use them!

For this, we need to learn the var() function.

The var() can have two arguments. The first argument needs to be a custom property. If the custom property is not valid, you want to have a fallback value. To achieve this, you simply need to set the second argument of the var() function. Let's look at an example.

  --example-color: #ccc;

.someElement {
background-color: var(--example-color, #d1d1d1);

This should be now pretty straightforward for you to understand. We are setting the --example-color to #ccc and then we are using it in .someElement to set the background color. If something goes wrong and our --example-color is not valid, we have a fallback value of #d1d1d1.

What happens if you don't set a fallback value and your custom variable is invalid? The browser then will act as if this property was not specified and do its regular job.

Tips and tricks
Multiple fallback values

What if you want to have multiple fallback values? So you would think you could do the following:

.someElement {
background-color: var(--first-color, --second-color, white);

This will not work. After the first comma var() treats everything even the commas as a value. The browser would change this into background-color: --second-color, white;. This is not what we want.

To have multiple values, we can simply call var() inside a var(). Here comes an example:

.someElement {
background-color: var(--first-color, var(--second-color, white));

Now this would produce our desired outcom. When both --first-color and --second-color are invalid then the browser will set the background to white.

What if my fallback value needs a comma?

What to do if for example, you want to set a font-family in in the fallback value and you need to specify more then one font? Looking back at the tip before this should be now straight forward. We simply write it with the commas. Example time:

.someElement {
font-family: var(--main-font, "lucida grande" , tahoma, Arial);

Here we can see the after the first comma the var() function treats everything like one value.

Setting and getting custom properties in Javascript

In more complex apps and websites, you will javascript for state management and rendering. You also can get and set custom properties with javascript. Here is how you can do it:

    const element = document.querySelector('.someElement');
// Get the custom propety"--first-color");
// Set a custom propety"--my-color", "#ccc");

We can get and set the custom properties like any other property. Isn't that cool?

Making a theme switcher with custom variables

Let's first have a look at what we will do here:

The HTML markup
<div class="grid theme-container">
<div class="content">
<div class="demo">
<label class="switch">
<input type="checkbox" class="theme-switcher">
<span class="slider round"></span>

Really nothing special here.

We will use CSS grid to center the content that's why we have a .grid class on our first element the .content and .demo Classes are just for styling. The two crucial classes here are .theme-container and .theme.switcher.

The Javascript code
const checkbox = document.querySelector(".theme-switcher");

checkbox.addEventListener("change", function() {
const themeContainer = document.querySelector(".theme-container");
if (themeContainer && this.checked) {
} else {

First we are selecting our .theme-switcher input and the .theme-container element.

Then we are adding an event listener that listens if a change happens. This means that every time you click on the input, the callback for that event listener will run.

In the if clause we are checking if there is a .themeContainer and if the checkbox input is checked.

When this check is true, we are adding the .light class to the .themeContainer and if it is false, we are removing it.

Why are we removing and adding the .light Class? We will answer this now.

The CSS code

Since this code is lengthy, I will show it to you step by step!

.grid {
display: grid;
justify-items: center;
align-content: center;
height: 100vh;
width: 100vw;

Lets first center our content. We are doing this with css grid. We will cover the grid feature in another CSS quickies!

:root {
/* light /
--c-light-background: linear-gradient(-225deg, #E3FDF5 0%, #FFE6FA 100%);
--c-light-checkbox: #fce100;
dark */
--c-dark-background:linear-gradient(to bottom, rgba(255,255,255,0.15) 0%, rgba(0,0,0,0.15) 100%), radial-gradient(at top center, rgba(255,255,255,0.40) 0%, rgba(0,0,0,0.40) 120%) #989898;
--c-dark-checkbox: #757575;

Puh this is a lot of code and numbers but actually we are not doing much here. We are preparing our custom properties to be used for our theme. --c-dark- and --c-light- is what I have chosen to prefix my custom properties. We have defined a light and a dark theme here. For our example we just need the checkbox color and the background property which is a gradient in our demo.

.theme-container {
--c-background: var(--c-dark-background);
--c-checkbox: var(--c-dark-checkbox);
background: var(--c-background);
background-blend-mode: multiply,multiply;
transition: 0.4s;
.theme-container.light {
--c-background: var(--c-light-background);
--c-checkbox: var(--c-light-checkbox);
background: var(--c-background);

Here comes an integral part of the code. We now see why we named the .theme-container How we did. It is our entrance to have now global custom variables. We don't want to use the specific custom variables. What we want is to use global custom variables. This is why we are setting --c-background. From now on, we will only use our global custom variables. Then we are setting the background.

.demo {
font-size: 32px;

/* The switch - the box around the slider */
.switch {
position: relative;
display: inline-block;
width: 60px;
height: 34px;

/* Hide default HTML checkbox /
.switch .theme-switcher {
opacity: 0;
width: 0;
height: 0;

This is just some boilerplate code to set our style. In the .demo selector, we are setting the font-size. This is the size of our symbols for the toggle. In the .switch selector the height and width is how long and wide the element behind our toggle symbol is.

/ The slider */
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--c-checkbox);
transition: 0.4s;

.slider:before {
position: absolute;
content: "🌑";
height: 0px;
width: 0px;
left: -10px;
top: 16px;
line-height: 0px;
transition: 0.4s;

.theme-switcher:checked + .slider:before {
left: 4px;
content: "🌞";
transform: translateX(26px);

Here we can finally see our custom properties in action besides using them directly in the .theme.container and again a lot of boilerplate code. As you can see, the toggle symbols are simple Unicode symbols. This is why the toggle will look different on every OS and mobile phone vendor. You have to keep this in mind. Important to know here is that in the .slider:before Selector, we are moving our symbol around with the left and top properties. We are doing that also in the .theme-switcher:checked + .slider:before but only with the left property.

/* Rounded sliders */
.slider.round {
border-radius: 34px;

This again is just for styling. To make our switch rounded on the corners.

That is it! We now have a theme switcher which is extendable. ✌😀

Originally published by lampewebdev at


Thanks for reading :heart: If you liked this post, share it with all of your programming buddies! Follow me on Facebook | Twitter

The ultimate CSS battle: Grid - Flexbox

Build a Custom Full Page Slider with CSS and JavaScript

The main differences between Flexbox and CSS Grid