Sarah Dayan

Follow this blog

Using State Machines in Vue.js with XState

While state machines used to be an obscure model for the front-end world, it has gained quite some traction lately, mostly thanks to XState. XState is a JavaScript state machine implementation created by Microsoft engineer David Khourshid. I met David at dotCSS 2019, where he talked about crafting stateful styles using finite state machines. During his talk, David asked: “is there a better way to model state for dynamic UIs?” After all, state is at the center of what we, front-end engineers, deal with every day. Think of when you set an app to dark mode, when you load the latest purchases from a given user, or when you momentarily disable a button during data fetching: all you do is managing state. User flows are transitions between UI states, caused by events. There are many ways to represent state in modern web applications. In Vue.js, you can use local state (encapsulated within components) or global state (using a state management library like Vuex). Wherever you put your state, it usually works the same way: you represent it with properties that you can change, and you use these properties to determine view logic. Password Modal with Finite State Machine by David Khourshid Think, for instance, of a password-protected resource. You can input a password and submit it. While it’s being validated on the server, the UI goes in a loading state, and you can’t interact with it. If the password is invalid, the UI goes in an error state, maybe showing an error message and outlining the input in red, but lets you try again. Finally, when you submit the right password, the UI goes into a success state and moves on to the unlocked resource. All these scenarios can be solved with event listeners and if statements. In a Vue.js application, you could model this with the data object and computed properties, which would change based on user events and Promise resolutions. Yet, as the application would grow, this could quickly turn into a tangled mess: new conditions, new events, new corner cases, and before you know it, you end up with contradictory instructions that set your view in an inconsistent state. This is what state machines and XState attempt at solving. State machines are a tried and tested mathematical model, invented long before JavaScript. They let you model the behavior of a system that can be in only one state at any given time (not several, not none). There’s a finite number of possible states, which are triggered by a finite number of possible events. Going from a state to another is called a transition. Instead of defining imperative UI flows, and lose track of their logic, state machines make them first-class citizens by letting you model them declaratively. They’re the closest thing to an actual flowchart, which is how a product manager or a UI designer would likely design the experience of a product. State machines in Vue XState works within any JavaScript and TypeScript project, including Vue. We’ll build a simple Markdown editor, which renders a live preview. The live preview displays the HTML render, can switch to the HTML code, or be collapsed. Markdown Editor built with Vue.js and XState Let’s create a brand new project with Vue CLI, with the default settings. vue create markdown-editor-vue-xstate Install the necessary dependencies: XState, as well as markdown-it and indent.js to render the Markdown. cd markdown-editor-vue-xstate yarn add xstate markdown-it indent.js Great! Let’s quickly bootstrap the application to have a working prototype. Open the App.vue file, and replace the boilerplate with the following code: <template> <div id="app"> <textarea v-model="content" /> <div v-html="rendered" /> <pre>{{ raw }}</pre> </div> </template> <script> import MarkdownIt from "markdown-it"; import { indent } from "indent.js"; const md = new MarkdownIt(); export default { name: "App", data() { return { content: "# Hello there!\n\n- Type some Markdown on the left\n- See HTML in the right\n- Magic\n\n![An orange jellyfish](https://i.picsum.photos/id/1069/400/250.jpg)" }; }, computed: { rendered() { return md.render(this.content); }, raw() { return indent.html(this.rendered, { tabString: " " }); } } }; </script> Great, time to bring XState. We’re currently displaying the rendered Markdown as interpreted HTML, and the raw HTML. What about toggling between both? Or collapse the render to extend the editor in full screen? We can use a state machine to model this. <script> import { createMachine, interpret } from "xstate"; const toggleMachine = createMachine({ id: "toggle", initial: "rendered", states: { rendered: { on: { SWITCH: "raw" } }, raw: { on: { SWITCH: "rendered" } } } }); export default { data() { return { // … toggleService: interpret(toggleMachine), current: toggleMachine.initialState }; }, created() { this.toggleService .onTransition(state => { this.current = state; }) .start(); } }; </script> Let’s analyze this code. First, we import createMachine and interpret. createMachine is a factory function that lets us create state machines, while interpret allows us to parse and execute it in a runtime environment. An interpreted, running instance of a statechart is a service, which we add to our data object as the toggleService property. When we start the application, we set a listener for transitions with the onTransition method, which we use to assign the new state on a current property, which we initialize to the initial state of the machine. In other words, every time we’ll dispatch an event to the state machine (resulting in a transition), we’ll also update our reactive Vue state with the state of the machine. Now let’s look at the machine itself. const toggleMachine = createMachine({ id: "toggle", initial: "rendered", states: { rendered: { on: { SWITCH: "raw" } }, raw: { on: { SWITCH: "rendered" } } } }); Our machine has two states; rendered, which corresponds to rendered Markdown, and raw, which represents the raw HTML output. Each state node has an on property, containing a mapping of all possible transitions. When receiving the SWITCH event while the machine is on the rendered state, the machine transitions to raw, and vice versa. We also set an initial state, rendered. A state machine must always have a state; it can’t be undefined. This creates our first user flow and starts defining the application state that we can use it in our template. <template> <div id="app"> <textarea v-model="content" /> <div v-show="current.matches('rendered')" v-html="rendered" /> <pre v-show="current.matches('raw')" > {{ raw }} </pre> </div> </template> Remember, we’re exposing our service on the current reactive property. This allows us to use the matches method to define view logic based on the current state. In our case, we’re showing the rendered Markdown when the state is rendered, and the raw HTML when the state is raw. Let’s add a button to transition between states. <template> <div id="app"> <!-- … --> <button @click="send('SWITCH')"> {{ current.matches('raw') ? 'Show rendered Markdown' : 'Show HTML code' }} </button> </div> </template> <script> export default { // … methods: { send(event) { this.toggleService.send(event); } } } </script> Now, when clicking the button, we’ll send a SWITCH event to the service. When the current state is rendered, it transitions to raw, and vice versa. As a result, the UI toggles between rendered Markdown and raw HTML. Great! What about creating a focus mode now, and allowing the user to fully collapse the preview? This is where nested states and statecharts come into play. Statecharts Statecharts are extended state machines. They introduce additional useful concepts, including nested states. This allows us to compose states into logical groups. In our case, we want to implement a focus mode where we can collapse the preview. This means that, in addition to being either rendered or raw, the preview can also be visible or hidden. Yet, these two new states aren’t independent of the first two: they condition them. The preview can only be rendered or raw if it was first visible. This is what nested states allow us to do; encapsulate a set of states within another. Let’s add our new visible and hidden states at the root of the machine, and nest our existing rendered and raw within visible. const toggleMachine = createMachine({ id: "toggle", initial: "visible", states: { visible: { on: { TOGGLE: "hidden" }, initial: "rendered", states: { rendered: { on: { SWITCH: "raw" } }, raw: { on: { SWITCH: "rendered" } } } }, hidden: { on: { TOGGLE: "visible" } } } }); We’ve also created a new TOGGLE event which switches between visible and hidden. The visible state automatically moves on to its initial child state, rendered. “Wait… I thought state machines could only be in one state at a time!” Indeed, state machines are always in a single state at a time. Statecharts don’t change that; yet, they introduce the concept of composite states. In our case, the visible state is a composite state, composed of sub-states. In XState, this means that our machine can be in state hidden, visible.rendered, and visible.raw. At this stage, it might become hard to visualize the entire flow. Fortunately, XState provides a nifty tool: the visualizer. This lets you paste any XState state machine, and instantly get an interactive visualization. Here, we have a clear vision of our user flow. We know what we can and can’t do, when we can do it, and in what state it results. You can use such a tool to debug your statecharts, pair program with fellow developers, and communicate with designers and product managers. We can now use the new states in our template to implement the focus mode. <template> <div id="app"> <textarea v-model="content" /> <div v-show="current.matches('visible.rendered')" v-html="rendered" /> <pre v-show="current.matches('visible.raw')" > {{ raw }} </pre> <button @click="send('SWITCH')"> {{ current.matches('visible.raw') ? 'Show rendered Markdown' : 'Show HTML code' }} </button> <button @click="send('TOGGLE')"> {{ current.matches('hidden') ? 'Show preview' : 'Hide preview' }} </button> </div> </template> Neat! We can now entirely toggle the preview. Now, if you’re testing your application in the browser, you’ll notice that when you do, you always go back to the initial rendered state, even though you switched it to raw before hiding the preview. Better user experience would be to automatically go back to the latest substate when transitioning to visible. Fortunately, statecharts let us manage this with history nodes. History A history state node is a particular node that, when you reach it, tells the machine to go to the latest state value of that region. You can have shallow history nodes (default), which save only the top-level history value, and deep history nodes, which save the entire nested hierarchy. History is a compelling feature that allows us to memorize in which state we left the preview and resume it whenever we make it visible. Let’s add it to our state machine. const toggleMachine = createMachine({ // … states: { visible: { // … states: { // … memo: { type: "history" } } }, hidden: { on: { TOGGLE: "visible.memo" } } } }); Now, whenever the machine receives a TOGGLE event while hidden, it resumes the latest substate of visible. Our application works well, but it lacks an important feature: state persistence. When you’re using a tool often, it’s pleasant to have it “remember” our preferences. XState lets us achieve that with state resolution. Persisting and rehydrating state An XState state is a plain, serializable object literal, which means we can persist it as JSON in a web storage system such as LocalStorage and resume it when the user comes back to the application. First, let’s save our state every time a transition happens. It ensures we never “miss” a state change. export default { // … created() { this.toggleService .onTransition(state => { this.current = state; try { const state = JSON.stringify(this.current) localStorage.setItem("state", state); } catch () { console.error("Local storage is unavailable."); } }) .start(); }, }; If the LocalStorage is available (not full, and the browser is not in incognito mode), we persist the current state of the machine as JSON inside it. We can now use it to hydrate the machine when we start it. import { createMachine, State, interpret } from 'xstate'; // … const savedState = JSON.parse(localStorage.getItem("state")); const previousState = State.create(savedState || toggleMachine.initialState); const resolvedState = toggleMachine.resolveState(previousState); // … export default { // … created() { this.toggleService // … .start(resolvedState); }, }; If there’s nothing in the LocalStorage, we use the initial state of the machine. Otherwise, we use the resolved persisted state. If you try this in your browser, change the state, then refresh, you’ll start from where you left off. Note that state persistence and data persistence are two different things. We’re currently saving our application state, not the data (the typed Markdown) because this is out of the scope of a state machine. Data state is, by definition, infinite; it doesn’t belong to a finite state machine. To persist data automatically, you can use Vue watchers to observe the content data property, and save it to the LocalStorage when it changes. Remember that such operations are slow and synchronous; I recommend you debounce them. Is it worth it? State machines model the concept of state, and gives it a framework to properly think about it. It’s a shift of mental model which brings many advantages, including the reliability of decades of mathematical formalism. Additionally, it lets you look at state as a self-contained flow chart, which makes it easier to visualize and share with non-developers. You probably don’t need state machines in every project, especially those with minimal state, or when it doesn’t change much. However, they may have a clear advantage over other kinds of state management libraries, if you need such a mechanism in your project. XState has many more great features to discover, we barely scratched the surface here. If XState in Vue looks like too much boilerplate, know that it also ships Vue bindings for the Vue 3 Composition API. You can use this flavor to create state machines in your Vue applications with terser, more functional code. You can also find the final code from this tutorial on GitHub.

An Introduction to TDD with Vue.js

TDD is a process where you write tests before you write the associated code. You first write a test that describes an expected behavior, and you run it, ensuring it fails. Then, you write the dumbest, most straightforward code you can to make the test pass. Finally, you refactor the code to make it right. And you repeat all the steps for each test until you’re done. This approach has many advantages. First, it forces you to think before you code. It’s commonplace to rush into writing code before establishing what it should do. This practice leads to wasting time and writing complicated code. With TDD, any new piece of code requires a test first, so you have no choice but take the time to define what this code should do before you write it. Secondly, it ensures you write unit tests. Starting with the code often leads to writing incomplete tests, or even no tests at all. Such a practice usually happens as a result of not having precise and exhaustive specs, which leads to spending more time coding than you should. Writing tests becomes a costly effort, which is easy to undermine once the production code is ready. Unit tests are critical to building robust code. Overlooking or rushing them increases chances of your code breaking in production at some point. Why do TDD for components? Testing a component can be counter-intuitive. As we saw in Unit Test Your First Vue.js Component, it requires a mental shift to wrap your head around testing components versus testing plain scripts, knowing what to test, and understanding the line between unit tests and end-to-end. TDD makes all this easier. Instead of writing tests by examining all bits and pieces of a finished project and trying to guess what you should cover, you’re doing the opposite. You’re starting from actual specs, a list of things that the component should do, without caring about how it does it. This way, you’re ensuring that all you test is the public API, but you’re also guaranteeing you don’t forget anything. In this tutorial, we’ll build a color picker. For every swatch, users can access the matching color code, either in hexadecimal, RGB, or HSL. Design inspired from Custom Color Picker Exploration by Chris Castillo Despite its apparent simplicity, there are a bunch of small pieces of logic to test. They require some thinking before jumping into code. In this article, we’ll deep dive into TDD. We’ll put some specs together before we write a single line of code. Then, we’ll test every public feature in a test-driven fashion. Finally, we’ll reflect on what we did and see what we can learn from it. Before we start This tutorial assumes you’ve already built something with Vue.js before, and written unit tests for it using Vue Test Utils and Jest (or a similar test runner). It won’t go deeper into the fundamentals, so make sure you get up to speed first. If you’re not there yet, I recommend you go over Build Your First Vue.js Component and Unit Test Your First Vue.js Component. TL;DR: this post goes in-depth in the how and why. It’s designed to help you understand every decision behind testing a real-world Vue.js component with TDD and teach you how to make design decisions for your future projects. If you want to understand the whole thought process, read on. Otherwise, you can go directly to the afterthoughts at the end, or look at the final code on GitHub. Write down your specs Before you even write your first test, you should write down an overview of what the component should do. Having specs makes testing much more straightforward since you’re mostly rewriting each spec in the form of tests. Let’s think about the different parts that compose our component, and what they should do. First, we have a collection of color swatches. We want to be able to pass a list of custom colors and display as swatches in the component. The first one should be selected by default, and the end user can select a new one by clicking it. Secondly, we have the color mode toggler. The end user should be able to switch between three modes: hexadecimal (default), RGB and HSL. Finally, we have the color code output, where the end user can get the code for the currently selected color swatch. This code is a combination of the selected swatch and color mode. Thus, by default, it should display the first swatch as a hexadecimal value. When changing any of these, the code should update accordingly. As you can see, we don’t go too deep into details; we don’t specify what the color mode labels should be, or what the active state looks like for the color swatches. We can make most of the small decisions on the fly, even when doing TDD. Yet, we’ve come from a simple definition of what the component should be, to a comprehensive set of specs to start from. Write test-driven code First, you need to create a new Vue project with Vue CLI. You can check Build Your First Vue.js Component if you need a step by step guide. During the scaffolding process, manually select features and make sure you check Unit testing. Pick Jest as your testing solution, and proceed until the project is created, dependencies are installed, and you’re ready to go. We’ll need to use SVG files as components, so you also need to install the right loader for them. Install vue-svg-loader as a dev dependency, and add a rule for it in your vue.config.js file. // vue.config.js module.exports = { chainWebpack: config => { const svgRule = config.module.rule('svg') svgRule.uses.clear() svgRule.use('vue-svg-loader').loader('vue-svg-loader') } } This loader doesn’t play well with Jest by default, which causes tests to throw. To fix it, create a svgTransform.js file as documented on the website, and edit your jest.config.js as follows: // svgTransform.js const vueJest = require('vue-jest/lib/template-compiler') module.exports = { process(content) { const { render } = vueJest({ content, attrs: { functional: false } }) return `module.exports = { render: ${render} }` } } // jest.config.js module.exports = { // ... transform: { // ... '.+\\.(css|styl|less|sass|scss|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub', '^.+\\.svg$': '<rootDir>/svgTransform.js' }, // ... } Note that we’ve removed “svg” from the first regular expression (the one that gets transformed with jest-transform-stub). This way, we ensure SVGs get picked up by svgTransform.js. Additionally, you need to install color-convert as a dependency. We’ll need it both in our code and in our tests later on. Don’t serve the project yet. We’re going to write tests and rely on them passing or not to move on. We don’t want to control whether what we build works by testing it visually in the browser, nor being distracted by how it looks. Instead, open your project and create a new ColorPicker.vue single-file component in the src/components/ directory. In tests/unit/, create its associated spec file. <!-- ColorPicker.vue --> <template> <div></div> </template> <script> export default {} </script> <style> </style> // ColorPicker.spec.js import { shallowMount } from '@vue/test-utils' import ColorPicker from '@/components/ColorPicker' describe('ColorPicker', () => { // let's do this! }) In your terminal, execute the following command to run tests: npm run test:unit --watchAll For now, you should get an error because you don’t yet have tests. Don’t worry though; we’ll fix this shortly 🙂 Note the usage of the --watchAll flag in the command: Jest is now watching your files. This way, you won’t have to re-run test by hand. TDD goes in 3 stages: Red: you write a test that describes an expected behavior, then you run it, ensuring it fails. Green: you write the dumbest, most straightforward code you can to make the test pass. Refactor: you refactor the code to make it right. Step 1: Red Time to write our first test! We’ll start with the color swatches. For clarity, we’ll wrap all tests for each distinct element in their own suite, using a describe block. First, we want to make sure that the component displays each color that we provide as an individual swatch. We would pass those as props, in the form of an array of hexadecimal strings. In the component, we would display the list as an unordered list, and assign the background color via a style attribute. import { shallowMount } from '@vue/test-utils' import ColorPicker from '@/components/ColorPicker' import convert from 'color-convert' let wrapper = null const propsData = { swatches: ['e3342f', '3490dc', 'f6993f', '38c172', 'fff'] } beforeEach(() => (wrapper = shallowMount(ColorPicker, { propsData }))) afterEach(() => wrapper.destroy()) describe('ColorPicker', () => { describe('Swatches', () => { test('displays each color as an individual swatch', () => { const swatches = wrapper.findAll('.swatch') propsData.swatches.forEach((swatch, index) => { expect(swatches.at(index).attributes().style).toBe( `background: rgb(${convert.hex.rgb(swatch).join(', ')})` ) }) }) }) }) We mounted our ColorPicker component and wrote a test that expects to find items with a background color matching the colors passed as props. This test is bound to fail: we currently have nothing in ColorPicker.vue. If you look at your terminal, you should have an error saying that no item exists at 0. This is great! We just passed the first step of TDD with flying colors. Step 2: Green Our test is failing; we’re on the right track. Now, time to make it pass. We’re not much interested in writing working or smart code at this point, all we want is to make Jest happy. Right now, Vue Test Utils complains about the fact that we don’t event have no item at index 0. [vue-test-utils]: no item exists at 0 The simplest thing we can do to make that error go away is to add an unordered list with a swatch class on the list item. <template> <div class="color-picker"> <ul class="swatches"> <li class="swatch"></li> </ul> </div> </template> Jest still complains but the error has changed: Expected value to equal: "background: rgb(227, 52, 47);" Received: undefined This makes sense; the list item doesn’t have a style attribute. The simplest thing we can do about it is to hardcode the style attribute. This isn’t what we want in the end, but, we aren’t concerned about it yet. What we want is for our test to go green. We can therefore hardcode five list items with the expected style attributes: <ul class="swatches"> <li class="swatch" style="background: rgb(227, 52, 47);"></li> <li class="swatch" style="background: rgb(52, 144, 220);"></li> <li class="swatch" style="background: rgb(246, 153, 63);"></li> <li class="swatch" style="background: rgb(56, 193, 114);"></li> <li class="swatch" style="background: rgb(255, 255, 255);"></li> </ul> The test should now pass. Step 3: Refactor At this stage, we want to rearrange our code to make it right, without breaking tests. In our case, we don’t want to keep the list items and their style attributes hardcoded. Instead, it would be better to receive swatches as a prop, iterate over them to generate the list items, and assign the colors as their background. <template> <div class="color-picker"> <ul class="swatches"> <li :key="index" v-for="(swatch, index) in swatches" :style="{ background: `#${swatch}` }" class="swatch" ></li> </ul> </div> </template> <script> export default { props: { swatches: { type: Array, default() { return [] } } } } </script> When tests re-run, they should still pass 🥳 This means we’ve successfully refactored the code without affecting the output. Congratulations, you’ve just completed your first TDD cycle! Now, before we go to the next test, let’s reflect a bit. You may be wondering: “Isn’t this a bit dumb? I knew the test would fail. Am I not wasting time by running it anyway, then hardcoding the right value, see the test pass, then make the code right? Can’t I go to the refactor step directly?” It’s understandable that you’re feeling confused by the process. Yet, try to look at things from a different angle: the point here isn’t to prove that the test doesn’t pass. We know it won’t. What we want to look at is what our test expects, make them happy in the simplest possible way, and finally write smarter code without breaking anything. That’s the whole idea of test-driven development: we don’t write code to make things work, we write code to make tests pass. By reversing the relationship, we’re ensuring robust tests with a focus on the outcome. What are we testing? Another question that may come to mind is how we’re deciding what to test. In Unit Test Your First Vue.js Component, we saw that we should only be testing the public API of our component, not the internal implementation. Strictly speaking, this means we should cover user interactions and props changes. But is that all? For example, is it okay for the output HTML to break? Or for CSS class names to change? Are we sure nobody is relying on them? That you aren’t yourself? Tests should give you confidence that you aren’t shipping broken software. What people can do with your program shouldn’t stop working the way they expect it to work. It can mean different things depending on the project and use case. For example, if you’re building this color panel as an open source component, your users are other developers who use it in their own projects. They’re likely relying on the class names you provide to style the component to their liking. The class names become a part of your public API because your users rely on them. In our case, we may not necessarily be making an open source component, but we have view logic that depends on specific class names. For instance, it’s important for active swatches to have an active class name, because we’ll rely on it to display a checkmark, in CSS. If someone changes this by accident, we want to know about it. Testing scenarios for UI components highly depend on the use case and expectations. Whichever the case, what you need to ask yourself is do I care about this if it changes? Next tests Testing the swatches Let’s move on to the next test. We expect the first swatch of the list to be the one that’s selected by default. From the outside, this is something that we want to ensure keeps on working the same way. Users could, for instance, rely on the active class name to style the component. test('sets the first swatch as the selected one by default', () => { const firstSwatch = wrapper.find('.swatch') expect(firstSwatch.classes()).toContain('active') }) This test, too, should fail, as list items currently don’t have any classes. We can easily make this pass by adding the class on the first list item. <li :key="index" v-for="(swatch, index) in swatches" :style="{ background: `#${swatch}` }" class="swatch" :class="{ 'active': index === 0 }" ></li> The test now passes; however, we’ve hardcoded the logic into the template. We can refactor that by externalizing the index onto which the class applies. This way, we can change it later. export default { // ... data() { return { activeSwatch: 0 } } } <li :key="index" v-for="(swatch, index) in swatches" :style="{ background: `#${swatch}` }" class="swatch" :class="{ active: index === activeSwatch }" ></li> This naturally leads us to our third test. We want to change the active swatch whenever the end user clicks it. test('makes the swatch active when clicked', () => { const targetSwatch = wrapper.findAll('.swatch').at(2) targetSwatch.trigger('click') expect(targetSwatch.classes()).toContain('active') }) For now, nothing happens when we click a swatch. However, thanks to our previous refactor, we can make this test go green and even skip the refactor step. <li :key="index" v-for="(swatch, index) in swatches" :style="{ background: `#${swatch}` }" class="swatch" :class="{ active: index === activeSwatch }" @click="activeSwatch = index" ></li> This code makes the test pass and doesn’t even need a refactor. This is a fortunate side-effect of doing TDD: sometimes, the process leads to either writing new tests that either don’t need refactors, or even that pass right away. Active swatches should show a checkmark. We’ll add it now without writing a test: instead, we’ll control their visibility via CSS later. This is alright since we’ve already tested how the active class applies. First, create a checkmark.svg file in src/assets/. <svg viewBox="0 0 448.8 448.8"> <polygon points="142.8 323.9 35.7 216.8 0 252.5 142.8 395.3 448.8 89.3 413.1 53.6"/> </svg> Then, import it in the component. import CheckIcon from '@/assets/check.svg' export default { // ... components: { CheckIcon } } Finally, add it inside the list items. <li ... > <check-icon /> </li> Good! We can now move on to the next element of our component: the color mode. Testing the color mode Let’s now implement the color mode toggler. The end user should be able to switch between hexadecimal, RGB and HSL. We’re defining these modes internally, but we want to ensure they render correctly. Instead of testing button labels, we’ll rely on class names. It makes our test more robust, as we can easily define a class name as part of our component’s contract. However, button labels should be able to change. Now you may be tempted to check for these three specific modes, but that would make the test brittle. What if we change them? What if we add one, or remove one? That would still be the same logic, yet the test would fail, forcing us to go and edit it. One solution could be to access the component’s data to iterate on the modes dynamically. Vue Test Utils lets us do that through the vm property, but again, this tightly couples our test with the internal implementation of the modes. If tomorrow, we decided to change the way we define modes, the test would break. Another solution is to keep going with black box testing and only expect the class name to match a given pattern. We don’t care that it’s color-mode-hex, color-mode-hsl or color-mode-xyz, as long as it looks like what we expect from the outside. Jest lets us do that with regular expression matchers. // ... describe('Color model', () => { test('displays each mode as an individual button', () => { const buttons = wrapper.findAll('.color-mode') buttons.wrappers.forEach(button => { expect(button.classes()).toEqual( expect.arrayContaining([expect.stringMatching(/color-mode-\w{1,}/)]) ) }) }) }) Here, we’re expecting elements with a class that follows the pattern “color-mode-“ + any word character (in ECMAScript, any character within [a-zA-Z_0-9]). We could add or remove any mode we want, and the test would still be valid. Naturally, right now, the test should fail, as there are no buttons with class color-mode yet. We can make it pass by hardcoding them in the component. <div class="color-modes"> <button class="color-mode color-mode-hex"></button> <button class="color-mode color-mode-rgb"></button> <button class="color-mode color-mode-hsl"></button> </div> We can now refactor this code by adding the modes as private data in our component and iterate over them. export default { // ... data() { return { activeSwatch: 0, colorModes: ['hex', 'rgb', 'hsl'] } } } <div class="color-modes"> <button :key="index" v-for="(mode, index) in colorModes" class="color-mode" :class="`color-mode-${mode}`" >{{ mode }}</button> </div> Good! Let’s move on. As with the swatches, we want the first mode to be set as active. We can copy the test we wrote and adapt it to this new use case. test('sets the first mode as the selected one by default', () => { const firstButton = wrapper.find('.color-mode') expect(firstButton.classes()).toContain('active') }) We can make this test pass by manually adding the class on the first list item. <button :key="index" v-for="(mode, index) in colorModes" class="color-mode" :class="[{ 'active': index === 0 }, `color-mode-${mode}`]" >{{ mode }}</button> Finally, we can refactor by externalizing the index onto which the class applies. export default { // ... data() { return { activeSwatch: 0, activeMode: 0, colorModes: ['hex', 'rgb', 'hsl'] } } } <button :key="index" v-for="(mode, index) in colorModes" class="color-mode" :class="[{ active: index === activeMode }, `color-mode-${mode}`]" >{{ mode }}</button> We need to change the active mode whenever the end user clicks the associated button, as with the swatches. test('sets the color mode button as active when clicked', () => { const targetButton = wrapper.findAll('.color-mode').at(2) targetButton.trigger('click') expect(targetButton.classes()).toContain('active') }) We can now add a @click directive as we did with the swatches, and make the test go green without having to refactor. <button :key="index" v-for="(mode, index) in colorModes" class="color-mode" :class="[{ active: index === activeMode }, `color-mode-${mode}`]" @click="activeMode = index" >{{ mode }}</button> Testing the color code Now that we’re done testing the swatches and color code, we can move on to the third and final element of our color picker: the color code. What we display in there is a combination of the other two: the selected swatch defines the color we should display, and the selected mode determines how to display it. First, we want to make sure we initially display the default swatch in the default mode. We have the information to build this since we’ve implemented the swatches and the color mode. Let’s start with a (failing) test. describe('Color code', () => { test('displays the default swatch in the default mode', () => { expect(wrapper.find('.color-code').text()).toEqual('#e3342f') }) }) Now, let’s make this pass by hardcoding the expected result in the component. <div class="color-code">#e3342f</div> Good! Time to refactor. We have a raw color in hexadecimal mode, and we’re willing to output it in hexadecimal format. The only difference between our input and output values is that we want to prepend the latter with a hash character. The easiest way of doing so with Vue is via a computed property. export default { // ... computed: { activeCode() { return `#${this.swatches[this.activeSwatch]}` } } } <div class="color-code">{{ activeCode }}</div> This should keep the test green. However, there’s an issue with this computed property: it only works for hexadecimal values. It should keep on working when we change the color, but not when we change the mode. We can verify this with another test. test('displays the code in the right mode when changing mode', () => { wrapper.find('.color-mode-hsl').trigger('click') expect(wrapper.find('.color-code').text()).toEqual('2°, 76%, 54%') }) Here, we’ve changed to HSL mode, but we’re still getting the hexadecimal output. We need to refactor our code so that our activeCode computed property is not only aware of the current color, but also the current color mode. One way we can achieve this is to create computed properties for each mode and proxy them through activeCode based on the selected mode. First, we should simplify access to the current color and mode. Right now, we need to do an array lookup, which is repetitive and makes the code hard to read. We can use computed properties to wrap that logic. export default { // ... computed: { // ... activeColorValue() { return this.swatches[this.activeSwatch] }, activeModeValue() { return this.colorModes[this.activeMode] } } } As you can see, we’re not writing tests for these computed properties, as they aren’t part of our public API. We’ll use them later in our dedicated color mode computed properties, which themselves will be proxied in activeCode, which we’re testing in our “Color code” suite. All we care about is that the color code renders as expected so that the user can rely on them. How we get there are implementation details that we need to be able to change if need be. We can now write our dedicated computed properties for each mode. We’ll map their name onto the ones in colorModes, so we can do an array lookup later in activeCode to return the right one. For the hexadecimal output, we can externalize what we currently have in activeCode and refactor it using activeColorValue. export default { // ... computed: { // ... hex() { return `#${this.activeColorValue}` } } } Now, let’s modify activeCode so it proxies the right computed property depending on the active mode. export default { // ... computed: { // ... activeCode() { return this[this.activeModeValue] } } } This still shouldn’t make our latest test pass, since we haven’t written a computed property for it. However, our test that checks if the default mode renders correctly is still passing, which is a good sign we’re on the right track. We now want to write a computed property that returns the color output in HSL mode. For this, we’ll use color-convert, an npm package that lets us convert colors in many different modes. We’ve already been using it in our tests, so we don’t have to reinstall it. import convert from 'color-convert' export default { // ... computed: { // ... hsl() { const hslColor = convert.hex.hsl(this.activeColorValue) return `${hslColor[0]}°, ${hslColor[1]}%, ${hslColor[2]}%` } } } Great, our test passes! We can now finish this up adding the missing RGB mode. Yet, as you can see, we’re currently not testing the output of our color computed properties in isolation, but through other tests. To make things cleaner, we could decouple that logic from the component, import it as a dependency, and test it separately. This has several benefits: it keeps the component from growing every time we want to add a color mode, it keeps domains separated: the component focuses on its own view logic, and the color modes utility takes care of testing each mode exhaustively. First, create a new color.js file in the src/utils/ directory, and a matching spec file in tests/unit/. // color.spec.js import { rgb, hex, hsl } from '@/utils/color' // color.js import convert from 'color-convert' export const rgb = () => {} export const hex = () => {} export const hsl = () => {} We can use TDD to test those three functions and make sure they always return the expected value. We can extract the logic we had in our Vue component for the last two, and write the RGB function from scratch. For the sake of brevity, we’ll cover all three tests at once, but the process remains the same. import { rgb, hex, hsl } from '@/utils/color' const color = 'e3342f' describe('color', () => { test('returns the color into RGB notation', () => { expect(rgb(color)).toBe('227, 52, 47') }) test('returns the color into hexadecimal notation', () => { expect(hex(color)).toBe('#e3342f') }) test('returns the color into HSL notation', () => { expect(hsl(color)).toBe('2°, 76%, 54%') }) }) We now have three failing tests. The first thing we can do is to return hardcoded values to go green. export const rgb = () => '227, 52, 47' export const hex = () => '#e3342f' export const hsl = () => '2°, 76%, 54%' Now, we can start refactoring by migrating the code from our Vue component. export const hex = () => `#${color}` export const hsl = color => { const hslColor = convert.hex.hsl(color) return `${hslColor[0]}°, ${hslColor[1]}%, ${hslColor[2]}%` } Finally, we can implement our rgb function. export const rgb = color => convert.hex.rgb(color).join(', ') All tests should stay green! We can now use the color utilities in our Vue component and refactor it a bit. We no longer need to import color-convert in the component, nor do we need dedicated computed properties for each mode, or even for getting the active color and mode values. All we need to keep is activeCode, where we can store all the necessary logic. This is a good example where doing black box testing helps us: we’ve been focusing on testing the public API; thus we can refactor the internals of our component without breaking the tests. Removing properties like activeColorValue or hex doesn’t matter, because we were never testing them directly. // ... import { rgb, hex, hsl } from '@/utils/color' const modes = { rgb, hex, hsl } export default { // ... computed: { activeCode() { const activeColor = this.swatches[this.activeSwatch] const activeMode = this.colorModes[this.activeMode] return modes[activeMode](activeColor) } } } We now have much terser code in our component, and better domain separation, while still respecting the component’s contract. Finally, we can implement a missing test: the one that ensures the color code changes whenever we click a new swatch. This should already go green, but it’s still essential for us to write it, so we can know about it if it breaks. test('displays the code in the right color when changing color', () => { wrapper .findAll('.swatch') .at(2) .trigger('click') expect(wrapper.find('.color-code').text()).toEqual('#f6993f') }) And we’re done! We just built a fully functional Vue component using TDD, without relying on browser output, and our tests are ready. Visual control Now that our component is ready, we can see how it looks and play with it in the browser. This allows us to add the CSS and ensure we didn’t miss out on anything. First, mount the component into the main App.vue file. <!-- App.vue --> <template> <div id="app"> <color-picker :swatches="['e3342f', '3490dc', 'f6993f', '38c172', 'fff']"/> </div> </template> <script> import ColorPicker from '@/components/ColorPicker' export default { name: 'app', components: { ColorPicker } } </script> Then, run the app by executing the following script, and open it in your browser at http://localhost:8080/. npm run serve You should see your color picker! It doesn’t look like much for now, but it works. Try clicking colors and change the color mode; you should see the color code change. To see the component with proper styling, add the following CSS between the style tags: .color-picker { background-color: #fff; border: 1px solid #dae4e9; border-radius: 0.125rem; box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1); color: #596a73; font-family: BlinkMacSystemFont, Helvetica Neue, sans-serif; padding: 1rem; } .swatches { color: #fff; display: flex; flex-wrap: wrap; list-style: none; margin: -0.25rem -0.25rem 0.75rem; padding: 0; } .swatch { border-radius: 0.125rem; cursor: pointer; height: 2rem; margin: 0.25rem; position: relative; width: 2rem; } .swatch::after { border-radius: 0.125rem; bottom: 0; box-shadow: inset 0 0 0 1px #dae4e9; content: ''; display: block; left: 0; mix-blend-mode: multiply; position: absolute; right: 0; top: 0; } .swatch svg { display: none; color: #fff; fill: currentColor; margin: 0.5rem; } .swatch.active svg { display: block; } .color-modes { display: flex; font-size: 1rem; letter-spacing: 0.05rem; margin: 0 -0.25rem 0.75rem; } .color-mode { background: none; border: none; color: #9babb4; cursor: pointer; display: block; font-weight: 700; margin: 0 0.25rem; padding: 0; text-transform: uppercase; } .color-mode.active { color: #364349; } .color-code { border: 1px solid #dae4e9; border-radius: 0.125rem; color: #364349; text-transform: uppercase; padding: 0.75rem; } You should see something like this: And we’re done! Afterthoughts How can we improve this? For now, we have a robust test suite. Even though we don’t have 100% coverage, we can feel confident with our component going out in the wild, and evolving over time. There are still a couple of things we could improve though, depending on the use case. First, you may notice that when clicking the white swatch, the checkmark doesn’t show up. That’s not a bug, rather a visual issue: the checkmark is there, but we can’t see it because it’s white on white. You could add a bit of logic to fix this: when a color is lighter than a certain threshold (let’s say 90%), you could add a light class on the swatch. This would then let you apply some specific CSS and make the checkmark dark. Fortunately, you already have all you need: the color-converter package can help you determine whether a color is light (with the HSL utilities), and you already have a color utility module to store that logic and test it in isolation. To see what the finished code could look like, check out the project’s repository on GitHub. We could also reinforce the suite by adding a few tests to make sure some expected classes are there. This doesn’t test actual logic, but would still be particularly useful if someone was relying on those class names to style the component from the outside. Again, everything depends on your use case: test what shouldn’t change without you knowing, don’t only add tests for the sake of it. What did we learn? There are several lessons to learn from this TDD experiment. It brings a lot to the table but also highlights a few challenges that we should be aware of. First, TDD is a fantastic way to write robust tests, not too many and not too few. Have you ever finished a component, moved on to tests and thought “where do I even start?”? Looking at finished code and figuring out what to test is hard. It’s tempting to get it done quickly, overlook some critical parts and end up with an incomplete test suite. Or you can adopt a defensive approach and test everything, risking to focus on implementation details and writing brittle tests. Adopting TDD for developing UI components helps us focus on exactly what to test by defining, before writing any line of code, if this is part of the contract or not. Secondly, TDD encourages refactors, leading to better software design. When you’re writing tests after coding, you’re usually no longer in a refactoring dynamic. You can fix your code if you find issues while testing, but at this stage, you’re most likely done with the implementation. This separation between writing code and writing test is where lies the issue. With TDD, you’re creating a deeper connection between code and tests, with a strong focus on making the public API reliable. Implementation comes right after you’ve guaranteed the outcome. This is why the green step is critical: you first need your test to pass, then ensure it never breaks. Instead of implementing your way to a working solution, you’re reversing the relationship, focusing on the contract first, and allowing the implementation to remain disposable. Because refactoring comes last, and you’ve established the contract, you now have mental space to make things right, clean some code, adopt a better design, or focus on performance. It’s worth noting that TDD is much easier to follow with specs. When you already have a clear overview of everything the component should do, you can translate those specifications into tests. Some teams use frameworks like ATDD (acceptance test–driven development), where the involved parties develop specifications from a business perspective. The final specs, or acceptance tests, are a perfect base to write tests following TDD. On the other hand, going with TDD to test UI components can be difficult at first, and require some prior knowledge before diving into it. For starters, you need to have good knowledge of your testing libraries so that you can write reliable assertions. Look at the test we wrote with a regular expression: the syntax is not the most straightforward. If you don’t know the library well, it’s easy to write a test that fails for the wrong reasons, which would end up hindering the whole TDD process. Similarly, you need to be aware of some details regarding the values you expect; otherwise, you could end up battling with your tests and do some annoying back-and-forths. On that matter, UI components are more challenging than renderless libraries, because of the various ways the DOM specifications can be implemented. Take the first test of our suite for example: we’re testing background colors. However, even though we’re passing hexadecimal colors, we’re expecting RGB return values. That’s because Jest uses jsdom, a Node.js implementation of the DOM and HTML standards. If we were running our tests in a specific browser, we might have a different return value. This can be tricky when you’re testing different engines. You may have to seek some more advanced conversion utilities or use environment variables to handle the various implementations. Is it worth it? If you made it this far, you’ve probably realized that TDD demands time. This article itself is over 6,000 words! This can be a bit scary if you’re used to faster development cycles, and probably looks impossible if you’re often working under pressure. However, it’s important to bust the myth that TDD would somehow double development time for little return on investment, because this is entirely false. TDD requires some practice, and you’ll get faster over time. What feels clumsy today can become a second nature tomorrow, if you do it regularly. I encourage you not to discard something because it’s new and feels awkward: give it some time to assess it fairly, then take a decision. Secondly, time spent on writing test-driven code is time you won’t spend fixing bugs. Fixing bugs is far more costly than preventing them. If you’ve ever had to fix critical production bugs, you know this feels close to holding an open wound on a surgical patient with one hand, while trying to operate with the other one. In the desert. At night. With a Swiss Army knife. It’s messy, stressful, suboptimal, and bears high chances of screwing up something else in the process. If you want to preserve your sanity and the trust your end users have in your software, you want to avoid those situations at all costs. Tests help you catch bugs before they make it to production, and TDD helps you write better tests. If you think you should test your software, then you should care about making these tests useful in the first place. Otherwise, the whole thing is only a waste of time. As with anything, I encourage you to try TDD before discarding the idea. If you’re consistently encountering production issues, or you think you could improve your development process, then it’s worth giving it a shot. Try it for a limited amount of time, measure the impact, and compare the results. You may discover a method that helps you ship better software, and feel more confident about hitting the “Deploy” button.

Unit Test Your First Vue.js Component

In Build Your First Vue.js Component we made a star rating component. We’ve covered many fundamental concepts to help you create more complex Vue.js components. Yet, there’s one crucial point you need to build bulletproof components you can use in production: unit testing. Why unit test a component? Unit tests are a crucial part of continuous integration. They make your code a lot more reliable by focusing on small, isolated entities and making sure they always behave as expected. You can confidently iterate on your project without fear of breaking things. Unit tests aren’t limited to scripts. Anything we can test in isolation is unit testable, as long as you respect a few good practices like single-responsibility, predictability and loose coupling. As reusable entities of our app, Vue.js components are great candidates for unit testing. We’ll test the one we made as a single unit with various inputs and user interactions, and make sure it always behaves as we expect. Before we start A few things have changed since the initial tutorial. Vue CLI 3 was released, and Vue Test Utils, the official Vue.js unit testing utility library, has matured to beta version. In the first tutorial, we used webpack-simple, a prototyping template that doesn’t include testing features. For all those reasons, the simplest thing to do is to wipe the slate clean and migrate the project from the tutorial to a more recent Vue.js install. I re-created the project from the first tutorial so you can download it directly from GitHub. Then, navigate to the unzipped directory and install dependencies. Note: make sure you install Node.js before going further. cd path/to/my/project npm install Then, run the project: npm run serve Vue Test Utils & Jest For this tutorial, we’ll use Vue Test Utils, the official Vue.js testing toolkit, along with Jest, a JavaScript test runner backed by Facebook. Vue Test Utils lets you mount Vue components in isolation and simulate user interactions. It has all the necessary utilities to test single-file components, including those using Vue Router or Vuex. Jest is a full-featured test runner that requires almost no configuration. It also provides a built-in assertion library. Using Vue CLI 3 (which I used to generate the boilerplate) allows you to pick your favorite test runner, and sets it up for you. If you want to use another test runner (like Mocha), install Vue CLI 3 and generate your own starter project. Then, you can migrate the source files from my boilerplate right in it. What should we test? A common approach of unit testing is to only focus on the public API (aka black box testing). By overlooking implementation details, you’re allowing internals to change without having to adapt tests. After all, what you want to do is make sure your public API won’t break. What happens under the hood is indirectly tested, but all that matters is for the public API to remain reliable. This is also the official recommendation from the Vue Test Utils guides. Therefore, we’ll only test what we can access from the outside of the component: user interactions props changes We won’t directly test computed properties, methods or hooks. These will be implicitly tested by testing the public interface. Setting up a spec file Like with regular tests, each component has a spec file which describes all tests we want to run. Specs are JavaScript files. By convention, they have the same name as the components they’re testing, plus a .spec suffix. Go ahead and create a test/unit/Rating.spec.js file. // Rating.spec.js import { shallowMount } from '@vue/test-utils' import Rating from '@/components/Rating' describe('Rating', () => { // your tests go here }) We’ve imported our Rating component and shallowMount. The latter is a Vue Test Utils function which lets us mount our component without mounting its children. The describe function call wraps all the test we’re about to write; it describes our testing suite. It has its own scope, and can itself wrap other nested suites. Enough said let’s start writing tests. Identifying testing scenarios When we look at Rating from the outside, we can see it does the following: it renders a list of stars which is equal to the value of the maxStars prop the user passes, it adds an active class to each star which index is lower than or equal to the stars prop the user passes, it toggles the active class on a star when the user clicks it and removes it on the next stars, it toggles the icons star and star-o when the user clicks a star, it renders a counter if the user sets the hasCounter prop to true, hides it if they set it to false, and displays text saying how many stars of the maximum number of stars are currently active. Notice we’re only looking at what the component does from the outside. We don’t care that clicking a star executes the rate method, or that the internal stars data property changes. We could rename these, but this shouldn’t break our tests. Our first test Let’s write our first test. We first need to manually mount our component with shallowMount, and store it in a variable on which we’ll perform assertions. We can also pass props through the propsData attribute, as an object. The mounted component is an object which comes with a handful of useful utility methods. describe('Rating', () => { const wrapper = shallowMount(Rating, { propsData: { maxStars: 6, grade: 3 } }) it('renders a list of stars with class `active` equal to prop.grade', () => { // our assertion goes here }) }) Then, we can write our first assertion: it('renders a list of stars with class `active` equal to prop.grade', () => { expect(wrapper.findAll('.active').length).toEqual(3) }) Let’s analyze what’s happening here. First, we’re using Jest’s expect function, which takes the value we want to test as an argument. In our case, we call the findAll method on our wrapper to fetch all elements with an active class. This returns a WrapperArray, which is an object that contains an array of Wrappers. A WrapperArray has two properties: wrappers (the contained Wrappers) and length (the number of Wrappers). The latter is what we need to make sure we have the expected number of stars. The expect function also returns an object on which we can call methods to test the passed value: these methods are called matchers. Here, we use the toEqual matcher and pass it the expected value as in arguments. The method returns a boolean, which is what a test expects to either pass or fail. To summarize, here we say we expect the total amount of elements with the class active we find in our wrapper to be equal to 3 (the value we assigned to the grade prop). In your terminal, run your test: npm run test:unit You should see it pass 🎉 Time to write some more. Simulating user input Vue Test Utils makes it easy to simulate what real users end up doing in production. In our case, users can click on stars to toggle them. We can fake this in our tests with the trigger method, and dispatch all kinds of events. it('adds `active` class on an inactive star when the user clicks it', () => { const fourthStar = wrapper.findAll('.star').at(3) fourthStar.trigger('click') expect(fourthStar.classes()).toContain('active') }) Here, we first get our fourth star with findAll and at, which returns a Wrapper from a WrapperArray at the passed index (zero-based numbering). Then, we simulate the click event on it: we’re mimicking the action from a user who would click or tap the fourth star. Since we set the grade prop to 3, the fourth star should be inactive before we click; therefore the click event should make it active. In our code, this is represented by a class active which we append on stars only when they’re activated. We test it by calling the classes method on the star, which returns its class names as an array of strings. Then, we use the toContain matcher to make sure the active class is here. Setup and teardown Since we’ve triggered a click on our component, we’ve mutated its state. The problem is, we’re using that same component for all our tests. What happens if we change the order of our tests, and move this one to first position? Then the second test would fail. You don’t want to rely on brittle things like order when it comes to tests. A test suite should be robust, and existing tests should ideally not change unless you’re breaking the API. What we want is to make sure we always have a predictable wrapper to perform assertions on. We can achieve this with setup and teardown functions. These are helpers which let us initialize things before we run tests, and clean up afterward. In our case, a way of doing it could be to create our wrapper before each test and destroy it after. let wrapper = null beforeEach(() => { wrapper = shallowMount(Rating, { propsData: { maxStars: 6, grade: 3 } }) }) afterEach(() => { wrapper.destroy() }) describe('Rating', () => { // we remove the `const wrapper = …` expression // … } As their name suggest, beforeEach and afterEach run before and after each test. This way, we can be 100% sure we’re using a fresh wrapper whenever we run a new test. Special identifiers for tests It’s never a good idea to mix selectors for styling and other purposes, such as test hooks. What if you change the tag name or the class? What if you don’t have a specific identifier on an element you want to test, such as, in our case, the counter? You don’t want to pollute your production code with classes which would be useless there. It would be much better to have dedicated hooks for tests, such as a dedicated data attribute, but only during tests. This way, this wouldn’t leave a mess in the final build. One way to handle this is to create a custom Vue directive. The Vue instance has a directive method which takes two arguments: a name and an object of functions for each hook of the component lifecycle when injected in the DOM. You can also pass a single function if you don’t care about a specific hook. Let’s create a new directory called directives in src/, and add a test.js file. We’ll export the function we want to pass in our directive. // test.js export default (el, binding) => { // do stuff } A directive hook can take several arguments, but in our case, we only need the first two: el and binding. The el argument refers to the element the directive is bound to, and the binding argument is an object which contains the data we passed in the directive. This way, we can manipulate the element as we like. export default (el, binding) => { Object.keys(binding.value).forEach(value => { el.setAttribute(`data-test-${value}`, binding.value[value]) }) } We’re passing an object to our directive, so we can generate data attributes starting with data-test-. In the handler function, we iterate over each property of binding, and we set a data attribute based on the name and value, on our element. Now, we need to register our directive so we can use it. We can do it globally, but in our case, we’re only going to register it locally, right in our Rating.vue component. <script> import Test from '@/directives/test.js' export default { // … directives: { Test }, // … } </script> Our directive is now accessible under the v-test name. Try setting the following directive on the counter: <span v-test="{ id: 'counter' }" v-if="hasCounter"> {{ stars }} of {{ maxStars }} </span> Now inspect the HTML in your browser with the developer tools: your counter should look like this: <span data-test-id="counter">2 of 5</span> Great, it works! Now we don’t need this either in dev mode nor when we build the project. The sole purpose of this data attribute is to be able to target elements during tests, so we only want to set it up when we run them. For this, we can use the NODE_ENV environment variable provided by Webpack, the module bundler powering our project. When we run tests, NODE_ENV is set to 'test'. Therefore, we can use it to determine when to set the test attributes or not. export default (el, binding) => { if (process.env.NODE_ENV === 'test') { Object.keys(binding.value).forEach(value => { el.setAttribute(`data-test-${value}`, binding.value[value]) }) } } Refresh your app in the browser and inspect the counter again: the data attribute is gone. Now we can use the v-test directive for all elements we need to target. Let’s take our test from earlier: it('adds `active` class on an inactive star when the user clicks it', () => { const fourthStar = wrapper.findAll('[data-test-id="star"]').at(3) fourthStar.trigger('click') expect(fourthStar.classes()).toContain('active') }) We’ve replaced the .star selector with [data-test-id="star"], which allows us to change classes for presentation purposes without breaking tests. We get one of the benefits of the single-responsibility principle and loose coupling: when your abstractions only have a single reason to change, you avoid all kinds of pesky side-effects. Should we also use these hooks for the classes we test? After setting this directive to target elements to test, you may be wondering if you should also use them to replace the classes we actively look for. Let’s look at the assertion from our first test: expect(wrapper.findAll('.active').length).toEqual(3) Should we use v-test on the elements with the active class, and replace the selector in the assertion? Great question. Unit tests are all about testing one thing at a time. The first argument of the it function is a string, with which we describe what we’re doing from a consumer perspective. The test that wraps our assertion says renders a list of stars with class active equal to prop.grade: this is what the consumer expects. When they pass a number to the grade property, they expect to retrieve an equal number of active or selected stars. Yet, in our component’s logic, the active class is precisely what we use to define this trait. We assign it depending on a specific condition, so we can visually differentiate active stars from the others. Here, the presence of this specific class is exactly what we want to test. So, when deciding whether you should use a selector you already have or set a v-test directive, ask yourself the question: what am I testing, and does using this selector makes sense for a business logic perspective? How is it different from functional or end-to-end tests? At first, it might look odd to unit test components. Why would you unit test UI and user interactions? Isn’t that what functional tests are here for? There is a fundamental yet subtle difference to make between testing a component’s public API (aka from a consumer perspective) and testing a component from a user perspective. But first, let’s underline something important: we’re testing well-defined JavaScript functions, not pieces of UI. When you look at a single-file component, it’s easy to forget it compiles into a JavaScript function. We’re not testing the underlying Vue mechanism which, from this function, causes UI-oriented side-effects like injecting HTML in the DOM. That’s what Vue’s own tests already take care of. In our case, our component is no different from any other function: it accepts input and returns an output. These causes and consequences are what we’re testing, and nothing else. What’s confusing is that our tests look a bit different from regular unit tests. Usually, we write things like: expect(add(3)(4)).toEqual(7) There’s no debate here. Input and output of data, that’s all we care about. With components, we’re expecting for things to render visually. We’re traversing a (virtual) DOM and test for the presence of nodes. That’s also what you do with functional or end-to-end tests, with tools like Selenium or Cypress.io. So how does that differ? You need not to confuse what we’re doing to fetch the data we want to test and the actual purpose of the test. With unit tests, we’re testing isolated behaviors, while with functional or end-to-end tests, we’re testing scenarios. A unit test makes sure a unit of the program behaves as expected. It’s addressed to the consumer of the component (the programmer who uses the component in their software). A functional test ensures a feature or a workflow behaves as expected, from a user perspective (the final user, who consumes the full software). Going further I won’t go into the detail of each test, because they all share a similar structure. You can find the full spec file on GitHub, but I strongly recommend you try to implement them yourself first. Software testing is an art as much as it is a science and requires twice as much practice as it requires theory. Don’t worry if you didn’t get everything, or if you struggle with writing your first tests: testing is notoriously hard. Also, if you have a question, don’t hesitate to hit me up on Twitter!

How I Dropped 250 KB of Dead CSS Weight with PurgeCSS

I’m a big advocate for utility-first CSS. After trying several methods over the years, it’s what I found to be the best, most maintainable and scalable way of writing CSS to this day. When my coworker Clément Denoix and I built api-search.io, I decided to use Tailwind CSS to style it: a theme-agnostic, fully customizable utility-first library. The whole point of a library is to give you access to a broad set of tools to use at will. The problem is, since you usually use only a subset of it, you end up with a lot of unused CSS rules in your final build. In my case, not only did I load the entire Tailwind CSS library, but I also added several variants to some modules. That ended up making the final minified CSS file weight 259 KB (before GZip). That’s quite heavy when you consider the website is a simple single-page app with a minimal design. You don’t want to load each utility by hand when you need it. That would be a long and cumbersome task. A better scenario is to have everything at your disposal during development and automatically remove what you didn’t use during the build step. In JavaScript, we call it tree-shaking. Now, thanks to PurgeCSS, you can do the same with your CSS codebase. PurgeCSS analyzes your content files and your CSS, then matches the selectors together. If it doesn’t find any occurrence of a selector in the content, it removes it from the CSS file. For the most part, this can work out of the box. However, there are some areas in any website that may require some more thinking before letting PurgeCSS do its magic. Splitting my CSS The project contains three main CSS files: A CSS reset called normalize.css, included in Tailwind CSS. Tailwind CSS, the most substantial part of my CSS codebase. Some custom CSS, mostly for styling the InstantSearch components to which I couldn’t add classes. PurgeCSS can’t detect that I need to keep selectors such as .ais-Highlight, because the components that use it only show up in the DOM at runtime. Same goes with normalize.css: I’m relying on it to reset browser styles, but many of the related components will never be matched because they’re generated in JavaScript. In the case of classes starting with .ais-, we can sort them out with whitelisting. But when it comes to reset styles, selectors are a bit trickier to track down. Plus, the size of normalize.css is pretty insignificant and isn’t bound to change, so in this case, I decided to ignore the file altogether. Consequently, I had to split styles before running PurgeCSS. My initial CSS configuration looked like this: A tailwind.src.css file with three @tailwind directives: preflight, components and utilities. An App.css file with my custom styles. An npm script in package.json to build Tailwind CSS right before starting or building the project. Every time this script runs, it outputs a tailwind.css file in src, which is loaded in the project. The @tailwind preflight directive loads normalize.css. I didn’t want PurgeCSS to touch it, so I moved it to a separate file. // tailwind.src.css @tailwind components; @tailwind utilities; /* normalize.src.css */ @tailwind preflight; Then, I changed my existing tailwind script in package.json to build normalize.src.css separately. { "scripts": { "tailwind": "npm run tailwind:normalize && npm run tailwind:css", "tailwind:normalize": "tailwind build src/normalize.src.css -c tailwind.js -o src/normalize.css", "tailwind:css": "tailwind build src/tailwind.src.css -c tailwind.js -o src/tailwind.css" } } Finally, I loaded normalize.css in the project. // src/index.js ... import './normalize.css' import './tailwind.css' import App from './App' ... Now, I can run PurgeCSS on tailwind.css without fearing it might strip down needed rulesets. Configuring PurgeCSS PurgeCSS comes in many flavors: a command-line interface, a JavaScript API, wrappers for Webpack, Gulp, Rollup, etc. We used Create React App to bootstrap the website, so Webpack came preconfigured and hidden behind react-scripts. This means I couldn’t access Webpack configuration files unless I ran npm run eject to get them back and manage them directly in the project. Not having to manage Webpack yourself has many advantages, so ejecting wasn’t an option. Instead, I decided to use a custom configuration file for PurgeCSS, and an npm script. I first created a purgecss.config.js at the root of the project: module.exports = { content: ['src/App.js'], css: ['src/tailwind.css'] } The content property takes an array of files to analyze to match CSS selectors. The css property takes an array of stylesheets to purge. Then, I edited my npm scripts to run PurgeCSS: { "scripts": { "start": "npm run css && react-scripts start", "build": "npm run css && react-scripts build", "css": "npm run tailwind && npm run purgecss", "purgecss": "purgecss -c purgecss.config.js -o src" } } I added a purgecss script that takes my configuration file and outputs the purged stylesheet in src. I made this script run every time we start or build the project. Special extractor for Tailwind CSS Tailwind CSS uses special characters, so if you use PurgeCSS out of the box, it may remove necessary selectors. Fortunately, PurgeCSS allows us to use a custom extractor, which is a function that lists out the selectors used in a file. For Tailwind, I needed to create a custom one: module.exports = { ... extractors: [ { extractor: class { static extract(content) { return content.match(/[A-z0-9-:\/]+/g) || [] }, extensions: ['js'] } } ] } Whitelisting runtime classes PurgeCSS can’t detect classes that are generated at runtime, but it lets you define a whitelist. The classes you whitelist remain in the final file no matter what. The project uses React InstantSearch, which generates components with classes that all start with ais-. Conveniently, PurgeCSS supports patterns in the form of regular expressions. module.exports = { ... css: ['src/tailwind.css', 'src/App.css'], whitelistPatterns: [/ais-.*/], ... } Now if I forget to remove a class that I no longer use from App.css, it will be taken out from the final build, but my InstantSearch selectors will remain safe. New build, lighter CSS With this new configuration, my final CSS file has gone from 259 KB to… 9 KB! It’s pretty significant in the context of a whole project, especially since many countries still have slow and unstable Internet, and more and more people browse on their phone while on the move. Accessibility is also about catering for people with low bandwidth connection. It’s not acceptable not to try and help your users with slower Internet, especially if what you’re making them download is dead code. That’s worth taking a moment to optimize your build. 🙂

Should You Chain or Extend CSS Classes?

If you’re building an app or a website that changes often, modular CSS methods solve many issues. Instead of copying your HTML structure in CSS and decorate it, you create consumable libraries of components. The latter makes projects more scalable and keeps the CSS codebase under control. CSS modularity relies on composition, which inevitably fattens the HTML. This collateral effect can be a significant rebuttal for many people because of the “bloat” it creates. In this article, we’ll compare two techniques: chaining and extending. We’ll see what they provide and what their shortcomings are so that you can make more thoughtful choices. Chaining Chaining CSS classes means composing the desired look by adding granular modifiers together onto an HTML selector. The composite styles create the final visual outcome, which is the default behavior with most modular CSS methodologies. Let’s take the following OOCSS code for a button: .btn { display: block; box-shadow: 0 0 5px 0 rgba(0, 0, 0, .2); } .btn-default { border: 3px solid grey; } .btn-primary { background: purple; color: white; } If you were to chain modifiers, your HTML would look like this: <button class="btn btn-primary">Primary button</button> <button class="btn btn-default">Default button</button> Now let’s do something a bit more complex, this time with BEM: <div class="media-object media-object--reverse media-object--outlined"> <div class="media-object__media"> <img class="media-object__img media-object__img--faded img img--square" src="..." alt="..."> </div> <div class="media-object__body">...</div> </div> Here we have a lot more interacting classes: The .media-object block has several modifiers (.media-object--reverse and .media-object--outlined). The .media-object__img element has one modifier (.media-object__img--faded). The .media-object__img element is also an .img block with its own modifier (.img--square). Pros The top highlight of chaining classes is separate responsibility. It keeps your CSS codebase clean, light, comfortable to read, and non-repetitive. What each class does is crystal clear, you immediately know what you should use and what you shouldn’t. It also prevents dead code: since you’re dealing with building blocks, everything is potentially useful. When you remove a component, you only need to remove the HTML. Separate modifiers are great to represent state; thus it makes life easier for JavaScript engineers. All they have to do is add and remove classes. On large projects, this method can save you a lot of time. Cons One of the most recurring issues people have with modular CSS is that it creates “class madness” in the HTML. Strictly speaking, this is true. Design patterns that split responsibilities almost always result in more files and verbose code. CSS is no exception: if you pick a method that’s supposed to make your codebase more maintainable, the counterpart is lengthy HTML files. Having to type much code is becoming less and less of a problem these days, as most editors and IDEs offer powerful autocompletion. Now, it’s still more code to write every time you make a new page or compose a new component. Over time, this can induce a feeling of clutter and redundancy that will put-off some developers. Extending If you don’t want to chain classes, you can extend them. We still have the same separate blocks, but instead of chaining them in the HTML, we inherit the properties of the base class to its modifiers. This way, we can use them all at once. Let’s use the @extend function in Sass to do so: .btn { display: block; box-shadow: 0 0 5px 0 rgba(0, 0, 0, .2); &-default { @extend .btn; border: 3px solid grey; } &-primary { @extend .btn; background: purple; color: white; } } This will turn into the following CSS snippet: .btn, .btn-default, .btn-primary { display: block; box-shadow: 0 0 5px 0 rgba(0, 0, 0, .2); } .btn-default { border: 3px solid grey; } .btn-primary { background: purple; color: white; } With the above CSS, our HTML would look like this: <button class="btn-primary">Primary button</button> <button class="btn-default">Default button</button> Instead of having a slew of seemingly repetitive classes, we only have one. It has an explicit name and keeps the code readable. We can still use .btn alone but if we need a variation of it, we only need to append the modifier part on it instead of chaining a new class. Pros The highlight of this method is a clutter-free, more readable, and lighter HTML. When you go for modular CSS, you also decide to do more HTML and less CSS. The CSS becomes a library instead of a list of instructions. Thus, you spend more time in the HTML, which is why you may want to keep it light and easy to read. Cons Your CSS may look DRY, especially if you’re using a pre-processor, but extending classes results in a much heavier CSS file. Plus, you don’t have much control over what happens: every time you use @extend, the class definition is moved to the top and added to a list of selectors sharing the same ruleset. This process can result in weird style overrides and a lot more generated code. There’s also the case of wanting to use several modifiers together. With the extend method, you don’t compose in the HTML anymore. You’re left with one solution if you’re going to create new combinations: create even more classes by extending modifiers. This is hard to maintain and results in more code. Every time you need to blend classes, you’ll need to edit the CSS and create a potentially non-reusable new rule. If you ever remove the HTML that uses it, you’ll also have to delete the CSS class. Afterthoughts Modular CSS comes at the price of more verbose HTML, but it’s not much to pay for all the benefits it provides. If you’ve already determined you need modularity, don’t shoot yourself in the foot by using incompatible practices. It will result in more work for half the benefits. Inheritance is tempting, but composition has more than once been recognized as a far better strategy. HTML “bloat” is not that big of a deal when you look at its actual impact. Modularity inevitably creates more code, the method you pick only determines where it goes. From a performance standpoint, more HTML is far better than more CSS. Don’t focus on small things that don’t matter. Instead, leverage tools that help you write and navigate code more efficiently look at the big picture and make choices based on facts, not personal preferences.

Build a Shopping Cart with Vue and Dinero.js

My friend Cory and I chat almost every day, so you can bet he knows about everything going on in my life. But as we were talking the other day, I realized he had no idea how Dinero.js, my latest project, actually works. Like, what you can do with it. I paused and realized it may actually not be that obvious. It’s easier, whatever your skill level is, to understand what a smooth scrolling plugin does than what a money library has to offer. “Do you see in JavaScript how you can use a Date constructor to store a date and format it later? Or you use Moment.js to create moment objects and how it’s better than storing dates as strings or any other type? Well, Dinero.js is like Moment, but for money. There’s no native way to handle money, and if you try to do it with Number types, you’re going to run into issues. That’s what Dinero.js helps you avoid. It secures your monetary values in objects and allows you to do whatever you need with them.” I was happy with my explanation, as Cory started “a-ha”-ing. But I realized one thing had been missing from the beginning. Something that would speak volumes and help anyone understand the benefits of Dinero.js: a real-world example. In this tutorial, we’ll build a shopping cart. We’ll use Vue.js to build the component, then integrate Dinero.js to handle all the money stuff. TL;DR: this post goes in-depth in the how and why. It’s designed to help you grasp the core concepts of Dinero.js. If you want to understand the whole thought process, read on. Otherwise you can look at the final code on CodeSandbox. This post assumes you have basic knowledge of Vue.js. If not, first check my tutorial “Build Your First Vue.js Component”. It will equip you with everything you need to go further. Getting started For this project, we’ll use vue-cli and the webpack-simple Vue.js template. If you don’t have vue-cli installed globally on your machine, fire up your terminal and type the following: npm install -g vue-cli Then: vue init webpack-simple path/to/my-project You can keep the default options for all questions. When it’s done, navigate to the new directory, install dependencies and run the project: cd path/to/my-project npm install npm run dev Webpack will start serving your project on port 8080 (if available) and open it in your browser. Setting up the HTML/CSS I won’t get into page structure and styling in this tutorial, so I invite you to copy/paste the code. Open the App.vue file, and paste the following snippets. This goes between the <template> tags: <div id="app"> <div class="cart"> <h1 class="title">Order</h1> <ul class="items"> <li class="item"> <div class="item-preview"> <img src="" alt="" class="item-thumbnail"> <div> <h2 class="item-title"></h2> <p class="item-description"></p> </div> </div> <div> <input type="text" class="item-quantity"> <span class="item-price"></span> </div> </li> </ul> <h3 class="cart-line"> Subtotal <span class="cart-price"></span> </h3> <h3 class="cart-line"> Shipping <span class="cart-price"></span> </h3> <h3 class="cart-line"> Total <span class="cart-price cart-total"></span> </h3> </div> </div> Ant this between the <style> tags: body { margin: 0; background: #fdca40; padding: 30px; } .title { display: flex; justify-content: space-between; align-items: center; margin: 0; text-transform: uppercase; font-size: 110%; font-weight: normal; } .items { margin: 0; padding: 0; list-style: none; } .cart { background: #fff; font-family: 'Helvetica Neue', Arial, sans-serif; font-size: 16px; color: #333a45; border-radius: 3px; padding: 30px; } .cart-line { display: flex; justify-content: space-between; align-items: center; margin: 20px 0 0 0; font-size: inherit; font-weight: normal; color: rgba(51, 58, 69, 0.8); } .cart-price { color: #333a45; } .cart-total { font-size: 130%; } .item { display: flex; justify-content: space-between; align-items: center; padding: 15px 0; border-bottom: 2px solid rgba(51, 58, 69, 0.1); } .item-preview { display: flex; align-items: center; } .item-thumbnail { margin-right: 20px; border-radius: 3px; } .item-title { margin: 0 0 10px 0; font-size: inherit; } .item-description { margin: 0; color: rgba(51, 58, 69, 0.6); } .item-quantity { max-width: 30px; padding: 8px 12px; font-size: inherit; color: rgba(51, 58, 69, 0.8); border: 2px solid rgba(51, 58, 69, 0.1); border-radius: 3px; text-align: center; } .item-price { margin-left: 20px; } Adding data When you’re dealing with products, you usually retrieve raw data from a database or an API. We can get close by representing it in a separate JSON file, then import it asynchronously as if we were querying an API. Let’s create a products.json file in assets/ and add the following: { "items": [ { "title": "Item 1", "description": "A wonderful product", "thumbnail": "https://fakeimg.pl/80x80", "quantity": 1, "price": 20 }, { "title": "Item 2", "description": "A wonderful product", "thumbnail": "https://fakeimg.pl/80x80", "quantity": 1, "price": 15 }, { "title": "Item 3", "description": "A wonderful product", "thumbnail": "https://fakeimg.pl/80x80", "quantity": 2, "price": 10 } ], "shippingPrice": 20 } This is pretty similar to what we would get from a real API: data as a collection, with titles and text as strings, and quantity and prices as numbers. We can go back to App.vue and set empty values in data. This will allow the template to initialize while the actual data is being fetched. data() { return { data: { items: [], shippingPrice: 0 } } } Finally, we can fetch data from products.json with an asynchronous request, and update the data property when it’s ready: export default { ... created() { fetch('./src/assets/products.json') .then(response => response.json()) .then(json => (this.data = json)) } } Now let’s populate our template with this data: <ul class="items"> <li :key="item.id" v-for="item in data.items" class="item"> <div class="item-preview"> <img :src="item.thumbnail" :alt="item.title" class="item-thumbnail"> <div> <h2 class="item-title">{{ item.title }}</h2> <p class="item-description">{{ item.description }}</p> </div> </div> <div> <input type="text" class="item-quantity" v-model="item.quantity"> <span class="item-price">{{ item.price }}</span> </div> </li> </ul> ... <h3 class="cart-line"> Shipping <span class="cart-price">{{ data.shippingPrice }}</span> </h3> ... You should see all the items in your cart. Now let’s add some computed properties to calculate the subtotal and total: export default { ... computed: { getSubtotal() { return this.data.items.reduce( (a, b) => a + b.price * b.quantity, 0 ) }, getTotal() { return ( this.getSubtotal + this.data.shippingPrice ) } } } And add them to our template: <h3 class="cart-line"> Subtotal <span class="cart-price">{{ getSubtotal }}</span> </h3> ... <h3 class="cart-line"> Total <span class="cart-price cart-total">{{ getTotal }}</span> </h3> There we go! Try changing quantities around, you should see the subtotal and total amounts change accordingly. Now we have a few issues here. First, we’re only showing amounts, not currencies. Sure, we could hard code them in the template right next to the reactive amounts. But what if we want to make a multi-lingual website? Not all languages format money the same way. What if we want to show all amounts with two decimal places, for better alignment? You could try and keep all initial amounts as floats by using the toFixed method, but then you’d be working with String types which are a lot harder and less performant when it comes to doing maths. Also, that would mean changing data for purely presentational purposes, which never is a good idea. What if you need the same data for other purposes and it requires a different format? Finally, the current solution is relying on floating point math, which is a bad idea when it comes to handling money. Try and change a few amounts: { "items": [ { ... "price": 20.01 }, { ... "price": 15.03 }, ... ] } Now, look at how broken your shopping cart is 😱 This isn’t some buggy JavaScript behavior but a limitation of how we can represent our decimal numbering system with binary machines. If you do math with floats, you’ll sooner or later encounter those inaccuracies. The good news is, we don’t have to use floats to store money. That’s exactly where Dinero.js comes into play. Dinero.js, a wrapper for money Dinero.js is to money what Moment.js is to dates. It’s a library that lets you create monetary value objects, manipulate them, ask them questions, and format them. It relies on Martin Fowler’s money pattern and helps you solve all common problems caused by floats, primarily by storing amounts in minor currency unit, as integers. Open up your terminal and install Dinero.js: npm install dinero.js --save Then import it into App.vue: import Dinero from 'dinero.js' export default { ... } You can now create Dinero objects 🎉 // returns a Dinero object with an amount of $50 Dinero({ amount: 500, currency: 'USD' }) // returns $4,000.00 Dinero({ amount: 500 }) .add(Dinero({ amount: 500 })) .multiply(4) .toFormat() Let’s create a factory method to turn our price properties into Dinero objects on demand. We have floats with up to two decimal places. This means if we want to turn them into their equivalents in minor currency units (in our case, dollars), we need to multiply them by 10 to the power of 2. We pass the factor as an argument with a default value, so we can use the method with currencies that have different exponents. export default { ... methods: { toPrice(amount, factor = Math.pow(10, 2)) { return Dinero({ amount: amount * factor }) } } } Dollars are the default currency, so we don’t need to specify it. Because we’re doing floating point math during the conversion, some calculations may end up as slightly inaccurate floats. That’s easy to fix by rounding the result to the closest integer. toPrice(amount, factor = Math.pow(10, 2)) { return Dinero({ amount: Math.round(amount * factor) }) } Now we can use toPrice in our computed properties: export default { ... computed: { getShippingPrice() { return this.toPrice(this.data.shippingPrice) }, getSubtotal() { return this.data.items.reduce( (a, b) => a.add( this.toPrice(b.price).multiply(b.quantity) ), Dinero() ) }, getTotal() { return this.getSubtotal.add(this.getShippingPrice) } } } And in our template: <ul class="items"> <li :key="item.id" v-for="item in data.items" class="item"> <div class="item-preview"> <img :src="item.thumbnail" :alt="item.title" class="item-thumbnail"> <div> <h2 class="item-title">{{ item.title }}</h2> <p class="item-description">{{ item.description }}</p> </div> </div> <div> <input type="text" class="item-quantity" v-model="item.quantity"> <span class="item-price">{{ toPrice(item.price) }}</span> </div> </li> </ul> <h3 class="cart-line"> Subtotal <span class="cart-price">{{ getSubtotal }}</span> </h3> <h3 class="cart-line"> Shipping <span class="cart-price">{{ getShippingPrice }}</span> </h3> <h3 class="cart-line"> Total <span class="cart-price cart-total">{{ getTotal }}</span> </h3> If you look at your shopping cart, you’ll see {} in place of prices. That’s because we’re trying to display an object. Instead, we need to format them so they can display prices with the right syntax, alongside their currency symbol. We can achieve that with Dinero’s toFormat method. <ul class="items"> <li :key="item.id" v-for="item in data.items" class="item"> ... <div> ... <span class="item-price"> {{ toPrice(item.price).toFormat() }} </span> </div> </li> </ul> <h3 class="cart-line"> Subtotal <span class="cart-price"> {{ getSubtotal.toFormat() }} </span> </h3> <h3 class="cart-line"> Shipping <span class="cart-price"> {{ getShippingPrice.toFormat() }} </span> </h3> <h3 class="cart-line"> Total <span class="cart-price cart-total"> {{ getTotal.toFormat() }} </span> </h3> Look in your browser: you now have a well-formatted, fully functional shopping cart 🤗 Going further Now that you have a good grasp of the basics of Dinero.js, time to raise the bar a little. Presentation Let’s change shippingPrice to 0 in the JSON file. Your cart should now display “Shipping: $0.00”, which is accurate but not user-friendly. Wouldn’t it be nicer for it to say “Free”? Fortunately, Dinero.js has a plenty of handy methods to ask questions to your instances. In our case, the isZero method is exactly what we need. In the template, you can display text instead of a formatted Dinero object whenever it represents zero: <h3 class="cart-line"> Shipping <span class="cart-price"> {{ getShippingPrice.isZero() ? 'Free' : getShippingPrice.setLocale(getLocale).toFormat() }} </span> </h3> Of course, you can generalize this behavior by wrapping it in a method. It would take a Dinero object as an argument and return a String. This way, you could show “Free” whenever you try to display a zero amount. Locale switching Imagine you’re making an e-commerce website. You want to accommodate your international audience, so you translate content and add a language switcher. Yet, there’s one detail that may slip your attention: money formatting also changes depending on the language. For example, €10.00 in American English translates to 10,00 € in French. Dinero.js supports international formatting via the I18n API. This lets you display amounts with localized formatting. Dinero.js is immutable, so we can’t rely on changing Dinero.globalLocale to reformat all existing instances. Instead, we need to use the setLocale method. First, we add a new property language in data and set it to a default value. For locales, you need to use a BCP 47 language tag such as en-US. data() { return { data: { ... }, language: 'en-US' } } Now we can use setLocale directly on Dinero objects. When language changes, the formatting will change as well. export default { ... methods: { toPrice(amount, factor = Math.pow(10, 2)) { return Dinero({ amount: Math.round(amount * factor) }) .setLocale(this.language) } }, computed: { ... getSubtotal() { return this.data.items.reduce( (a, b) => a.add( this.toPrice(b.price).multiply(b.quantity) ), Dinero().setLocale(this.language) ) }, ... } } All we need is to add setLocale in toPrice and getSubtotal, the only places where we’re creating Dinero objects. Now we can add our language switcher: <h1 class="title"> Order <span> <span class="language" @click="language = 'en-US'">English</span> <span class="language" @click="language = 'fr-FR'">French</span> </span> </h1> .language { margin: 0 2px; font-size: 60%; color: rgba(#333a45, 0.6); text-decoration: underline; cursor: pointer; } When you click on the switcher, it will reassign language, which will change how the objects are formatted. Because the library is immutable, this will return new objects instead of changing existing ones. It means if you create a Dinero object and decide to display it somewhere, then reference it somewhere else and apply a setLocale on it, your initial instance won’t be affected. No pesky side effects! All tax included It’s common to see a tax line on shopping carts. You can add one with Dinero.js, using the percentage method. First, let’s add a vatRate property in the JSON file: { ... "vatRate": 20 } And an initial value in data: data() { return { data: { ... vatRate: 0 } } } Now we can use this value to calculate the total of our cart with tax. First, we need to create a getTaxAmount computed property. We can then add it to getTotal as well. export default { ... computed: { getTaxAmount() { return this.getSubtotal.percentage(this.data.vatRate) }, getTotal() { return this.getSubtotal .add(this.getTaxAmount) .add(this.getShippingPrice) } } } The shopping cart now shows the total with tax. We can also add a line to show what the tax amount is: <h3 class="cart-line"> VAT ({{ data.vatRate }}%) <span class="cart-price">{{ getTaxAmount.toFormat() }}</span> </h3> And we’re done! We’ve explored several concepts of Dinero.js, but that’s only scratching the surface of what it has to offer. You can read through the documentation and check out the project on GitHub. Star it, fork it, send me feedback, or even open a pull request! I have a nice little contributing guide to help you get started. You can also look at the final code on CodeSandbox. I’m currently working on bringing a convert method to Dinero.js, as well as better support for all ISO 4217 currencies and cryptos. You can stay tuned by following me on Twitter. Happy coding! 👩🏻‍💻

How to Handle Monetary Values in JavaScript

Money is everywhere. Banking apps, e-commerce websites, stock exchange platforms, we interact with money daily. We also increasingly rely on technology to handle ours. Yet, there’s no consensus around how to programmatically handle monetary values. It’s a prevalent concept of modern societies, yet it’s not a first-class data type in any mainstream language, while things like date and time are. As a result, every piece of software comes up with its own way of handling money, with all the pitfalls that come with it. Pitfall #1: Money as Number Your first instinct when you need to represent money might be to use a Number. Money is nothing more than a numeric value, right? Wrong. The amount part of a monetary value is only relative to another aspect: its currency. There’s no such thing as 10 “money”. It’s 10 dollars, 10 euros, 10 bitcoins… If you want to add two monetary values with different currencies, you need to convert them first. Same if you want to compare them: if all you have is an amount, you can’t make an accurate comparison. Amount and currency can’t go without one another. Pitfall #2: Floating point math Most contemporary currencies are either decimal or have no sub-units at all. This means that when money has sub-units, the number of these in a main unit is a power of 10. For example, there are 100 cents in a dollar, being 10 to the power of 2. Using a decimal system has advantages, but raises a major issue when it comes to programming. Computers use a binary system, so they can’t natively represent decimal numbers. Some languages have come up with their own solutions like the BigDecimal type in Java or the decimal type in C#. JavaScript only has the Number type, which can be used as an integer or a double precision float. Because it’s a binary representation of a base 10 system, you end up with inaccurate results when you try to do math. 0.1 + 0.2 // returns 0.30000000000000004 😧 Using floats to store monetary values is a bad idea. As you calculate more values, the imperceptible precision errors lead to larger gaps. This inevitably ends up causing rounding issues. Pitfall #3: Percentage vs. allocation Sometimes you need to split money but percentages can’t cut it without adding or losing pennies. Imagine you need to bill $999.99 with a 50% downpayment. This can be done with some simple math. Half is $499.995, but you can’t split a penny so you’ll likely round the result to $500. Problem is, as you charge the second half, you end up with the same result and charge a penny extra. You can’t solely rely on percentages or divisions to split money because it’s not divisible to infinity. Gas price may show more than two fraction digits, but it’s only symbolic: you always end up paying a rounded price. Engineering to the rescue As you can see, there is much more to money than meets the eye, and it’s more than simple Number data types can take. Fortunately, software engineer Martin Fowler came up with a solution. In Patterns of Enterprise Application Architecture, he describes a pattern for monetary values: Properties amount currency Methods math: add, subtract, multiply, allocate comparison: equals to, greater than, greater than or equal, lesser than, lesser than or equal. From this, you can create value objects that fulfill most of your monetary needs. Money as a data structure Money behaves differently from a simple number, and thus should be treated differently. The first and most important thing is that it should always be composed of an amount and a currency. You can do everything from an amount and a currency. You can add monetary amounts together, check if they’re equal or not, format them into whatever you need. This can be done through an object’s methods. In JavaScript, any kind of function that returns an object will do the trick. Amounts in cents There are several ways you can solve the floating point issue in JavaScript. You can use libraries like Decimal.js that will handle your floats as strings. This isn’t a bad solution and even comes handy when you have to handle big numbers. Yet, it comes at the expense of adding a (heavy) dependency, and slower performances. You can multiply floats into integers before you calculate, then divide them back. (0.2 * 100 + 0.01 * 100) / 100 // returns 0.21 🎉 It’s a fine solution but requires extra calculations either on object construction or on each manipulation. This isn’t necessarily draining on performances, but still more process work than necessary. A third alternative is to directly store values in cents, relative to the unit. If you need to store 10 cents, you won’t store 0.1, but 10. This allows you to work with integers only, which means safe calculations (until you hit big numbers) and great performances. Dinero.js, an immutable library to create, calculate and format monetary values From these observations, I made a JavaScript library: Dinero.js. Dinero.js follows Fowler’s pattern and more. It lets you create, calculate and format monetary values in JavaScript. You can do math, parse and format your objects, ask them questions and make your development process easier. The library was designed to be immutable and chainable. It supports global settings, has extended formatting options and provides native internationalization support. Why immutable? An immutable library is safer and more predictable. Mutable operations and reference copies are the sources of many bugs. Opting for immutability avoids them altogether. With Dinero.js, you can perform calculations without worrying about altering original instances. In the following Vue.js example, price won’t be altered when priceWithTax is called. If the instance was mutable, it would. const vm = new Vue({ data: { price: Dinero({ amount: 500 }) }, computed: { priceWithTax() { return this.price.add(this.price.percentage(10)) } } }) Chainability Good developers strive to make their code more concise and easier to read. When you want to successively perform several operations on a single object, chaining provides an elegant notation and concise syntax. Dinero({ amount: 500 }) .add(Dinero({ amount: 200 })) .multiply(4) .setLocale('fr-FR') .toFormat() // returns "28,00 US$" Global settings When you’re handling lots of monetary values, chances are you want some of them to share some attributes. If you’re making a website in German, you’ll likely want to show amounts with the German currency format. This is where global settings come in handy. Instead of passing them to every instance, you can declare options that will apply to all new objects. Dinero.globalLocale = 'de-DE' Dinero({ amount: 500 }).toFormat() // returns "5,00 $" Native Internationalization support Traditionally, libraries use locale files for internationalization. If you’re exhaustive, they tend to make libraries much heavier. Moment.js is four times heavier with locale files. Locale files are also hard to maintain. The Internationalization API is native and pretty well supported. Unless you have to work with outdated and/or marginal browsers, toFormat is safe to use. Formatting An object is great to store data, but not so helpful when it comes to displaying it. Dinero.js comes with various formatting methods, including toFormat. It provides intuitive and concise syntactic sugar over Number.prototype.toLocaleString. Pair it with setLocale and you’ll be able to display any Dinero object into the proper format, in any language. This is particularly helpful for multi-lingual e-commerce websites. What’s next? Fowler’s money pattern is widely recognized as a great solution. It has inspired many implementations in many languages. If you’re into DIY, I recommend it and the observations from this article as a starting point. Or you can pick Dinero.js: a modern, reliable, fully tested solution that already works. Have fun! Any questions about Dinero.js? Or on how to make your own money data structure? Let’s chat on Twitter!

Setup For an Open Source JavaScript Project

When I started my career, my mentor told me: “A good developer is a lazy developer. Don’t waste time on repetitive tasks, instead spend it on building automated processes. The computer works for you, and it will always be faster than you.” This was back in 2010, and the toolset we had at our disposal was more scarce than it is today. Yet, this piece of advice has stuck with me ever since. From executable scripts to Yeoman configs, IFTTT setups and Automator workflows, not to mention the slew of apps I use to assist my every move on the computer, I see automation as a game and take a lot of satisfaction in it. JavaScript has exploded since then, but with it has grown complexity. We used to add an external JavaScript file to an HTML page and call it a day, but there’s much more to building a web project now than just coding. We also have more tools than we can use to unload repetitive tasks, so finding your way through it all can be overwhelming. To sort this out, I decided to show you the detailed setup for a real-life project: my latest open source project, Dinero.js. Disclaimer: this isn’t a tutorial on how to make an open source library, but rather an overview of what I use, how, and why. For a thorough step-by-step guide, I recommend the egghead.io course How to Write an Open Source JavaScript Library by Kent C. Dodds. Dependency management npm & Yarn Before the modern times, we used to download dependencies by hand and load them globally in pages. This made things easy but led to a number of problems: duplicate libraries, heavy repositories, difficult version management, etc. Fortunately, we now have a robust and trust-worthy front-end dependency manager: npm. If you come from PHP, you can see npm like Composer and Packagist put together. It provides the richest front-end repository out there, and a great command-line interface to handle dependencies. Many people (including me) prefer using Yarn though: a faster CLI that integrates a powerful cache system, parallelizes downloads and provides an offline mode. Now Yarn is only a layer on top of the npm repository: it browses npm packages, but allows you to use their tool instead. Coding style & conventions EditorConfig Imagine you’re working on several projects, all of which have different conventions. On this library you chose two-space indentation, but this other open source project you contribute to prefers four-space long tabs. Are you going to manually reconfigure your editor every time you switch? EditorConfig is a configuration file that lives in your project and defines editor settings. Every time you work on a project that has an .editorconfig file, your editor will conform to its rules. Most editors can parse .editorconfig files, but if it’s not the case for yours you can still download a plugin. Prettier One of the tools I’m the most grateful for is Prettier. I dig it so much that I have it as an npm script in my project and as a code editor plugin. That’s how deep my love is. Prettier solves the problem of arguing over coding style and wasting time in code review. No more heated discussions around simple vs. double quotes. No more rejected PRs because you forgot a space before an if parenthesis. And above all things, no more wasted time formatting code by hand. Prettier is opinionated, so you’ll get limited room for customizing the default rules. And that’s for the best: that’s not what you should spend your precious time on. ESLint Like with grammar and spelling, your code isn’t immune to typos. Also, it’s not unlikely to accidentally add code that may introduce bugs, like globals or unwanted type coercion. This is what ESLint takes care of. It will not rewrite your file like Prettier does, but you’ll get warnings in the terminal. There is some common territory between ESLint and Prettier, which is why I recommend that: You run Prettier first, then ESLint. You use a tool that ensures they don’t conflict with one another, like eslint-config-prettier. Commitizen & cz-conventional-changelog You’re probably starting to see a pattern here: yes, I’m big into conventions. I’d rather trust a convention and focus on my job than fall into the rabbit hole of bikeshedding, and commit messages fall under that category. Now the idea behind conventional commit messages isn’t only to make pretty commits, it’s about automating a large part of your CI workflow. When you maintain software, there are some tedious tasks that need to be taken care of. Among them are keeping a changelog up to date and versioning the project. Maintaining a changelog by hand is a pain. You have to check every commit since the latest release, filter out what’s doesn’t concern the user (changes to the build system, non-breaking refactors, etc.), find out what effective changes were made and write it down in a human-readable way. Same goes for the version. Depending on the changes, you need to resolve what the next version is. No matter how well you think you know semver, it can be tedious to increment the version by hand. Human error easily leads to incorrect versions, and this can be a big problem for users. This is what Commitizen & cz-conventional-changelog take off your plate. Instead of committing the usual way, you run a script that asks you questions. It will then commit for you with a properly formatted message that follows the Angular Git Commit Guidelines. Later on, when you deploy with semantic-release, those commit messages will be used to generate the changelog and resolve the new version number. Automatically. Nice, right? lint-staged If you’re working in a team, one of the best ways to ensure code quality is doing code reviews. It’s paramount that code going to production goes under at least a second pair of eyes. Now because they’re time-consuming, it’s important that code reviews observe a few rules. Among those, review time shouldn’t be used to spot linting errors. All formatting and linting should happen before committing. It shouldn’t distract the reviewer from doing their job, and it shouldn’t break the build. This is why lint-staged is so useful: every time you commit, it will act as a pre-commit hook and run a script of your choosing. In Dinero.js, here’s what’s my lint-staged configuration looks like: { "lint-staged": { "*.js": ["npm run lint!", "git add"] } } The npm run lint! command sequentially triggers two other scripts: npm run format (Prettier), then npm run lint (ESLint). Every time I try to commit a JavaScript file, Prettier will reformat it. Then, ESLint will perform a scan: if it passes, the commit will go through. Otherwise, ESLint will throw an error and the commit will be aborted. Documentation JSDoc Documentation should live as close as possible from the code it describes. This is a good way to keep it up to date and guarantee its exhaustiveness. A great implementation of this idea is doc blocking: using formatted comments to document code, which can then automatically generate a documentation website. In JavaScript, the most popular documentation generator is JSDoc. With JSDoc, all you need to do is add a comment with specific tags and descriptions above every significative part of the code (a function, a module, etc.) { /** * Returns the currency. * * @example * // returns 'EUR' * Dinero({ currency: 'EUR' }).getCurrency() * * @return {String} */ getCurrency() { return currency } } This doc block has a description, one example and a typed return value. Once written, doc blocks can be turned into a documentation website with a single command. You can use any pre-existing JSDoc template to generate your website or create yours. Here’s how the doc block for Dinero.getCurrency looks like once compiled into a website. Why not ESDoc? The younger kid on the block, ESDoc, takes a different approach than JSDoc. Among other things, ESDoc was designed to work well with ES6 classes, and concrete code in general. The downside is that it doesn’t support factory functions. Factory functions are dynamic object generators, a behavior that ESDoc doesn’t cover. If you try to document a factory with ESDoc, the generated documentation will come back empty. In my case, factories are the building blocks of Dinero.js, which explains my choice. If your project uses the ES6 class syntax, ESDoc will meet all your needs. Else, go with JSDoc: it supports all ES6 features, as well as “older” patterns like factory functions and the original syntax for constructors. Algolia DocSearch You may have written your documentation with care and presented it in a pretty website, at the end of the day, what matters is for users to find what they need as quickly as possible. Nobody likes to break their flow for too long to go find something they need. It’s no surprise StackOverflow is so popular: people need answers to their questions, and they need it fast. Algolia is the best search service out there. Their (free) DocSearch solution lets you create an excellent documentation experience for your users. DocSearch is an on-demand service: once your docs are ready, send them a URL and you’ll get a code snippet to add to your website. Tests Mocha & Chai Unit testing is crucial. If you can only do one thing for code quality, forget linting, forget formatting, forget code reviews and write unit tests. Unit testing forces you to build modular, single-responsibility code and ensures you don’t break things that used to work fine. It’s a crucial part of continuous integration. If you’re serious about what you’re building, you should 100% unit test it. Now if you’re just starting out, unit testing may seem a bit scary. The good news is they don’t have to be: thanks to tools like Mocha and Chai, writing tests comes really close to being fun. Here’s an excerpt from my unit tests for Dinero.js: import chai from 'chai' import Dinero from '../../src/dinero' const expect = chai.expect describe('Dinero', () => { describe('#getAmount()', () => { it('should return the right amount as a number', () => { expect(Dinero({ amount: 500 }).getAmount()).to.equal(500) }) it('should return the default amount as a number when no amount is specified', () => { expect(Dinero().getAmount()).to.equal(0) }) }) }) This JavaScript file, called a “spec”, uses the Mocha framework and the Chai assertion library. The public API is built to look like actual English sentences: even non-technical people can read the spec files and understand what’s going on. This makes it easy for new contributors, because the learning curve is almost non-existent. Tests using Mocha and Chai are natively run with Node.js, which means it expects CommonJS modules for the spec and source files. But thanks to Babel, we don’t have to write CJS if we don’t want to: we can still use ES modules and transpile them on the fly as we run tests! This is how I’m able to include modules with import instead of require and still have fully working tests. Istanbul & Coveralls Writing unit tests is great, but as your project scales, you may lose track of what needs to be tested. It’s not your fault: you’re busy building something and there are a lot of things to remember. That’s why we automate tasks, to assist ourselves and help us remember things we forget. Code coverage monitors your code on a regular basis (usually every time you run tests) and gives you a report of the amount of code that’s covered by unit tests. Istanbul is a code coverage tool. In Dinero.js I use nyc, its command-line interface, to generate reports. An Istanbul report once unit tests are done. Istanbul generates reports in all kinds of formats: terminal output, HTML, but also LCOV. This one is particularly useful when used with online services like Coveralls. Every time Travis CI runs a build, it executes tests and nyc generates an LCOV file. It’s then sent to Coveralls which generates detailed stats. This is particularly useful for contributions: when someone submits a pull request, a Coveralls bot automatically replies with the updated coverage. This contributes to making code reviews easier and quicker. Build Babel ES6+ has brought amazing features to JavaScript, but they’re still not supported everywhere. This doesn’t mean you must wait before you can start to use it: meet Babel. Babel is a transpiler. It translates code into another language or another version of the same language. Your source code remains the same, but what the user gets is translated into another syntax to ensure it works in their environment. You get to use cutting-edge features, neat syntaxes and keep your source code clean, and you don’t have to worry about it working on old browsers. I’ve written the entire Dinero.js source code using ES6 features, such as fat arrow functions and ES modules. Every time I release a version, Babel transpiles the source files into distributable ES5 code. Babel also comes handy for unit testing. I’m using Node.js for that, which doesn’t natively support ES modules yet, thus can’t handle my source files. Thanks to Babel, I can transpile them on the fly every time I run my test command. Rollup Once your library is ready, you need to package it so it can be used by different people in different environments. Some will use it with Node. Some will need it directly in the browser as a script tag. Others will want it as an ES module to be included it in their own project and bundled with their own tools. Rollup is a module bundler like Webpack or Parcel, but it’s particularly useful for building JavaScript libraries. It was designed to work with ES modules, and turn them into any module format you want. Back in the days, the code we wrote was exactly the code that ended up in production. If you wanted your code to be as ubiquitous as possible, you’d wrap it into a UMD pattern by hand. Today, you can code exactly the way you want and ship different bundles for everyone, thanks to module bundlers like Rollup. Need a UMD version? There you go. Along with an AMD, a CJS, an IIFE, anything. CI GitHub The most popular collaborative open source platform needs no introduction. GitHub is a wonderful product that fulfills everything developers can hope for and beyond. It hosts most of my projects. It hosts this blog. It connects with the best CI tools on the market. If you want to contribute to your favorite open source projects, build yourself a reputation and create the next best tools for other developers, look no further. Travis CI You can look at Travis CI as the conductor of your project’s build process. Crafting a quality project is hard, and coding is only a small part of it. There are tasks to run in a certain order, at the right time, under the right circumstances. Here’s a list of all that needs to be done once I want to ship anything for Dinero.js: Run unit tests. If they pass: Run code coverage Build a version (dist files) Recompile the docs Tag a version and push the tag on GitHub Increment the version and push the build to npm Write an entry in the changelog Push the docs files to GitHub Pages Otherwise, fix things, rinse and repeat. Before I installed my CI pipeline, I tried doing this by hand. Guess what? There hasn’t been a single time when I did it right. Why? Because as a typical human, I’m error-prone and subject to distractions. On the other hand, machines respond well to orders. They will do exactly what you want, how you want it. All you have to do is specify it well, once. Travis CI is free for open-source projects and integrates well with third-party services. All you have to do is log in with your GitHub account and sync a project. By default, Travis will execute tests every time you push to your remote repository. Then, you can tell Travis what to do when tests pass with a .travis.yml file at the root of the project. semantic-release Before getting into what semantic-release does, you need to understand Semantic Versioning (aka “semver”). In short, semver is a convention based on an X.Y.Z numeric format, respectively the MAJOR, the MINOR and the PATCH: When you fix a bug but your changes are backwards compatible, you increment the PATCH. When you add a feature but your changes are still backwards compatible, you increment the MINOR. When you make any kind of backwards incompatible changes, you increment the MAJOR. This helps people who depend on your project know if they can safely upgrade, and simplifies dependency management in general. Semantic Versioning is widely used in software development, but it can be hard to enforce. Again, we humans are error-prone and sentimental creatures. If you forget to take a commit into account, have a doubt on the nature of a change, or simply don’t understand semver quite yet, you can mislabel a new version. If you fix a small bug that slipped your attention just after releasing a new version, you might be tempted to sneak it in and act like nothing happened. This is where semantic-release comes into play. In short, semantic-release takes care of versioning for you. You have no say in it. It uses your conventionally written commit messages to decide what the next version will be. Add it to your CI pipeline (in your Travis CI workflow, for example), and you get a fully automated system that will read your commits, change the version, tag it, push to GitHub, push to npm, and write your changelog. Phew. Isn’t it a bit much? This may look like a lot of things to set up. “Do I really need all this?”, you may wonder. I’ll reply with a few questions: how many tasks are you currently handling by hand? How much time does a release take you? How confident are you when you do it? When was the last time you performed your entire workflow without forgetting anything? I personally can’t deploy a release by hand without a cheat sheet. Linting, formatting, testing, code coverage, docs, building, semantic versioning, releasing, updating the changelog, all in that order while making sure I’m on the right branch… ugh. Really hope I didn’t leave a typo! This process is so time-consuming, you can screw it up in so many ways, and it’s repeatedly taking you so much time from actual work, that automating it should be a no-brainer. It looks tricky when you’re not used to it, but once you’ve built your workflow, all you have to do is maintain it. Update dependencies, keep an eye on innovative new tools, improve the process. You can even use a scaffolding tool to save your whole configuration and deploy ready-to-use project templates. Give it a try! What about you? What’s your workflow for web projects? What has made your life easier? Come chat with me about it on Twitter!

Multi-Colored SVG Symbol Icons with CSS Variables

Long gone are the days of using images and CSS sprites to make icons for the web. With the explosion of web fonts, icon fonts have become the number one solution for displaying icons in your web projects. Fonts are vectors, so you don’t have to worry about resolution. They benefit from the same CSS properties as text. As a result, you have full control over size, color, and style. You can add transforms, effects, and decorations such as rotations, underlines or shadows. No wonder why projects like Font Awesome have been downloaded more than 15 million times on npm alone to this day. Icon fonts aren’t perfect though, which is why a growing number of people prefer using inline SVG images. CSS Tricks wrote a list of areas where icon fonts fall short compared to native SVG elements: sharpness, positioning, or even failures because of cross-domain loading, browser-specific bugs, and ad-blockers. Now you can circumvent most of these issues, and usually, icon fonts are a safe choice. Yet, there’s one thing that remains absolutely impossible with icon fonts: multicolor support. Only SVG can do this. TL;DR: this post goes in-depth in the how and why. If you want to understand the whole thought process, read on. Otherwise you can look at the final code on CodePen. Setting up SVG symbol icons The problem with inline SVG is how verbose they are. You don’t want to copy/paste all that amount of coordinates every single time you need to use the same icon. This would be repetitive, hard to read and a pain to maintain. With SVG symbol icons, you have one copy of each SVG element, and you instantiate them anywhere with a reference. You start by including the SVG inline, hide it, wrap it in a <symbol> and identify it with an id attribute. <svg xmlns="http://www.w3.org/2000/svg" style="display: none"> <symbol id="my-first-icon" viewBox="0 0 20 20"> <title>my-first-icon</title> <path d="..." /> </symbol> </svg> The full SVG markup is included once and hidden in the HTML. Then, all you have to do is instantiate the icon with a <use> element. <svg> <use xlink:href="#my-first-icon" /> </svg> This will display an exact copy of your original SVG icon. That’s it! Pretty nice, right? You probably noticed the funny xlink:href attribute: this is the link between your instance and the original SVG. It’s important to mention that xlink:href is a deprecated SVG attribute. Even if most browsers still support it, you should use href instead. Now the thing is, some browsers like Safari don’t support SVG resource references through the href attribute, so you still need to provide xlink:href. To be safe, provide both attributes. Adding some color Unlike with fonts, color doesn’t have any effect on SVG icons: you must use the fill attributes to define a color. This means they won’t inherit parent text color like icon fonts do, but you can still style them in CSS. <svg class="icon"> <use xlink:href="#my-first-icon" /> </svg> .icon { width: 100px; height: 100px; fill: red; } From here, you can create other instances of the same icon with a different fill color. <svg class="icon icon-red"> <use xlink:href="#my-first-icon" /> </svg> <svg class="icon icon-blue"> <use xlink:href="#my-first-icon" /> </svg> .icon { width: 100px; height: 100px; } .icon-red { fill: red; } .icon-blue { fill: blue; } It works, but this isn’t exactly what we want. So far, all we did can be achieved with a regular icon font. What we want is have a different color for each part of the icon. We want to fill each path with a different color, without altering other instances, and we want to be able to override it if necessary. At first, you might be tempted to rely on specificity. <svg xmlns="http://www.w3.org/2000/svg" style="display: none"> <symbol id="my-first-icon" viewBox="0 0 20 20"> <title>my-first-icon</title> <path class="path1" d="..." /> <path class="path2" d="..." /> <path class="path3" d="..." /> </symbol> </svg> <svg class="icon icon-colors"> <use xlink:href="#my-first-icon" /> </svg> .icon-colors .path1 { fill: red; } .icon-colors .path2 { fill: green; } .icon-colors .path3 { fill: blue; } This won’t work. We’re trying to style .path1, .path2 and .path3 as if they were nested in .icon-colors, but technically speaking they’re not. The <use> element isn’t a placeholder that gets replaced by your SVG definition. It’s a reference which clones the content it’s pointing to into the shadow DOM 😱 What can we do then? How can we affect children content in a scoped way when said children aren’t in the DOM? CSS variables to the rescue In CSS, some properties are inherited from ancestors to children. If you assign a text color to the body, all the text in the page will inherit that color until they’re overridden. The ancestor isn’t aware of the children, but the inheritable styles are still propagated. In our early example, we inherited the fill property. Look again, you’ll see that the class in which we declared a fill color is appended on the instances, not the definitions. This is how we were able to get different colors for each instance of a single definition. Now here’s the problem: we want to pass different colors to different paths of the original SVG, but there’s only one fill attribute we can inherit from. Meet CSS variables. CSS variables are declared within rulesets just like any other property. You can name them anything you want, and assign them any valid CSS value. Then, you declare it as a value for itself, or any child property, and it will be inherited. .parent { --custom-property: red; color: var(--custom-property); } All children of .parent will have red text. .parent { --custom-property: red; } .child { color: var(--custom-property); } All .child nested in .parent elements will have red text. Now let’s apply this concept to our SVG symbol. We’ll use the fill attribute on each path of the SVG definition, and set them to different CSS variables. Then, we’ll assign them different colors. <svg xmlns="http://www.w3.org/2000/svg" style="display: none"> <symbol id="my-first-icon" viewBox="0 0 20 20"> <title>my-first-icon</title> <path fill="var(--color-1)" d="..." /> <path fill="var(--color-2)" d="..." /> <path fill="var(--color-3)" d="..." /> </symbol> </svg> <svg class="icon icon-colors"> <use xlink:href="#my-first-icon" /> </svg> .icon-colors { --color-1: #c13127; --color-2: #ef5b49; --color-3: #cacaea; } And… it works! 🎉 From now on, all we need to create an instance with a different color scheme is to create a new class. <svg class="icon icon-colors-alt"> <use xlink:href="#my-first-icon" /> </svg> .icon-colors-alt { --color-1: brown; --color-2: yellow; --color-3: pink; } If you still want to have monochrome icons, you don’t have to repeat the same color on every CSS variable. Instead, you can declare a single fill rule: because CSS variables aren’t defined, it will fall back on your fill declaration. .icon-monochrome { fill: grey; } Your fill declaration will work because the fill attributes on the original SVG are set with undefined CSS variables values. What to name my CSS variables? There usually are two routes you can take when it comes to naming things in CSS: descriptive or semantic. Descriptive means calling a color what it is: if you’re storing #ff0000, you’d call it --red. Semantic means calling the color by how it’s applied: if you’re using #ff0000 for the handle of a coffee cup, you’d call it --cup-handle-color. Descriptive names might be your first instinct. It feels DRYer since #ff0000 can be used for other things than the handle of the coffee cup. A --red CSS variable is reusable for other icon paths that need to be red. After all this is how utility-first CSS works and it’s a fine system. Problem is, in our case we can’t apply granular classes to the elements we want to style. Utility-first principles can’t apply because we have a single reference for each icon, and we have to style it through class variations. Using semantic class names, like --cup-handle-color for example, makes more sense for this use case. When you want to change the color of a part of an icon, you instantly know what it is and what to override. The class name will remain relevant, no matter what color you assign. To default or not to default It’s tempting to make the multi-colored version of your icons be their default state. This way, you could use them with no need for extra styling, and you would add your own classes only when necessary. There are two ways to achieve that: :root and var() default. :root You can define all your CSS variables on the :root selector. This keeps them all in one place and allows you to “share” similar colors. :root has the lowest priority, so it remains easy to override. :root { --color-1: red; --color-2: green; --color-3: blue; --color-4: var(--color-1); } .icon-colors-alt { --color-1: brown; --color-2: yellow; --color-3: pink; --color-4: orange; } However, there are major drawbacks with this method. First, keeping color definitions separate from their respective icons can be confusing. When you decide to override them, you have to go back and forth between the class and the :root selector. But more importantly, it doesn’t allow you to scope your CSS variables, thus keeps you from reusing the same names. Most of the time, when an icon only uses one color, I use the --fill-color name. It’s simple, understandable, and it makes sense to use the same name for all icons that only need one fill color. If I have to declare all variables in the :root declaration, I can’t have several --fill-color. I’ll be forced to define --fill-color-1, --fill-color-2, or use namespaces like --star-fill-color, --cup-fill-color. var() default The var() function, which you use to assign a CSS variable to a property, can take a default value as a second argument. <svg xmlns="http://www.w3.org/2000/svg" style="display: none"> <symbol id="my-first-icon" viewBox="0 0 20 20"> <title>my-first-icon</title> <path fill="var(--color-1, red)" d="..." /> <path fill="var(--color-2, blue)" d="..." /> <path fill="var(--color-3, green)" d="..." /> </symbol> </svg> Until you define --color-1, --color-2 and --color-3, the icon will use the default values you set for each <path>. This solves the global scope issue we have when using :root, but be careful: you now have a default value and it’s doing its job. As a result, you can’t use a single fill declaration to define monochrome icons anymore. You’ll have to assign the color to every CSS variable used on the icon, one by one. Setting default values can be useful, but it’s a tradeoff. I suggest you don’t make it a habit, and only do it when it makes sense for a given project. How browser-friendly is all that? CSS variables are compatible with most modern browsers but as you probably expect it, Internet Explorer doesn’t support it at all. Not even IE11, and since development was discontinued in favor of Edge, there’s no chance it will ever get up to speed. Now, not because a feature isn’t supported by a browser you need to cater to means you have to rule it out altogether. In such cases, go for graceful degradation: offer multi-colored icons to modern browsers, and provide a fallback fill color for older ones. What you want to do is set a declaration that will only work if CSS variables aren’t supported. This can be achieved by setting the fill property to the fallback color: if CSS variables are supported, it won’t even be taken into account. If they’re not, your fill declaration will apply. If you’re using Sass, this can be abstracted into a @mixin. @mixin icon-colors($fallback: black) { fill: $fallback; @content; } We can now define color schemes without worrying about browser compatibility. .cup { @include icon-colors() { --cup-color: red; --smoke-color: grey; }; } .cup-alt { @include icon-colors(green) { --cup-color: green; --smoke-color: grey; }; } Passing the CSS variables in the mixin through @content is optional. If you do it outside, the compiled CSS will be the same. Yet this can be helpful to package it all in one place: you can fold snippets in your editor and visually identify declarations that go together. Check out this pen on different browsers. On up-to-date versions of Firefox, Chrome, and Safari, the last two cups will respectively be red with grey smoke and blue with grey smoke. On Internet Explorer and Edge before version 15, the third cup will be all red and the fourth will be all blue! ✨ See the Pen Multi-Colored SVG Symbol Icons with CSS Variables by Sarah Dayan (@sarahdayan) on CodePen. If you want to learn more about SVG symbol icons (and SVG in general), I strongly suggest you read everything by Sara Soueidan. And if you have any question about CSS symbol icons, don’t hesitate to hit me up on Twitter!

In Defense of Utility-First CSS

“Favor composition over inheritance”. This piece of wisdom from Design Patterns, one of the most influential software engineering books, is the foundation of utility-first CSS. It also shares many principles with functional programming: immutability, composability, predictability, and avoidance of side-effects. The goal behind all those fancy terms is to write code that’s easier to maintain and to scale. Despite its growing popularity, utility-first CSS still hasn’t convinced everyone. While some praise it, others have been vividly critical about such a practice. I used to be in the latter group. I was a BEM fan, sold to an approach I adopted for its advantages and ended up rooting for like we do for a sports team. I rejected utility-first because it was implying my beloved and familiar approach wasn’t good anymore. Since then, I’ve dived a lot deeper into the topic. I studied design patterns and functional programming, and this allowed me to radically revise my judgment. CSS Tricks and Adam Wathan did a brilliant job at taking us on a journey from “regular” CSS to utility-first, and explaining the “why” behind it. Rather than paraphrasing, I’ll focus on the recurring criticism of utility-first and debunk common misconceptions. “Might as well use inline styles” The gut reaction people usually have when they see utility-first CSS is to compare it to applying CSS rules to HTML nodes through the style attribute. This way of styling is unanimously considered a bad practice, and we have since moved on to separate stylesheets and class abstractions. Utility-first CSS is no different. All styles are defined and maintained separately. This allows code reuse, usage of pseudo-classes, pseudo-elements, pre-processors and browser caching. Yet, atomic CSS detractors hurriedly associate it to inline styles. Atomic classes are small, they often have only one rule, and they’re named in a functional way instead of being semantic. All that being said, just because it looks the same doesn’t mean it is the same. Understanding how both practices differ is key to grasping the benefits of utility-first. Inline styles allow you to do anything you want. You don’t have to follow any pre-existing definition. You’re re-writing everything from the ground up every time you style a new HTML node. Similar elements end up with duplicate code, which makes the page unnecessarily heavier. If you’re not careful, it’s easy to ignore pre-existing solutions and reinvent the wheel every time. <h2 style="font-size: 16px; font-weight: bold; color: purple">Stranger Things</h2> <p style="font-size: 13px; font-style: italic">Stranger Things is an American science fiction-horror web television...</p> <h2 style="font-size: 16px; font-weight: bold; color: purple">Game of Thrones</h2> <p style="font-size: 13px; font-style: italic">Game of Thrones is an American fantasy drama television...</p> Unnecessarily verbose, heavier file size, multiple sources of truth for a single design concept. <button style="padding: 5px 8px; font-size: 13px">Button</button> <button style="padding: 0 8px; font-size: 13px; line-height: 23px">Button</button> <button style="display: flex; padding: 0 8px; font-size: 13px; height: 23px; align-items: center">Button</button> Three attempts at solving the same problem. This is easily induced by the absence of a single source of truth, and likely to cause visual inconsistencies. Utility classes expose a well-defined API that you can use to compose more complex components. You’re not re-writing styles; instead, you’re relying on classes that define styles and behaviors once and for all. <h2 class="font-16 font-bold font-purple">Stranger Things</h2> <p class="font-13 font-italic">Stranger Things is an American science fiction-horror web television...</p> <h2 class="font-16 font-bold font-purple">Game of Thrones</h2> <p class="font-13 font-italic">Game of Thrones is an American fantasy drama television...</p> /* Font sizes */ .font-13 { font-size: 13px } .font-16 { font-size: 16px } ... /* Font styles */ .font-bold { font-weight: bold } .font-italic { font-style: italic } ... /* Font colors */ .font-purple { color: purple } ... Using a defined set of existing CSS rules, no matter how atomic they are, forces you to pick styles from a limited list. You’re not granted total freedom like you are with inline styles. You’re maintaining a consistent catalog of allowed styles on the one hand, and using them to compose larger components on the other hand. This approach enforces consistency by limiting you in the ways you can style elements in your project: instead of having access to 16+ million colors, you only have access the number of colors defined in your theme. It also provides a single source of truth: instead of re-declaring the same color for each element that uses it, you define it once in a class and use that class wherever you need it. In addition to that, using separate styling (with atomic classes or not) gives you access to pseudo-classes and pseudo-elements, pre-processors, caching… a whole load of benefits that aren’t available with inline styles. You may argue that it doesn’t matter if atomic styles are limited: carelessly mixing them may result in inconsistent layouts like with inline styles. But that’s a human issue, not a technical one. You get the exact same problem with any approach, and any language for that matter, whether you’re able to scope or not: if you don’t follow the rules, style guides and best practices that your team put in place, you’re the one to blame. Not the program, not the language, and not the architecture. “It violates separation of concerns” One of the biggest arguments against functional CSS is that it goes against separation of concerns. That CSS should strictly be in charge of the styling, and HTML should semantically structure the page. That by using atomic classes and composing components in the HTML, you’re somewhat delegating styling to the HTML instead of doing it in CSS. This is an extreme, and ultimately warped, vision of what “separation of concerns” means. I remember a few years back, I was on a job interview with a front-end developer who told me everything about his sheer disdain for Bootstrap. According to him, using extra markup to create a grid was a heresy: that’s a job for CSS, and CSS only. HTML should be 100% oblivious to how it’s rendered. The problem with that kind of thinking is that it’s deeply impractical. It raises design principles to a dogmatic level, ignoring concrete use-cases and context. It pushes you to be more concerned about checking all the “good practice” checkboxes than solving actual problems. Adam Wathan explains it well (see: “Separation of concerns” is a straw man): when it comes to HTML and CSS, you can’t look at it from a strict “separation of concerns” perspective. It’s a “which depends on which” relationship. Make no mistake: just because style composition is performed in the HTML document doesn’t mean it’s done in HTML. We’re not using style or align attributes on HTML nodes. We’re assembling pieces that we defined in a proper stylesheet, in CSS. Our HTML becomes a consumer of our CSS “API”. As Vue.js explains it in their documentation, separation of concerns doesn’t equal separation of file types. Your styles can be composed on HTML nodes, it’s still a CSS job. “It bloats the HTML” When people mention code bloat, they usually mean one of two things (or both): code that’s hard to read, and a heavier codebase. The complexity of your layout has to exist somewhere. A component-first approach doesn’t remove “bloat”, it only deports it to the stylesheet. Even so, because your larger components reuse the same atomic styles as others, you inevitably end up with duplicate code. $green: #74b759; .component { &-title { color: $green; font-weight: bold; } } .widget { &-title { color: $green; font-style: italic; } } .footer { &-links { color: $green; text-decoration: underline; } } Even with Sass, you get duplicate rules in the source code. @mixin can help, but you still get duplicates in the compiled CSS. Now I know what you’re thinking. We got @extend. That’s an ideal use case for it, right? Not so fast. @extend may avoid ruleset duplication in the compiled CSS, but the mega comma-separated selector it will generate could end up being a lot heavier than if you had duplicated the rule. So much for avoiding bloat. You’re also concatenating unrelated classes and moving them all to the top, where the first @extend takes place. This can quickly result in specificity issues and odd overrides. Not to mention that you can’t @extend an outer class or placeholder from within a media query. So yeah, definitely not a silver bullet. From a file size standpoint, you shouldn’t worry about repeated class names in the HTML. That’s what Gzip is for. The deflate algorithm was specifically made to handle duplicate strings, so there’s no point in trimming away characters in your HTML. The resulting file size will make little to no difference whether you use a few or a lot of classes. On the other hand, the more a selector is repeated in a stylesheet, the more work your browser has to do to resolve all styles. If you have a single .title-green class for a given style, it simply matches all .title-green in the page. But if you have many classes doing the same thing (using @mixin) or similar selectors doing different things (using @extend), the more expensive it will be for the browser to match. HTML “bloat” doesn’t matter, but CSS does. The network and engine don’t care how many classes you have in your HTML, but the way you write your CSS counts. If your decision-making process revolves around performances, make sure you focus your attention on the right things. “BEM is enough” OOCSS and all derived methods (SMACSS, BEM, etc.) drastically improved how we handle CSS. Utility-first CSS is itself an heir of this approach: it, too, defines reusable objects. The problem with BEM is that it focuses on building components first. Instead of looking for the smallest, unsplittable patterns, you’re building blocks and their child elements. BEM does an excellent job at namespacing and preventing style leaks, but its component-first nature inevitably leads to premature abstraction: you make a component for a certain use-case and end up never reusing it (a navbar component, for example). BEM encourages you to use modifiers to handle component variations. This may seem smart at first, yet unfortunately leads up to other problems: you end up creating tons of modifiers you only use once for a specific use-case. Worse: from one component to another, you might end up with similar modifiers, further breaking the DRY principle. .card { background: white; border: 1px solid grey; text-align: justify; } .card--left { text-align: left; } .card--right { text-align: right; } .tooltip { background: black; color: white; text-align: center; } /* Oops, looks like duplicate rules down there! */ .tooltip--left { text-align: left; } .tooltip--right { text-align: right; } At scale, components can become hard to change without breaking instances throughout a project. Premature abstraction keeps components from evolving and splitting into independent entities if they need to. Modifiers multiply as an attempt to fix it, resulting in non-reusable variations for unicorn use-cases, and undo band-aids when we realize our component does too much. BEM is a great attempt at fixing inherent CSS problems, but making it the core CSS approach of your project brings all the problems you meet when favoring inheritance over composition. “It’s a whole other language to learn on top of CSS” This statement can be said of any naming system for any specific project, whatever methodology you pick. Your CSS class names ecosystem is a layer of abstraction on top of pure CSS. Whether you’re using semantic names like .card or functional ones like .bg, new contributors will need to familiarize themselves with what does what and when to use it. You can’t escape having to use a naming interface between your HTML and CSS, unless you’re willing to either describe your exact markup in CSS or write inline styles. Ultimately, functional class names are easier to understand because they describe the style. You know what they do without having to lookup the actual styles, while semantic names force you to either look at the rendering or browse code. “It’s unmaintainable” When people say utility-first CSS is unmaintainable, they often mention that when something changes in the design, you have to change it everywhere. You have buttons with regular corners and you decide to make them rounded, so you need to add the .rounded-corners utility class on every button in the code. Yet, the whole point of utility-first is that you start composing with utility classes, and then create components when you start identifying repetitive patterns. A button is an ideal and most obvious candidate for being abstracted into its own component. You might not even need to go through the “utility-first, then component” phase for this case. When it comes to larger components, favoring composition first is the best choice for maintainability. Why? Because it’s safer to add or remove classes on a specific HTML node than to add or remove styles in a class that applies on many elements. Too many times have I been subjected to changing designs, and had to duplicate existing components to make them behave differently because I had no other choice. Even when a designer supplies all designs at the beginning of a project, and even if you do a great job at identifying components before you code, you can’t predict the future. Let’s say initial designs have white cards with an inset box shadow and a little ribbon in the corner. .card { position: relative; background: white; padding: 22px; border: 1px solid lightgrey; text-align: justify; border-radius: 5px; box-shadow: 0 0 5px 0 rgba(0, 0, 0, .2); overflow: hidden; } .card::after { position: absolute; top: -11px; right: 9px; display: block; width: 10px; height: 50px; background: red; transform: rotateZ(-45deg); content: ''; } <div class="card">...</div> This solution is simple, semantic and reusable. You handle everything in CSS and only have minimal HTML to write. But suddenly you get new designs for new pages, and they’re using the card without the ribbon. Now you have to find a way to remove the ribbon for these new cards. .card-no-ribbon::after { display: none; } Problem is, this class is undoing something that was previously designed. Having to add a class to remove a feature is an anti-pattern: it’s counter-intuitive and hard to maintain. When you decide to change how the base class behaves, you need to keep an eye on the undo modifier to make sure it still works. We now need to add another ribbon to the bottom left. .card::before, .card::after { /* shared code */ } .card::before { top: -11px; right: 9px; } .card::after { bottom: -11px; left: 9px; } But now we need to update .card-no-ribbon! .card-no-ribbon::before, .card-no-ribbon::after { display: none; } This, right here, is the fragile base class anti-pattern in action. Because your base class was abstracted too soon, is doing too much, and now needs to evolve, you can’t edit it without worrying about possible side-effects. If new people start contributing to the project, those risks multiply by ten. The only option you have left this stage is to do a refactor: have a nude .card as the base class, and add the ribbons with .card--top-ribbon and .card--bottom-ribbon modifiers. But now you have to edit all the existing .cards in your code that do need to have a ribbon. Early refactors are a pretty good indicator of unmaintainability. You could argue that a smart developer could have seen it coming. That they should have made a naked .card base class and a .card--ribbon modifier, right from the start. That’s actually making a case in favor of utility-first and composition. You’re taking the decision to break down a given design element that you deemed too monolithic, so it’s easier to scale. That’s a good call. The more you go, the more you’ll realize this leads to utility-first. You might think it doesn’t, and that your job is to foresee what is the bare minimum for a given component, but unless you own a crystal bowl this is a risky assessment. Plus, this is short-sighted: what if parts of your component need to be extended to other components? Like, what if you now need buttons with ribbons? If you duplicate the .card--ribbon class, your code isn’t DRY anymore. Which makes it even more unmaintainable. So? Make a mixin and import it into both modifiers? Again, that’s extra work and “wet” code. The best solution for this use-case is to write a single utility class for the ribbon, and modifiers for sizes and colors if necessary. This allows you to have a single source of truth and use the ribbon anywhere you want to. If tomorrow you need to put ribbons on avatars, panels, unordered lists, modals, you can do it without having to write a single extra line of CSS. This is the definition of scalability and maintainability. All you have to do is reuse the available code you wrote proactively, instead of having to tweak existing code reactively. .ribbon { position: relative; overflow: hidden; } .ribbon::after { position: absolute; display: block; top: -11px; right: 9px; width: 10px; height: 50px; background: red; transform: rotateZ(-45deg); content: ''; } By breaking down designs into small elements, we write much more reusable code. Calling utility-first CSS “unmaintainable” is absolutely inaccurate. In fact, it may be the most maintainable and scalable CSS methodology to this day. You can’t predict the future. This is why you should always favor composition over inheritance. A good sign of a healthy and scalable codebase to how things go when you need to change it. If a new change makes you anxious because you might break something, it’s a sign of poor design. But I would go a step further and say that if you need to write new CSS to make an existing component do something that another component already does, your code isn’t as scalable as you think it is. If you need to reuse behavior that exists somewhere, you shouldn’t have to write new code. You should be able to trust and use what you already wrote and go from there. You have one source of truth on which you can rely, instead of two or more slight variations that you must not forget to keep up to date. This is the definition of maintainability. “It’s ugly and hard to read” Do you remember the uproar when BEM started to become popular? I do. I remember many people who were rejecting the whole thing only because of its syntax. Praising the model, but disgusted to the idea of chaining two underscores or two hyphens. As humans, it’s in our nature to be easily put off by what we’re not familiar with. Yet, letting subjective cosmetic considerations come in the way of a potentially useful technique is where developers should draw the line. Our job is to solve problems. Our main concern should be the end user. Look at the source code of many big projects, most of them have ended up adopting BEM. Chances are not all their front-end developers were sold at the beginning. Overcoming initial feelings, especially if driven by personal preference, isn’t that hard when you’re putting the success of a project first. Now on the topic of legibility, I get that long strings of classes can be “scary” when you open a file for the first time. This is not an insurmountable task though. More verbose code is a trade-off of composition, but it’s a much lesser inconvenience than unscalability. I don’t use shorthands like .pt-8 or .bb-lemon in my own code. I favor full-length class names like .padding-top-8 and .border-bottom-lemon which are much easier to read. Autocomplete solves the problem of having to type long class names, and there are tools you can use to re-hash class names into smaller ones for production. I doubt this will make any significant change to your performances but hey, if it makes you feel good to shave bytes away, knock yourself out 😊 Ultimately, the nature of functional class names might actually be more expressive. It’s easy for your brain to make a connection between such a class and what’s happening on screen. Even if you don’t get to see how it renders, you can get a pretty good idea of what .hidden or .opacity-6 are supposed to do. <blockquote class="border-thick-left-red padding-left-medium font-navy"> <p>You know how they call a Quarter Pounder with Cheese in Paris?</p> </blockquote> Stylistically speaking, it’s pretty easy to know what’s going on here. Semantic class names don’t convey the same thing. It works for small components like buttons or alerts, which are common enough to be easily recognized. Yet, the bigger and the more complex a component gets, the less obvious it is to know what class name maps to what element on the screen, or what it looks like. <div class="entry"> <h2 class="entry-title">The Shining</h2> <div class="widget widget-lead"> <div class="widget-content"> <p>His breath stopped in a gasp. An almost drowsy terror stole through his veins...</p> </div> <div class="author"> <img class="author-avatar" src="..."> <h3 class="author-name">Stephen King</h3> <p>Stephen Edwin King (born September 21, 1947) is an American author of horror, supernatural fiction, suspense, science fiction, and fantasy...</p> <div class="btn-group"> <a class="btn" href="#">Website</a> <a class="btn" href="#">Twitter</a> </div> </div> </div> </div> Harder to know what class does what without going through the stylesheet. In that way, functional classes are a lot easier to understand than semantic class names. They demand less catching up time, less file-switching and ultimately give you the very bit of information you’re looking for anyway when dealing with them. “It’s not how you write CSS” CSS specificity is a feature, not a bug. Use it correctly, and it will give you amazing control. That’s what CSS veterans say when yet another article about the dangers of specificity pops up. And technically they’re right: the CSS priority system isn’t an accident. It usually bothers people who don’t master CSS because of the lack of scope, but not because a language doesn’t behave like you’re used to means it’s broken. Nested CSS rules are like !important: they’re handy, but have been so poorly used for years that we now see it as something to avoid. Specificity should be used proactively, not reactively. They should be design decisions, not a quick fix for when your styles don’t apply. Harry Roberts explains it well in CSS Guidelines: “the problem with specificity isn’t necessarily that it’s high or low; it’s the fact it is so variant and that it cannot be opted out of: the only way to deal with it is to get progressively more specific”. Specificity is a powerful tool, but it needs to be used with the uppermost caution and a good long-term vision of the project. Use them wrong, and you’ll feel the pain of having to go back. Keeping specificity low avoids problems altogether: it relies solely on source order, which is a lot easier to manage. With atomic CSS, if a style doesn’t apply, fixing it is as simple as adding or removing a class on an HTML node. You don’t have to call your stylesheet’s structure into question, which is a lot easier and safer to manage. .color-navy { color: navy; } .color-red { color: red; } <div class="color-red color-navy"> <p>- Whose motorcycle is this?</p> <p>- It's a chopper baby.</p> <p>- Whose chopper is this?</p> <p>- It's Zed's.</p> <p>- Who's Zed?</p> <p>- Zed's dead baby, Zed's dead.</p> </div> Want the text to be navy? No need to touch the CSS. Simply remove the .color-red class from the encompassing <div>. If you need one of the children to be red, then move the .color-red on it. “If a feature is sometimes dangerous, and there is a better option, then always use the better option.” — Douglas Crockford Using specificity or not isn’t about showing how well you master CSS and how you, unlike others, can keep it under control. It’s about understanding the advantages and flaws of the features at your disposal, and making choices in the best interest of the project. “You end up with plenty of unused CSS” Let’s say you’re using Sass maps to generate your utility classes. Colors, font sizes, backgrounds, everything is automatically compiled into proper, ready-to-use CSS. Problem is, if you don’t use everything, you’re left with useless extra bytes in production. This can easily be fixed with UnCSS. UnCSS is great at dusting off your stylesheets, but it comes with two caveats: it only works on HTML files (so, no PHP and no template files) and it only takes into account the JavaScript that’s executed on page load (not classes added on user interactions, for example). If you’re using a language like PHP to render your pages, you can add a job in your deployment workflow that compiles pages into temporary HTML and runs UnCSS on them. For the second issue, you can use the ignore option to list out that are classes added on user interaction. Now it’s also important to ponder this issue. The cost of unused classes is heavier stylesheets (longer to download) and longer parse time. If you have a lot, and by that I mean a large percentage of your total styles, of unused classes, this can hurt performances. If you only have a few here and there, the impact will be negligible. Maintaining your CSS codebase is your job as a developer. No matter what methodology you go with, you have to keep an eye on the project and make sure to remove dead code when things change. Being careless with that is how you end up with plenty of unused classes, not because you’re generating some of them. Need a text color class only for the main color? Make a class for this one only. Need backgrounds for most colors in the theme, yet unsure you’ll use them all right away? Generate the damn classes. They’ll be ready when you need them, you won’t have to maintain them when you add new colors, and the extra code will cost nothing. This is not where your app’s bottlenecks are. If you’re having performances issues, there are a million other things to consider before even looking into your CSS. “It makes it hard to know what’s available to use” When your CSS codebase is a large collection of small utility classes, reading the source code won’t help you get a good overview of the available styles. But is it the role of the source code anyway? It certainly isn’t. That’s what style guides are for. Exploring source code is far from being enough to get a good understanding of how a full API is designed. This isn’t limited to atomic CSS: OOCSS or BEM projects, even small ones, can reach a level of sophistication which requires at least a README. Can you imagine having to crawl back in an unminifed version of the master Bootstrap stylesheet every time you don’t remember if this is .col-md-offset-6 or .col-offset-md-6? Would anyone new to Bootstrap understand what such a class means without a little literature on how the grid works? Documentation, style guides, and API references are designed to help us make sense of complex systems. Sure, it doesn’t mean documentation should justify poor design and unclear naming conventions, but thinking you should be able to understand an entire project only by reading the source code is pure fantasy. There are plenty of tools out there to help you generate documentation right from your code. I use KSS for most of my projects, but CSS-Tricks shares a list of alternatives. Give it a try! “Utility classes should be used along with components” Yes. Absolutely. That’s precisely why it’s called utility-first and not utility-only. Utility-first isn’t about ditching components altogether. It means you should start off with utility classes, make the most of them, and only abstract when you see repeating patterns. You’re allowing your project to grow while remaining flexible, and identify actual components over time, when patterns start to emerge. It is crucial to understand that a component isn’t just a similar-looking “block” that you can reuse. It’s a pattern that is strongly tied to your specific project. Sure, you’re probably going to use tons of .btn and .modal, so it makes sense to abstract them early on. But are you positive you’re going to ever reuse .testimonial? Or at least reuse it enough to make it worth being a new component? Will it always look like this in every context, or is it specific to the homepage? Keep your options open. It’s a lot easier to later abstract a composite style into a component than to try and undo one. “It makes redesigning/theming a nightmare” Because atomic CSS is strongly tied to your design, this can make things more difficult when you have to do a redesign or develop an alternate theme. It’s far from impossible though, and there are a few things you can do to make your utility-first CSS more suited to facing these kinds of needs. You can start by keeping class names not too specific: instead of .margin-bottom-8, you can use a more abstract name like .margin-bottom-xxs. This way you can change the value without making the names invalid. Another approach would be to create aliases. Imagine you’re building an app that has light and dark mode: some colors would change, some others wouldn’t. We don’t want to make all our color utilities contextual: .background-primary and .background-secondary don’t tell us what color is behind the class. You don’t want an entire color system like that. Yet, you could still have color utilities with proper color names (.background-lime or .background-red), and also generate aliases for those which might need to change for theming purposes. /* Backgrounds */ .background-lime { background: #cdf2b0; } .background-off-white, .background-light { background: #ebefe8; } .background-dark-grey, .background-dark { background: #494a4f; } /* Colors */ .color-lime { color: #cdf2b0; } .color-off-white, .color-light { color: #ebefe8; } .color-dark-grey, .color-dark { color: #494a4f; } <div class="background-light"> <h2 class="color-lime">Ezekiel 25:17</h2> <p class="color-dark">The path of the righteous man is beset on all sides by the inequities of the selfish and the tyranny of evil men...</p> </div> From here, all you have to do is write a JavaScript function that toggles all .*-light and .*-dark classes. And for elements that don’t need to change, you can use the original color classes. This method works well, but if you have a lot of classes to switch it may end up hurting performances. DOM manipulations are expensive, you want to reduce them as much as possible if you can. Hopefully, there’s a nifty technique involving CSS variables (thanks to Adam Wathan for coming up with it) which makes everything simpler. :root { --green: #42f49b; --off-white: #ebefe8; --dark-grey: #494a4f; } .theme-dark { --background: var(--dark-grey); --text: var(--off-white); } .theme-light { --background: var(--off-white); --text: var(--dark-grey); } .color-lime { color: var(--green); } .color-theme { color: var(--text); } .background-theme { background: var(--background); } <div class="theme-light"> <div class="background-theme"> <h2 class="color-lime">Ezekiel 25:17</h2> <p class="color-theme">The path of the righteous man is beset on all sides by the inequities of the selfish and the tyranny of evil men...</p> </div> </div> We defined colors with CSS variables and assigned different values for each context. Depending on the encompassing class, all colors will change thanks to ancestor inheritance. If you were to allow theme switching, all you’d have to do is change .theme-light into .theme-dark on the parent <div>, and all colors would adapt. This technique only works if you don’t have to support Internet Explorer and Edge below version 15. Otherwise, go for the first technique and use CSS ancestor inheritance system to avoid having to toggle too many variables. If you have to assign a text color to an entire block, set it on the parent instead of the children. /* Nope */ <div class="background-light"> <h2 class="color-lime">Ezekiel 25:17</h2> <p class="color-dark">The path of the righteous man is beset on all sides by the inequities of the selfish and the tyranny of evil men.</p> <p class="color-dark">Blessed is he, who in the name of charity and good will, shepherds the weak through the valley of darkness, for he is truly his brother's keeper and the finder of lost children.</p> <p class="color-dark">And I will strike down upon thee with great vengeance and furious anger those who would attempt to poison and destroy my brothers.</p> <p class="color-dark">And you will know my name is the Lord when I lay my vengeance upon thee.</p> </div> /* Yes */ <div class="background-light color-dark"> <h2 class="color-lime">Ezekiel 25:17</h2> <p>The path of the righteous man is beset on all sides by the inequities of the selfish and the tyranny of evil men.</p> <p>Blessed is he, who in the name of charity and good will, shepherds the weak through the valley of darkness, for he is truly his brother's keeper and the finder of lost children.</p> <p>And I will strike down upon thee with great vengeance and furious anger those who would attempt to poison and destroy my brothers.</p> <p>And you will know my name is the Lord when I lay my vengeance upon thee.</p> </div> Embracing change, within reason Having strong opinions is great. Not everything has to be settled by finding a middle ground. But there’s a clear line to draw between being opinionated and being reluctant to change. We, as developers, must be the first to embrace change. Looking back at my first reaction towards utility-first CSS, I realize how important it is we keep an open mind instead of rushing to pick a side. It doesn’t matter how experienced we think we are. Experience is great, but it can also make us believe we already have all we need to make judgment calls and don’t need to dive deeper to understand new concepts. Software development changes every day. Our industry is still young, and we’re figuring things out as we go. It doesn’t mean we should throw away the past, and continuously refactor all our projects to keep up with the latest trends. Past knowledge is the foundation of today’s discoveries, and it’s important we approach novelty with critical thinking. Yet, not because something is tried and true means it’s set in stone. We’ll probably move on from utility-first CSS at some point, like we got past many things we used to consider the pinnacle of front-end development. In the meantime, let’s try to stay as open-minded as possible, and do what’s best for the industry, the projects, and the users. Want to learn more about utility-first CSS and how to use it in your projects? Go read On the Growing Popularity of Atomic CSS on CSS Tricks and CSS Utility Classes and “Separation of Concerns” on Adam Wathan’s blog. You can also check out utility-first libraries on this curated list by CSS Tricks.

Build Your First Vue.js Component

I remember when I picked up CakePHP back in the days, I loved how easy it was to get started with. Not only were the docs well-structured and exhaustive, but they were also user-friendly. Years later, this is exactly what I found with Vue.js. Yet there’s one thing the Vue docs are still short of compared to Cake: a real-life project tutorial. No matter how well-documented a framework is, this isn’t enough for everyone. Reading about concepts doesn’t always help seeing the bigger picture or understand how you can use them to actually make something. If you’re like me, you learn better by doing and you refer to the docs while you code, as you need them. In this tutorial, we’ll build a star rating system component. We’ll visit several Vue.js concepts when we need them and we’ll cover why we’re using them. TL;DR: this post goes in-depth in the how and why. It’s designed to help you grasp some core concepts of Vue.js and teach you how to make design decisions for your future projects. If you want to understand the whole thought process, read on. Otherwise you can look at the final code on CodeSandbox. Getting started Vue.js (rightfully) prides itself on being runnable as a simple script include, but things are a bit different when you want to use single-file components. Now you don’t have to build components this way. You can perfectly get away with defining a global component with Vue.component. Problem is, this comes with tradeoffs like having to use string templates, no scoped CSS support, and no build step (so, no preprocessors). Yet, we want to go deeper and learn how to build an actual component that you could use in a real project. For those reasons, we’ll go with an actual real-life setup, powered by Webpack. To keep things simple and reduce configuration time, we’ll use vue-cli and the webpack-simple Vue.js template. First, you need to install vue-cli globally. Fire up your terminal and type the following: npm install -g vue-cli You can now generate ready-to-use Vue.js boilerplates in a few keystrokes. Go ahead and type: vue init webpack-simple path/to/my-project You’ll be asked a few questions. Choose defaults for all except “Use sass” to which you should answer yes (y). Then, vue-cli will initialize the project and create the package.json file. When it’s done you can navigate to the project’s directory, install dependencies and run the project: cd path/to/my-project npm install npm run dev That’s it! Webpack will start serving your project on port 8080 (if available) and fire it in your browser. If all went well, you should see a welcome page like this one. Are we there yet? Almost! To properly debug your Vue.js component, you need the right tools. Go ahead and install the Vue.js devtools browser extension (Firefox/Chrome/Safari). Your first component One of the best Vue.js features are single-file components (SFCs). They let you define the structure, style, and behavior of a component in one file, without the usual drawbacks of mixing HTML, CSS, and JavaScript. SFCs end with a .vue extension and have the following structure: <template> <!-- Your HTML goes here --> </template> <script> /* Your JS goes here */ </script> <style> /* Your CSS goes here */ </style> Let’s go and make our first component: create a Rating.vue file in /src/components, and copy/paste the code snippet above. Then, open /src/main.js and adapt the existing code: import Vue from 'vue' import Rating from './components/Rating' new Vue({ el: '#app', template: '<Rating/>', components: { Rating } }) Finally, add a little bit of HTML to your Rating.vue: <template> <ul> <li>One</li> <li>Two</li> <li>Three</li> </ul> </template> Now look at the page in your browser, and you should see the list! Vue.js attached your <Rating> component to the #app element in index.html. If you inspect the HTML, you should see no sign of the #app element: Vue.js replaced it with the component. Sidenote: have you noticed you didn’t even need to reload the page? That’s because Webpack’s vue-loader comes with a hot reload feature. Contrary to live reloading or browser syncing, hot reloading doesn’t refresh the page every time you change a file. Instead, it watches for component changes and only refreshes them, keeping state untouched. Now we’ve spent some time setting things up, but it’s time we actually write meaningful code. The template We’re going to use vue-awesome, an SVG icon component for Vue.js built with Font Awesome icons. This allows us to only load the icons we need. Go ahead and install it with npm (or Yarn): npm install vue-awesome Then edit your component like the following: <template> <div> <ul> <li><icon name="star"/></li> <li><icon name="star"/></li> <li><icon name="star"/></li> <li><icon name="star-o"/></li> <li><icon name="star-o"/></li> </ul> <span>3 of 5</span> </div> </template> <script> import 'vue-awesome/icons/star' import 'vue-awesome/icons/star-o' import Icon from 'vue-awesome/components/Icon' export default { components: { Icon } } </script> Alright alright, let’s slow down for a moment and explain all that 😅 Vue.js uses native ES6 modules to handle dependencies and export components. The first two lines in the <script> block import icons individually, so you don’t end up with icons you don’t need in your final bundle. The third one imports the Icon component from vue-awesome so you can use it in yours. Icon is a Vue.js SFC, like the one we’re building. If you open the file you’ll see it has the exact same structure as ours. The export default block exports an object literal as our component’s view model. We registered the Icon component in the components property so we can use it locally in ours. Finally, we used the Icon in our HTML <template> and passed it a name property to define what icon we want. Components can be used as custom HTML tags by converting them to kebab-case (eg.: MyComponent becomes <my-component>). We don’t need to nest anything inside of the component, so we used a self-closing tag. Sidenote: have you noticed we added a wrapping <div> around the HTML? That’s because we also added a counter in a <span> at root level, and component templates in Vue.js only accept one root element. If you don’t respect that, you’ll get a compilation error. The style If you’ve worked with CSS for some time, you know one of the main challenges is having to deal with its global nature. Nesting has long been considered the solution to this problem. Now we know it can quickly lead to specificity issues, making styles hard to override, impossible to reuse, and a nightmare to scale. Methodologies like BEM were invented to circumvent this issue and keep low specificity, by namespacing classes. For a while, it’s been the ideal way to write clean and scalable CSS. Then, frameworks and libraries like Vue.js or React came along and brought scoped styling to the table. React has styled components, Vue.js has component-scoped CSS. It lets you write component-specific CSS without having to come up with tricks to keep it contained. You write regular CSS with “normal” class names, and Vue.js handles scoping by assigning data-attributes to HTML elements and appending it to the compiled styles. Let’s add some simple classes on the component: <template> <div class="rating"> <ul class="list"> <li class="star active"><icon name="star"/></li> <li class="star active"><icon name="star"/></li> <li class="star active"><icon name="star"/></li> <li class="star"><icon name="star-o"/></li> <li class="star"><icon name="star-o"/></li> </ul> <span>3 of 5</span> </div> </template> And style it: <style scoped> .rating { font-family: 'Avenir', Helvetica, Arial, sans-serif; font-size: 14px; color: #a7a8a8; } .list { margin: 0 0 5px 0; padding: 0; list-style-type: none; } .list:hover .star { color: #f3d23e; } .star { display: inline-block; cursor: pointer; } .star:hover ~ .star:not(.active) { color: inherit; } .active { color: #f3d23e; } </style> See that scoped attribute up there? That’s what tells Vue.js to scope the styles, so they won’t leak anywhere else. If you copy/paste the HTML code right in the index.html, you’ll notice your styles won’t apply: that’s because they’re scoped to the component! 🎉 What about preprocessors? Vue.js makes it a breeze to switch from plain CSS to your favorite preprocessor. All you need is the right Webpack loader and a simple attribute on the <style> block. We said “yes” to “Use sass” when generating the project, so vue-cli already installed and configured sass-loader for us. Now, all we need to do is add lang="scss" to the opening <style> tag. We can now use Sass to write component-level styles, import partials like variables, color definitions or mixins, etc. If you prefer the indented syntax (or “sass” notation), simply switch scss to sass in the lang attribute. The behavior Now that our component looks good, it’s time to make it work. Currently, we have a hardcoded template. Let’s set up some initial mock state and adjust the template so it reflects it: <script> ... export default { components: { Icon }, data() { return { stars: 3, maxStars: 5 } } } </script> <template> <div class="rating"> <ul class="list"> <li v-for="star in maxStars" :class="{ 'active': star <= stars }" class="star"> <icon :name="star <= stars ? 'star' : 'star-o'"/> </li> </ul> <span>3 of 5</span> </div> </template> What we did here is use Vue’s data to setup component state. Every property you define in data becomes reactive: if it changes, it will be reflected in the view. We’re making a reusable component, so data needs to be a factory function instead of an object literal. This way we’re getting a fresh object instead of a reference to an existing one that would be shared across several components. Our data factory returns two properties: stars, the current number of “active” stars, and maxStars, the total amount of stars for the component. From these, we adapted our template so it reflects the actual component’s state. Vue.js comes with a bunch of directives that let you add presentation logic to your template without mixing it with plain JavaScript. The v-for directive loops over any iterable object (arrays, objects literals, maps, etc.). It also can take a number as a range to be repeated x number of times. That’s what we did with v-for="star in maxStars", so we have an <li> for each star in the component. You may have noticed some properties are prefixed with a colon: this is a shorthand for the v-bind directive, which dynamically binds attributes to an expression. We could have written it in its long form, v-bind:class. We need to append the active class on <li> elements when the star is active. In our case, this means every <li> which index is less than stars should have the active class. We used an expression in the :class directive to only append active when the current star is less than stars. We used the same condition, this time with a ternary operator, to define what icon to use with the Icon component: star or star-o. What about the counter? Now that our star list is bound to actual data, it’s time we do the same for the counter. The simplest way to do this is to use text interpolation with the mustache syntax: <span>{{ stars }} of {{ maxStars }}</span> Pretty straight-forward, isn’t it? Now in our case, this does the trick but if we needed a more complex JavaScript expression, it would be better to abstract it in a computed property. export default { ... computed: { counter() { return `${this.stars} of ${this.maxStars}` } } } <span>{{ counter }}</span> Here this is overkill. We can get away with in-template expressions and still keep things readable. Yet, keep computed properties in mind for when you have to deal with more convoluted logic. Another thing we need to do is provide a way to hide the counter if we don’t want it. The simplest way to do this is to use the v-if directive with a boolean. <span v-if="hasCounter">{{ stars }} of {{ maxStars }}</span> export default { ... data() { return { stars: 3, maxStars: 5, hasCounter: true } } } Interactivity We’re almost done but we still have to implement the most interesting part of our component: reactivity. We’re going to use v-on, the Vue.js directive that handles events, and methods, a Vue.js property on which you can attach all your methods. <template> ... <li @click="rate(star)" ...> ... </template> export default { ... methods: { rate(star) { // do stuff } } } We added a @click attribute on the <li>, which is a shorthand for v-on:click. This directive contains a call to the rate method which we defined in the methods property of the component. “Wait a minute… this looks awfully familiar with HTML’s onclick attribute. Isn’t it supposed to be an outdated and bad practice to use inline JavaScript in HTML?” It is indeed, but even though the syntax looks a lot like onclick, comparing the two would be a mistake. When you’re building a Vue.js component, you shouldn’t think of it as separated HTML/CSS/JS, but rather as one component that uses several languages. When the project is served in the browser or compiled for production, all the HTML and directives are compiled into plain JavaScript. If you inspect the rendered HTML, you won’t see any sign of your directives, nor any onclick attributes. Vue.js compiled your component and created proper bindings. This is also why you have access to the context of the component right from your template: because directives are bound to the view model. Contrary to a traditional project with separate HTML, the template is an integral part of the component. Back to our rate method. We need to mutate stars to the index of the clicked element, so we pass the index from the @click directive, and we can do the following: export default { ... methods: { rate(star) { this.stars = star } } } Go check the page in your browser and try clicking on stars: it works! If you open the Vue panel in your browser devtools and select the <Rating> component, you’ll see the data change as you click on stars. This shows you that your stars property is reactive: as you mutate it, it dispatches its changes to the view. That concept is called data-binding, which you should be familiar with if you ever used frameworks like Backbone.js or Knockout. The difference is that Vue.js, like React, does it in one direction only: this is called one-way data-binding. But that topic deserves an article of its own 😊 At this point, we could call it done but there’s a bit more work we could do to improve user experience. Right now, we can’t actually give a grade of zero, because clicking on a star sets the rate to its index. What would be better is to re-click on the same star and have it toggle its current state instead of staying active. export default { ... methods: { rate(star) { this.stars = this.stars === star ? star - 1 : star } } } Now if the clicked star’s index is equal to the current value of stars, we decrement its value. Otherwise, we assign it the value of star. If we want to be thorough, we should also add a layer of controls to make sure stars is never assigned a value that doesn’t make sense. We need to make sure stars is never less than 0, never greater than maxStars, and that it’s a proper number. export default { ... methods: { rate(star) { if (typeof star === 'number' && star <= this.maxStars && star >= 0) { this.stars = this.stars === star ? star - 1 : star } } } } Passing props Right now, the component’s data is hardcoded in the data property. If we want our component to actually be usable, we need to be able to pass custom data to it from its instances. In Vue.js, we do that with props. export default { props: ['grade', 'maxStars', 'hasCounter'], data() { return { stars: this.grade } }, ... } And in main.js: new Vue({ el: '#app', template: '<Rating :grade="3" :maxStars="5" :hasCounter="true"/>', components: { Rating } }) There are three things to observe here: First, we used the v-bind shorthand to pass props from the component instance: this is what Vue.js calls the dynamic syntax. You don’t need it when you want to pass a string value, for which the literal syntax (normal attribute without v-bind) will work. But in our case, since we’re passing numbers and booleans, it’s important we do. The props and data properties are merged at compile time, so we don’t need to change the way we call properties either in the view model or in the template. But for that same reason, we can’t use the same names for props and data properties. Finally, we defined a grade prop and passed it as a value to stars in the data property. The reason why we did that instead of using the grade prop directly is that the value will be mutated when we change the grade. In Vue.js, props are passed from parents to children, not the other way around, so you don’t accidentally mutate the parent’s state. This would go against the one-way data flow principle and make things harder to debug. This is why you should not try to mutate a prop inside of a child component. Instead, define a local data property that uses the prop’s initial value as its own. Final touches Before we call it a day, there’s one last piece of Vue.js goodness we should visit: prop validation. Vue.js lets you control props before they’re passed to the component. You can perform four major things: check type, require a prop to be defined, setup default values, and perform custom validation. export default { props: { grade: { type: Number, required: true }, maxStars: { type: Number, default: 5 }, hasCounter: { type: Boolean, default: true } }, ... } We used type checking to make sure the right type of data is passed to the component. This will be especially useful if we forget to use the dynamic syntax to pass non-string values. We also made sure the grade prop was passed by requiring it. For other props, we defined default values so the component works even if no custom data is passed. Now we can instantiate the component simply by doing the following: <Rating :grade="3"/> And that’s it! You just created your first Vue.js component, and explored many concepts including generating a boilerplate projet with vue-cli, single-file components, importing components in components, scoped styling, directives, event handlers, computed properties, custom methods, one-way data flow, props and prop validation. And that’s only scratching the surface of what Vue.js has to offer! This is a pretty dense tutorial, so don’t worry if you didn’t understand everything. Read it again, pause between sections, explore and fiddle with the code on CodeSandbox. And if you have any question or remark about the tutorial, don’t hesitate to hit me up on Twitter!

Generate All Your Utility Classes with Sass Maps

One of the powers of utility classes lies in giving you access to every small concept of your design system, in a slew of contexts. If your main color is royal blue, you can apply it as a text color on anything with a .text-royal-blue class, as a background color with a .bg-royal-blue class, etc. But how do you write them in an effective, consistent and scalable way? TL;DR: this post goes in-depth in the how-to stuff. If you want to understand the whole thought process, read on. Otherwise you can grab the code on GitHub or test it out on SassMeister. $royal-blue: #0007ff; .text-royal-blue { color: $royal-blue; } .bg-royal-blue { background: $royal-blue; } ... That’s repetitive. Not only you’re hand typing the color name and value every single time, but you’re also creating an unmaintainable system. What happens when you have ten color utilities like these ones, and you need to add one more color to the scheme? You shouldn’t spend time on mindless, tedious tasks. That’s what scripting languages are for. If you’re already using Sass, you need to harness its power and let it help you. Sass Maps? Maps are a Sass data type that represents an association between keys and values. If you’re familiar with other scripting languages you could see it as an associative array. It allows you to store data, and have a name to reference each piece. Lists and maps are a bit similar, in that they’re both storing a collection of data and they’re both iterable in an @each loop. But contrary to lists, maps make it easy to reference any piece of information by calling it by its name. This makes it ideal for grouping logically related information. $colors: ( mako-grey: #404145, fuel-yellow: #ecaf2d, pastel-green: #5ad864 ); Let’s add some logic Now that our colors are neatly stored inside a map, we need to iterate it to generate our utility classes. To do that, we’ll use the @each directive inside a @mixin, that we’ll include later in our utility base class. @mixin color-modifiers { // do stuff } Let’s now use the @each directive to loop through $colors and fetch the right data. @mixin color-modifiers { @each $name, $hex in $colors { // do stuff } } We’re iterating $colors and at every loop, the current key will be referenced in $name and the color’s hexadecimal code will be in $hex. We can start building our ruleset. @mixin color-modifiers { @each $name, $hex in $colors { &-#{$name} { color: $hex; } } } Now for every pair in the map, @each will generate a ruleset that references the parent selector with the & character, appends a hyphen and the color’s name, and sets the color attribute to the current hexadecimal value. In other words, doing this: .text { @include color-modifiers; } Will generate this: .text-mako-grey { color: #404145; } .text-fuel-yellow { color: #ecaf2d; } .text-pastel-green { color: #5ad864; } Pretty neat, uh? Actually, we barely scratched the surface. For now, our mixin can only output rules with the color attribute. What if we want to create some utility classes for background colors? Fortunately, Sass allows us to pass arguments to mixins. @mixin color-modifiers($attribute: 'color') { @each $name, $hex in $colors { &-#{$name} { #{$attribute}: $hex; } } } Now we can specify exactly what attribute we want. Let’s improve our mixin a little more: right now the modifier prefix is a hardcoded hyphen. This means your classes will always be in the form of .base-modifier. What if you need it to change? What if you also want to generate some BEM-flavored modifiers (two hyphens)? Again, that’s something we can achieve by using arguments. @mixin color-modifiers($attribute: 'color', $prefix: '-') { @each $name, $hex in $colors { &#{$prefix}#{$name} { #{$attribute}: $hex; } } } Now we can generate modifier classes with any kind of prefix we want. So, doing this: .text { @include color-modifiers($prefix: '--'); } Will generate this: .text--mako-grey { color: #404145; } .text--fuel-yellow { color: #ecaf2d; } .text--pastel-green { color: #5ad864; } Pro tip: in Sass, you can explicitly name arguments when you call a mixin or a function (like in the example above). This avoids having to provide them in order. Maps within maps I like to use a slightly different color system so I can manage tonal variations. By nesting maps within maps, I have a clean and readable way to keep shades grouped together. $colors: ( grey: ( base: #404145, light: #c7c7cd ), yellow: ( base: #ecaf2d ), green: ( base: #5ad864 ) ); If we want to work with such a color system, we need to adapt our mixin so it goes iterating a level deeper. @mixin color-modifiers($attribute: 'color', $prefix: '-', $separator: '-') { @each $name, $color in $colors { &#{$prefix}#{$name} { @each $tone, $hex in $color { &#{$separator}#{$tone} { #{$attribute}: $hex; } } } } } We added a new argument, $separator, to link the color’s name and the tone. We could have used the $prefix but it doesn’t have the same purpose. Using a dedicated variable with a default value is a better choice, as it gives us full freedom when we use the mixin. Now, doing this: .text { @include color-modifiers; } Will generate this: .text-grey-base { color: #404145; } .text-grey-light { color: #c7c7cd; } .text-yellow-base { color: #ecaf2d; } .text-green-base { color: #5ad864; } Great! We now have helpers composed of a base class, a color, and a tone. One thing we need to improve though is how base color modifiers are outputted. We actually don’t need that -base suffix, the base class and color are enough. What we must do is check for the tone in the nested @each loop, and only output it and the $separator when it’s not “base”. Luckily for us, Sass already has everything we need. @if, @else, if() Our first instinct might be to use the @if/@else directives. Problem is, this would force us to repeat code and result in complicated code. Instead, we’re going to use one of Sass’ secret weapons: if(). if() is Sass’ conditional (ternary) operator. It takes three arguments: a condition and two return statements. If the condition is met, if() will return the first statement. Otherwise, it will return the second one. You can see it as an @if/@else shorthand. @mixin color-modifiers($attribute: 'color', $prefix: '-', $separator: '-', $base: 'base') { @each $name, $color in $colors { &#{$prefix}#{$name} { @each $tone, $hex in $color { &#{if($tone != $base, #{$separator}#{$tone}, '')} { #{$attribute}: $hex; } } } } } Every time the nested @each loop will parse a $tone that’s different from “base”, it will return the $separator and the $tone as the class suffix. Else, it will return nothing, leaving the class as is. .text-grey { color: #404145; } .text-grey-light { color: #c7c7cd; } .text-yellow { color: #ecaf2d; } .text-green { color: #5ad864; } DRY-ing it all up In a real-world project, chances are you’ll want to use various map structures. For example, you could have one-level deep maps for font sizes and two-levels deep maps for colors. You’re not going to write a different mixin for each depth level. That would be repetitive and unmaintainable. You need to be able to rely a single mixin to handle that. We want a generic mixin to generate all modifiers, and that’s able to handle multidimensional maps. If you compare the two mixins we came up with in this tutorial, you’ll notice they look a lot alike. The only difference is that one performs an extra loop before printing the computed CSS declaration. This is a typical job for a recursive mixin. It will begin with an @each directive where we can start building our selector. This is where we’ll check if the current $key equals to “base” so we can decide to output it or not. Then, we’ll check if the current $value is a map itself: if yes, we need to run the mixin again from where we are and pass it the nested map. Otherwise, we can print the CSS declaration. @mixin modifiers($map, $attribute, $prefix: '-', $separator: '-', $base: 'base') { @each $key, $value in $map { &#{if($key != $base, #{$prefix}#{$key}, '')} { @if type-of($value) == 'map' { @include modifiers($value, $attribute, $separator); } @else { #{$attribute}: $value; } } } } And voilà! This mixin will work with maps of any depth. Feel free to use it in your own projects! If you like it, you can show some love by starring it on GitHub. Also, if you want to improve it, please leave a comment on the gist so I can update it 👍

Write More Understandable Code With Hungarian Notation

It happens all the time: you start a new project and everything goes smoothly. You have firm control of your codebase and productivity is on point. Then another project comes along, and before you know it six months have passed before you come back to that older project. Suddenly it’s not that clear anymore. What does this class do? What’s the type of this variable? Worse: now your colleagues have to build upon your work and you have a hard time giving them clear explanations. This is a common problem in software engineering. We humans have great minds but terrible memory. As Scott Berkun puts it, “we have such bad memory that we forget we have bad memory”. Our brain constantly switches from one thing to another, and unless we have something, some trigger to get back on track, it requires a significant amount of work to get all pieces together again. That trigger is called context, and fortunately for us, there’s a great way to implement it in our codebase. Hungarian notation is a naming convention that consists of prefixing to indicate either type (systems) or use (apps). This may sound like an obscure and barbaric term for such a simple concept, but you’ve probably seen it before without even knowing. In this article, we’ll cover Hungarian notation in JavaScript and CSS. Hungarian notation in JavaScript const $text = $('.text'); The above naming convention is pretty widespread when using jQuery. Prefixing variables that store a jQuery object with a $ makes it easier to know what it is a few dozen lines later. This is an example of type prefixing: the $ tells us our variable is a jQuery object. This does absolutely nothing to our variable though: it behaves the exact same way as any other. Also, prefixing doesn’t type a variable: you could have stored an integer there and it would work the same. Hungarian notation is by humans, for humans. If you do it wrong, your browser/compiler won’t insult you (but your coworkers might 😆). const _isPublished = true; Here’s another well known prefixing convention in JavaScript, this time to indicate a variable is private. This is an example of use prefixing: the _ tells us our variable is meant to be private. Again, prefixing a variable this way absolutely doesn’t make it private. You can achieve privacy via several patterns in JavaScript, but the language itself doesn’t natively support that concept. Don’t go thinking that prefixing a variable makes it “safe”. If you need privacy, make sure you build your code that way. If anything, the _ prefix is here to tell you a resource was meant to be private, therefore probably can’t be invoked directly, and even if it does, shouldn’t because it might change or disappear. A step further In this JavaScript implementation of the Luhn algorithm, the author used a more traditional version of the Hungarian notation: type prefixing with the type’s first letter. // Original code by DiegoSalazar gist.github.com/DiegoSalazar/4075533 // Cropped for brevity ... var nCheck = 0, nDigit = 0, bEven = false; value = value.replace(/\D/g, ""); for (var n = value.length - 1; n >= 0; n--) { var cDigit = value.charAt(n), nDigit = parseInt(cDigit, 10); if (bEven) { if ((nDigit *= 2) > 9) nDigit -= 9; } nCheck += nDigit; bEven = !bEven; } return (nCheck % 10) == 0; ... If you’re not used to it, this may look odd. Past that first impression, it becomes a lot clearer to spot which variable is a boolean, which one is a number and which one is a string (even if our JavaScript programmer here decided to go with c, presumably for char). Hungarian notation is considered helpful for loosely and dynamically typed languages like JavaScript, that also doesn’t benefit from type hinting. Ask a developer to improve this algorithm, all the type prefixes would certainly save them some time. Do I need to prefix all my variables? My personal opinion is no. Most of the time you can get away with a properly named variable, or short functions and methods (which you should strive for anyway). Clean code starts with expressive variables, and your job is to make sure these names are enough. I still believe Hungarian notation is interesting for use prefixing (apps). Intended use isn’t necessarily something you can find out from a variable name or by looking around in the code. Type prefixing (systems) remains helpful for complex algorithms, other than that don’t overdo it. Hungarian notation in CSS There are many ways to keep your CSS under control these days. Methodologies like OOCSS, BEM or atomic CSS are great at abstracting rules into expressive and modular components. Besides that, architectures like SMACSS or ITCSS do an amazing job at structuring the building blocks of your CSS codebase. Problem is, while CSS class names can tell you what kind of component they are, the role they play in the architecture of your project is a lot harder to define when you’re reading the HTML. <div class="card shadow media"> ... </div> In this example, the responsibility of each class is unclear. If you’re not familiar with this codebase, it could be nerve-wracking and time-consuming to find out what to remove to disable a specific style, and what you can safely edit without breaking something somewhere else. Namespaces, namespaces everywhere I’m a big fan of Harry Robert’s (yet unpublished) ITCSS architecture. In ITCSS, you chunk the CSS codebase into logical layers. The three final ones is where we define actual classes: objects, components, and utilities. Objects are abstract, undecorated, structural elements. They usually can be reused from a project to another, and are used to build actual styles upon. You may need to add modifiers, but an object usually is immutable. A .media-element class that puts an image and a text box side by side and make them use 100% of the width, or a .list that removes bullets and left padding, are good examples of objects. Components are concrete, specific UI elements that define the look and feel of your design. Some components are independent, while others may rely on objects. A .button is a great example of a component. Utilities are small rulesets that help you either build a larger component (that’s especially true if you’re using an atomic CSS approach) or override styles from higher layers. Utilities usually don’t have abstract names like objects or components, but are rather named after their function. .hidden or .text-center are typical utilities. Let’s use Hungarian notation on our classes: objects will start with o-, components with c- and utilities with u-. From there, this is how our HTML would look like: <div class="c-card u-shadow o-media"> ... </div> That’s much easier to read. Now we know at a glance what each class is responsible for. If you need to change the order in which the image and text content are displayed, you’ll add a modifier to the .o-media object. If the background color has to to change, it will be applied on the .c-card component. Finally, if the box-shadow needs to go, you’ll remove the .u-shadow utility. Harry Roberts dives way deeper into prefixing methods in his own article More Transparent UI Code with Namespaces. I strongly encourage you to read it (and everything Harry wrote) if you’re serious about building robust CSS architectures. There are some pretty interesting prefixes in there, such as js- to safely define all JavaScript hooks with no risk of breaking stuff if you remove a class, or qa- for automated functional testing with web drivers like Selenium. Do I need to prefix all my classes? Contrary to JavaScript, I would recommend prefixing all your CSS classes. While JavaScript is contained to its own codebase, CSS classes live outside of their stylesheets, right on HTML tags, where you lose all context. Use prefixing doesn’t only give you back that lost context, it also enforces the methodology and architecture you picked by making it more visible and explicit. You have everything to gain by trying it out.

Build a Simple Validator Service in JavaScript

Data validation is a pain. Not only is it hard to do it right, but it can also be difficult to implement without making a mess. When trying to validate data before saving it, it’s easy to pollute methods and violate many programming best practices. For all those reasons, a much better way would be to handle validation via a validator service. In programming, a service is a unit that externalizes business logic from entities. Using services is a great way to keep a clean codebase by breaking down responsibilities. A validator service will allow us to avoid having to explicitly validate data ourselves in our methods. Instead, we’ll create a reusable unit we can rely on to build the foundations of our program. The world before using a validator service Let’s say we’re building a simple model. Until now, when we wanted to validate data before setting it, our model’s setter methods looked something like this: var Model = function() { this.name = ''; } Model.prototype.setName = function(name) { if (typeof name === 'string') { this.name = name; } } Meh. I don’t know about you, but I dislike having the entire content of a method wrapped into an if statement. If the whole purpose of my method is conditional, it makes me feel like I skipped a step. Like there’s something I need to take care of beforehand. Plus, do you imagine what we’ll need to do if we have to add rules? Model.prototype.setName = function(name) { if (typeof name === 'string' && name !== '' && ...) { this.name = name; } } Gross. Imagine if we wanted to set several values, like all the properties of a single object, in the same method? I don’t even want to figure out what it would look like. And in fact, there’s much more than one problem to this code structure: It’s hard to read. As seen above, we can quickly end up with many successive or imbricated if statements, bloated with complex validation rules. To change it you’d have to spend time understanding what’s going on, then perform your edit, while making sure you’re not breaking anything. It’s repetitive. Chances are all your setter methods will have one or more if statements that pretty much do the same thing. This goes against the fundamental DRY principle, which states “every piece of knowledge must have a single, unambiguous, authoritative representation within a system”. The goal is for us to keep every change to this knowledge in sync across the entire program. If you have repetitive code to check if a value is not empty, for example by doing value !== '', and then want to reinforce it by adding && value !== null && typeof value !== 'undefined', you’ll have to find every occurrence of your former code and update it. This is tedious, time-consuming, has low added-value, and prone to bugs. It violates SRP. The single responsibility principle states “a class should have only one reason to change”. In the above example, our method does two things: it validates data and it assigns it if the test passes. We could even say it does more than that because it stores validation rules for the model’s name property (making it impossible to use elsewhere without duplicating code). The point is, the method has more than one responsibility, and this makes it more difficult to test, reuse, read and refactor. It couples logic and data. Right now every time we need to change the validation rules for this method, we’ll have to touch the if statement. As a direct consequence of violating SRP, the method couples two things that should be separate: a logic mechanism that should never change, and variable data. If we want to build a clear, solid and scalable program, this is everything we want to avoid. What we want is something with a validation mechanism that’s set once in a generic way so we can reuse it. We also want to store our validation rules separately, somewhere where it makes more sense, and in a way that’s easily editable. Finally, we want validation to be “invisible”: it must be done under the hood and never appear explicitly in our setter methods. Starting with what you want When I’m tackling a new problem and I don’t know where to start, my method of choice is reverse engineering. I start with what I want my final code to be and I backward build to make it work. Here’s how we’d ideally want to setup the model: // Model.js var Model = function() { this.name = { value: null, validator: ['isString', 'isNotEmpty'] }; this.age = { value: null, validator: ['isInt'] }; } This would be perfect. It doesn’t work yet, but this is what we’d want our validator to deal with in the end. Instead of assigning values directly to a variable, we decide every property is an object with at least two sub-properties: its actual value, and an array of its validation rules. This is legible, it has a standard format and we can easily add, change or remove rules. We don’t have to worry about the actual validation system that will handle them. From here, let’s start thinking about how we can build our Validator object. We want to validate data from an array of strings. So, for every rule, we need a dedicated method that uses the exact same name. // Validator.js var Validator = function() {}; Validator.prototype.isString = function(value) { if (typeof value === 'string') { return true; } return false; }; Validator.prototype.isNotEmpty = function(value) { if (value !== '' && value !== null && typeof value !== 'undefined') { return true; } return false; }; Validator.prototype.isInt = function(value) { return Number.isInteger(value); }; Every validation method follows the same model: it takes a value, makes sure it’s valid and returns a boolean. Instead of using messy if statements directly in setter methods, we have a much cleaner way to validate data: var validator = new Validator(); validator.isString('Iggy Pop'); // returns true validator.isInt('10'); // returns false Now, this is nice but we don’t actually want to do it by hand. We want to list out rules in the model and for them to be automatically validated. So for this, we need a method: // Validator.js Validator.prototype.validate = function(value, rules) { var self = this; return rules.every(function(rule) { return self[rule](value); }); }; Don’t freak out, I’ll explain 😁 What we want is for our value to be checked against a set of rules. This could be one rule or a thousand, which is why it’s ideal to have rules listed in an array. If at least one rule doesn’t pass we need to return false, else we’ll return true. Our method takes two arguments: a value to test, and a set of rules as an array. Each rule must be the exact name of the validator’s method that needs to be called, as a string. We’re using the native JavaScript method Array.prototype.every(). As explained on MDN, it “tests whether all elements in the array pass the test implemented by the provided function”. We use it to call every rule one after the other, and we pass it the value we want to test. Since every() needs every (duh!) test to return true to itself return true, we can simply return it. And what about this self[rule](value) weirdness? This line is what’s going to call the appropriate validator method for each rule. Let’s break this down: We defined the self variable two lines prior, and it refers to this in the context of the Validator object. As explained by Douglas Crockford in chapter 4 of JavaScript: The Good Parts, “When a function is not the property of an object, then it is invoked as a function […] When a function is invoked with this pattern, this is bound to the global object. This was a mistake in the design of the language.” When Validator.prototype.validate() is invoked, this refers to Validator but the scope changes within the callback function of every(). Because it’s using the function invocation pattern, using this would refer to window instead of Validator. To circumvent that, we stored the value of this in a variable while we still were in the desired context. Now we can use the variable within the callback and it will refer to the Validator object. rule is the current element being iterated on by every(). It successively refers to each rule in the array. JavaScript treats functions as objects, so we can access function members the exact same way: using either the dot or bracket notation. Here we use the current rule as the key, within brackets, to call the right method. value is the argument being tested. It’s wrapped in parentheses because the member we’re accessing is a function. We’re using an invocation operator to invoke it and we pass value as an argument. At each loop, we iterate over a new rule from the rules array and we use it to call the name-matching function. So with the ['isString', 'isNotEmpty'] array, the loop is calling Validator.prototype.isString() then Validator.prototype.isNotEmpty(), and passing them the value. A step further We have a good, working system. We can use our validator either to test a value with one rule or go with the validate() method for a whole set of rules. var validator = new Validator(); validator.validate(value, key.validator); Remember the checklist we defined earlier as the ideal system we’d want to build? Let’s get back to it and see if we fulfilled the contract. We wanted: ✅ something with a validation mechanism that’s set once in a generic way and can be reused ✅ store our validation rules separately and in a way that’s easily editable validation to be “invisible” in our setter methods We may have a neat way to validate data, but we still need to wrap it inside an if statement to make it work. // Model.js var Model = function() { this.name = { value: null, validator: ['isString', 'isNotEmpty'] }; this.validator = new Validator(); } Model.prototype.setName = function(name) { if (this.validator.validate(name, this.name.validator)) { this.name.value = name; } } It’s much better than before but still not ideal. Sure, if we need to change the validation rules we won’t have to touch that if statement. Yet, we’re still explicitly doing two different things in our method. This means we’ll need to do it in every new setter method, which is repetitive and not as legible as it could be. Let’s try to think about a method that would do it all for us: check if the validation passes, and set the data if it does. We’d only have to pass the value and the object property to assign it to, and it would handle all the heavy lifting for us. // Model.js Model.prototype.set = function(value, key) { if (this.validator.validate(value, key.validator)) { key.value = value; return true; } return false; }; Here we have a dedicated method Model.prototype.set(). It takes two arguments: the value to test and the key to assign it to. The method will call the validator’s validate() method and pass the value and the key’s validator property. If the test passes, the value will be assigned to the key’s value property and return true. Else, it will return false. Now instead of having an if statement in our setName() method, we can simply call the set() method and rely on it to perform the assignment if the tests pass. We can look at it as a “safe” and generic setter method. // Model.js Model.prototype.setName = function(name) { this.set(name, this.name); }; That’s it: every need is met 🎉 The code is clean, it’s a breeze to read, and there’s no sign of explicit validation. By using a service, we have not only automated recurring logic and made it easier to maintain, but we have freed our model from clutter. Unless we have to add new validation methods, there’s no reason for us or any newcomer to even open the validator file. All we have to do is use it. We don’t really have to understand the internals to make it work, but rather rely on it as a black box. This makes the learning curve of the project a lot more gentle. Another great thing is how we created a clean bridge between the generic validator and our specific model with Model.prototype.set(). If we wanted to use the validator with another model, or any other function, but they had a different way of storing validation rules, we could still do it. All we’d have to do is create another bridge. The model’s set() method binds the validator to itself based on how it’s built, but the validator remains generic. We haven’t specialized our validator, and we have a clean, reusable way to validate then set data in the model. Full code // Validator.js var Validator = function() {}; Validator.prototype.validate = function(value, rules) { var self = this; return rules.every(function(rule) { return self[rule](value); }); }; Validator.prototype.isString = function(value) { if (typeof value === 'string') { return true; } return false; }; Validator.prototype.isNotEmpty = function(value) { if (value !== '' && value !== null && typeof value !== 'undefined') { return true; } return false; }; Validator.prototype.isInt = function(value) { return Number.isInteger(value); }; // any other rule you want to add // Model.js var Model = function() { this.name = { value: null, validator: ['isString', 'isNotEmpty'] }; this.age = { value: null, validator: ['isInt'] }; }; Model.prototype.set = function(value, key) { if (this.validator.validate(value, key.validator)) { key.value = value; return true; } return false; }; Model.prototype.setName = function(name) { this.set(name, this.name); }; Model.prototype.setAge = function(age) { this.set(age, this.age); }; References Service-oriented programming on Wikipedia Don’t repeat yourself principle on Wikipedia Single responsibility principle on Wikipedia JavaScript: The Good Parts by Douglas Crockford Array.prototype.every() on MDN

A Better Way to Perform Multiple Comparisons in JavaScript

Having to compare a value with a bunch of other values is a common, even trivial task for a developer. It’s something you probably don’t even think about when you have to do it. Look at the following JavaScript example: var name = 'Kurt'; if (name === 'Jimi' || name === 'Amy' || name === 'Janis') { // do stuff } Nothing fancy here. It works as you expect it to, but somehow it doesn’t feel quite right. Like you could do it better. Like there must be a smarter way. There are several problems in the above condition: It’s repetitive. If you need to change something (new variable name, new operators, etc.), you have to make sure you don’t forget an occurence. This can be even more tedious if your condition is more complex, like (x === a || x === b || x !== c...). It’s long. If you have line length-based coding standards in your project (such as the no more than 80 characters per line rule), you won’t be able to add more conditions to your if statement without either breaking it into several lines (messy and hard to read) or shortening your variable names (a terrible short-term solution, and you may not even have a choice). It’s hard to read. This might be okay with 3 statements like we have up here but the more you add, the more illegible it will get. Native JavaScript alternative When given a problem, it’s always a good idea to look at it from different perspectives. What if, instead of comparing a value to every possibility one by one, we simply tried to check if it exists in a list? var names = ['Jimi', 'Amy', 'Janis', 'Brian', 'Jim', 'Robert', 'Kurt']; if (names.indexOf('Kurt') !== -1) { // do stuff } Instead of repeating our search value/variable, we’re using JavaScript’s native Array.prototype.indexOf() method to see if it exists in an array of values. indexOf() returns the value’s position, so we only have to make sure the result is different from -1 (which is what indexOf() returns if the value isn’t found). This method is a lot clearer, more elegant, legible and DRY. It’s also a lot more convenient. In real-life projects you usually get lists of values from API calls or database requests, which come as an array or can easily be turned into one. It’s much smarter for you to use this method than loop over every value and match it against your string. Imagine you’re building an banking app where the user must input his bank name to make sure it’s supported. The app currently supports 20 banks, but plans on adding more with time. Are you going to create a long and complicated condition and edit it every time you add a new value? Are you going to loop over a collection you got from an API call and return true as soon as you have a match? Hell no. var banks = [ 'JPMorgan Chase', 'Bank of America', 'Wells Fargo', 'Citigroup', 'Goldman Sachs', 'Morgan Stanley', 'U.S. Bancorp', 'PNC Financial Services', ' Capital One', 'TD Bank, N.A.', 'The Bank of New York Mellon', 'Barclays', 'HSBC Bank USA', 'State Street Corporation', 'Charles Schwab Corporation', 'BB&T', 'Credit Suisse', 'SunTrust Banks', 'Deutsche Bank', 'Ally Financial' ]; // or something like // var banks = Api.get('bankList'); if (banks.indexOf(document.getElementById('myBank').value) !== -1) { // do stuff } Here, we keep our list separate in a variable (either hard-coded or from a database) and perform the condition on it with indexOf(). If the list changes, that’s all we need to maintain, in one place, without touching any logic. And what if you don’t have an array but a string instead? Easy. Either use JavaScript’s native String.prototype.indexOf() method… … or if you have a consistent separator in your string, break it up into an array with String.prototype.split() then refer to the tutorial above. 'Motown Records'.indexOf('Records'); // returns 7 (position in the string) var label = 'Def Jam Recordings'; label.indexOf('Records'); // returns -1 (not found) var artists = 'Diana Ross,Michael Jackson,Stevie Wonder,The Temptations,Marvin Gaye'; artists.split(',') .indexOf('Marvin Gaye'); // returns 4 (position in the array) IE8-friendly solutions Maybe you have to put up with IE8 (or older). My condoleances, I know how you feel. Working with Internet Explorer has always been a pain for front-end developers. Unfortunately for us, the indexOf() method wasn’t implemented in the prototype of the Array object before IE9. Bummer. What do we do then? Do we go back to repetitive comparisons? Of course not. There’s a light at the end of the tunnel, in fact there’s even two ways out of it: using either jQuery or a polyfill. jQuery has $.inArray, a great utility function offering exactly what we want: it looks for a value (of any type) in an array, returns a position, and it’s compatible with IE8. var names = ['Jimi', 'Amy', 'Janis', 'Brian', 'Jim', 'Robert', 'Kurt']; if ($.inArray('Kurt', names) !== -1) { // do stuff } If you can’t use jQuery (or don’t want to include it only for $.inArray), you can still add a polyfill. MDN made one for Array.prototype.indexOf() you can use in your project. You’ll be able to use indexOf() on an array like you’d normally do, even with IE8: // polyfills/indexOf.js if (!Array.prototype.indexOf) Array.prototype.indexOf = function(searchValue, index) { // In non-strict-mode, if the `this` variable is null // or undefined, then it is set the the window object. // Else, `this` is automaticly converted to an object. var len = this.length >>> 0; // convert ot number or 0 index |= 0; // rounds and NaN-checks if (index < 0) // check if negative start index = Math.max(len - index, 0); else if (index >= len) // else, check if too big return -1; if (searchValue === undefined) // Because searchValue is undefined, keys that // don't exist will have the same value as the // searchValue, and thus do need to be checked. do { if (index in this && this[index] === undefined) return index; } while (++index !== len) else // Because searchValue is not undefined, there's no // need to check if the current key is in the array // because if the key isn't in the array, then it's // undefined which is not equal to the searchValue. do { if (this[index] === searchValue) return index; } while (++index !== len) // if nothing was found, then simply return -1 return -1; }; <!-- index.html --> <script src="polyfills/indexOf.js"></script> <script> var needle = 'frontstuff'; var haystack = ['CSS Tricks', 'David Walsh Blog', 'frontstuff']; var isACoolBlog = haystack.indexOf(needle) !== -1; // true </script> References Array.prototype.indexOf() on MDN String.prototype.indexOf() on MDN String.prototype.split() on MDN jQuery’s $.inArray

You Need to Stop Targeting Tags in CSS

CSS seems easy to most developers. Because of its apparent simplicity, and because it’s so flexible, you can easily bend it to your needs and make it work. Problem is, it often makes up for a lack of knowledge of how the language works and it doesn’t push you to try and write better code. If you look into CSS methodologies like BEM or SMACSS, one of the first things you’ll be told is not to style on tag names and use classes instead. This can be a big rebuttal when you’re not used to it. Why add classes when you could simply target tag names? Why increase the size of your HTML and CSS files instead of using what’s already there and works perfectly? Tags are agnostic A div or a strong are abstract entities. They’re not aware of your project’s context. They don’t know what they’re being used for. Some of them have a functional purpose (an a to create a hyperlink, a form to submit user input, etc.) but this is nothing more than a reusable, context-unaware component. Picking an HTML tag over another makes sense semantically, or when it comes to either accessibility or SEO. They’re a set of tools to help you give structure your content. They’re not responsible for what the app looks like and they should never be. Let’s take the following piece of HTML: <div class="element"> <div> <h2>Title</h2> <p>Text</p> <p>Text</p> <ul> <li>List item</li> <li>List item</li> </ul> <div> <h2>Title</h2> <p>Text</p> ... </div> </div> <div>...</div> </div> Let’s say we need all the p from the direct div children to be blue. The most straight-forward way to do it would probably be something like: .element > div p { color: blue; } Instead of adding a .blue-text class on the right p and do: .element .blue-text { color: blue; } Makes sense right? You’re using the existing DOM structure, you’re unleashing the power of CSS operators, you’re not adding unnecessary classes, and it works. But the problem here is that you’re giving meaning to a specific DOM element based on its type. You’re locking down the structure of your HTML for styling purposes. This may not seem like a big deal, but it’s actually a major problem for scalability. When you add CSS directly on tags, your markup can’t change. Your style is tightly coupled to your DOM, and any change increases the risk of breaking things. Let’s say you now need to wrap your h2 and the two p in another div (because they need a border all around them, for example). We now have to edit our CSS to make sure it still works. .element > div > div p { color: blue; } This is getting messy. Now let’s say that later in our project, we need the p from the last direct children div not to be blue anymore. This wasn’t planned, but now it’s required. Again, you’ll have to edit the CSS: .element > div > div:not(:last-child) p { color: blue; } Anyone with basic CSS knowledge can see it’s getting out of hands, and impossible to understand without comments. Now for some reason, we need to switch the two p with an unordered list. Again, you have to edit the CSS: .element > div > div:not(:last-child) li { color: blue; } But now we have a conflict with the existing unordered list, that isn’t supposed to be styled the same way. And what if on top of that, we need to use some jQuery plugin that throws in some additional HTML on which we have no control? This is the definition of unscalability. Not only you shouldn’t have to revise your CSS to make sure things don’t break every time you make a change somewhere else, but you also shouldn’t have such a rigid link between two distinct parts of your project. Keeping things decoupled is one of the fundamental principles of programming, and it’s time we understand CSS is no exception. If you start thinking of your UI as a collection of components, it means they need to be reusable. But not because they are reusable means they should always have the exact same structure. Let’s take the example of a media object: <div class="media"> <img src="..." alt="..."> <div> <h2>Title</h2> <time>Datetime</time> <p>Content</p> </div> </div> This is the base. It defines the concept of my component: its structure and its elements. I can reuse it as much as necessary with different content. But a well-conceived component is also flexible and extendable. For example, I should totally be able to do this: <article class="media"> <div> <time>Datetime</time> <h3>Title</h3> <ul> <li>Content</li> <li>Content</li> </ul> </div> <video> <source src="..." type="video/mp4"> </video> </article> If you’re styling on tags, chances are you’ll need to edit your CSS for the above component to look right. This would result in chained rulesets such as: .media h2, .media h3 { ... } .media img, .media video { ... } This is hard to read, tedious to maintain and it makes the file a lot heavier (not to mention bad for performance, but let’s not get ahead of ourselves). Instead, by using classes, you add a context layer onto agnostic tags and you automatically exclude what shouldn’t be styled the same way. You create a clean bridge between your HTML and your CSS. <div class="media"> <img class="media-object" src="..." alt="..."> <div class="media-body"> <h2 class="media-title">Title</h2> <time class="media-datetime">Datetime</time> <p class="media-content">Content</p> </div> </div> With the above HTML structure and well-written styles that rely on those classes, you can implement any variation without even opening your CSS file. The component is a lot more readable, scalable, and versatile. Now you may be wondering “Alright, I get that I should use more classes, but does this mean I need to use them everywhere?” This leads us to our second problem. Performance issues What would you say if you had to explain the following piece of code to someone who doesn’t know CSS? .element a { color: orange; } Probably something like “I’m looking inside every .element, I target all the a tags in there and give them the color orange.” And you’d be wrong. You may read from left to right, but your browser engine reads your CSS from right to left. It evaluates every ruleset starting from the rightmost selector then traces back to the left through the parent selectors to define if it’s a match or if it should discard the rule. So when the browser reads our piece of CSS it actually goes like “I’m looking for all the a tags, then I’m making sure they’re nested in an .element, and if that’s the case, I apply the color orange to them.” This may not sound like it really matters, but the way your browser interprets your code has a major impact on performance. In our case, it starts by targeting all a tags in your page and then it applies or discards the style depending on what their ancestors are. This eats up a lot more memory than if you had a class on the specific elements you want to style, and targeted them directly: .primary-links { color: orange; } Here, the browser only searches for tags with the .primary-links class and applies the corresponding styles. If an element in your HTML document doesn’t have the class, it won’t even be crawled. Now following that logic, there’s one case when styling on tags can actually make sense: when absolutely all tags of a certain type need to be styled the same way (or when there’s only one of them in the DOM, like html or body). There’s a great chance that all strong tags in your project are supposed to be bold and that all em are supposed to be in italics. Here it would be perfectly acceptable to style directly on tags because you need a unified behavior on all elements. Performance-wise, adding a class to all tags of a same type and styling on this class (e.g.: creating a .bold class and applying it on every strong tag) would have the exact same effect as styling directly on the tag, because you’re selecting them all anyway. Yet, it adds more code and is tedious to maintain, so styling directly on tags would be the best option here. Of course, it doesn’t prevent you from creating a class on the exact same model so you can still use it on elements of another type: strong, .bold { font-weight: bold; } <p>A sentence with some <strong>bold</strong> text in it.</p> <ul> <li class="bold">A bold list item</li> <li>a regular list item</li> </ul> Exceptions & compromises Methodologies, design patterns and best practices are crucial in programming. It’s what helps you save time by using tried and true solutions and ship more robust programs. Yet it’s important not to get too caught up in it and lose sight of why you got in the game in the first place: solving problems. Rules and recommendations are here to help you write better code, but they aren’t an end in themselves. For this blog, I’m using Eric Meyer’s Reset CSS as a base so I can start off with a perfectly clean slate. By definition, a reset or a normalizer applies CSS rules on tags to remove user agent’s default styling. This isn’t awesome for performance. A more performance-friendly way to do it would be to add classes and reset unwanted styles directly on them. But let’s face it: using a reset is really, really convenient. It saves you time, headaches, and is a trustworthy base for you to start on and style freely. Another good case is when you’re working on a CMS. If the website you’re developing is supposed to receive content from non-developers, you can’t ask them to add classes on elements. Even for this blog, there’s no way I’m adding classes to all a or blockquote every time I’m writing an article: this would be ridiculous and time-consuming. This is clearly a case where we can make a compromise. To make sure my global styles don’t bleed on the rest of my website, I usually namespace my editable areas. This way I define a scope for my styled tags and I can use them anywhere I need by simply wrapping my content area in a tag with the proper class. <div class="cms"> <!-- This is where the content will be outputted --> </div> .cms p { margin-bottom: 15px; } .cms a { color: red; } ... In the end, it all comes down to your judgment as a developer. Ask yourself: is my style really that global? Or global enough to deserve being assigned globally and overridden later? Is my app a component-rich environment that will scale or a simple static website that will never move? Do I have a lot of code in my page and a humongous stylesheet, or a hundred lines of HTML and 2KB of CSS? If you’re still skeptical, I encourage you to try this method on a side project: keep styled tags to a bare minimum (a base of maximum ten selectors, for example) and use classes for everything else. I guarantee you’ll be surprised by how confident you’ll feel about scaling because of how little to no styling conflicts you’ll encounter, as well as how little you’ll have to maintain your CSS codebase to keep it healthy.