React State From the Ground Up

As you begin to learn React, you will be faced with understanding what state is. State is hugely important in React, and perhaps a big reason you’ve looked into using React in the first place. Let’s take a stab at understanding what state is and how it works.

What is State?

State, in React, is a plain JavaScript object that allows you keep track of a component’s data. The state of a component can change. A change to the state of a component depends on the functionality of the application. Changes can be based on user response, new messages from server-side, network response, or anything.

Component state is expected to be private to the component and controlled by the same component. To make changes to a component’s state, you have to make them inside the component — the initialization and updating of the component’s state.

Class Components

States is only available to components that are called class components. The main reason why you will want to use class components over their counterpart, functional components, is that class components can have state. Let’s see the difference. Functional components are JavaScript functions, like this:

const App = (props) => { return ( <div> { this.props } </div> )
}

If the functionality you need from your component is as simple as the one above, then a functional component is the perfect fit. A class component will look a lot more complex than that.

class App extends React.Component { constructor(props) { super(props) this.state = { username: 'johndoe' } } render() { const { username } = this.state return( <div> { username } </div> ) }
}

Above, I am setting the state of the component’s username to a string.

The Constructor

According to the official documentation, the constructor is the right place to initialize state. Initializing state is done by setting this.state to an object, like you can see above. Remember: state is a plain JavaScript object. The initial state of the App component has been set to a state object which contains the key username, and its value johndoe using this.state = { username: 'johndoe' }.

Initializing a component state can get as complex as what you can see here:

constructor(props) { super(props) this.state = { currentTime: 0, status: false, btnOne: false, todoList: [], name: 'John Doe' }
}

Accessing State

An initialized state can be accessed in the render() method, as I did above.

render() { const { username } = this.state return( <div> { username } </div> )
}

An alternative to the above snippet is:

render() { return( <div> { this.state.username } </div> )
}

The difference is that I extracted the username from state in the first example, but it can also be written as const status = this.state.username. Thanks to ES6 destructuring, I do not have to go that route. Do not get confused when you see things like this. It is important to know that I am not reassigning state when I did that. The initial setup of state was done in the constructor, and should not be done again – never update your component state directly.

A state can be accessed using this.state.property-name. Do not forget that aside from the point where you initialized your state, the next time you are to make use of this.state is when you want to access the state.

Updating State

The only permissible way to update a component’s state is by using setState(). Let’s see how this works practically.

First, I will start with creating the method that gets called to update the component’s username. This method should receive an argument, and it is expected to use that argument to update the state.

handleInputChange(username) { this.setState({username})
}

Once again, you can see that I am passing in an object to setState(). With that done, I will need to pass this function to the event handler that gets called when the value of an input box is changed. The event handler will give the context of the event that was triggered which makes it possible to obtain the value entered in the input box using event.target.value. This is the argument passed to handleInputChange() method. So, the render method should look like this.

render() { const { username } = this.state return ( <div> <div> <input type="text" value={this.state.username} onChange={event => this.handleInputChange(event.target.value)} /> </div> <p>Your username is, {username}</p> </div> )
}

Each time setState() is called, a request is sent to React to update the DOM using the newly updated state. Having this mindset makes you understand that state update can be delayed.

Your component should look like this;

class App extends React.Component { constructor(props) { super(props) this.state = { username: 'johndoe' } } handleInputChange(username) { this.setState({username}) } render() { const { username } = this.state return ( <div> <div> <input type="text" value={this.state.username} onChange={event => this.handleInputChange(event.target.value)} /> </div> <p>Your username is, {username}</p> </div> ) }
}

Passing State as Props

A state can be passed as props from a parent to the child component. To see this in action, let’s create a new component for creating a To Do List. This component will have an input field to enter daily tasks and the tasks will be passed as props to the child component.

Try to create the parent component on your own, using the lessons you have learned thus far.

Let’s start with creating the initial state of the component.

class App extends React.Component { constructor(props) { super(props) this.state = { todoList: [] } } render() { return() }
}

The component’s state has its todoList set to an empty array. In the render() method, I want to return a form for submitting tasks.

render() { const { todoList } = this.state return ( <div> <h2>Enter your to-do</h2> <form onSubmit={this.handleSubmit}> <label>Todo Item</label> <input type="text" name="todoitem" /> <button type="submit">Submit</button> </form> </div > )
}

Each time a new item is entered and the submit button is clicked, the method handleSubmit gets called. This method will be used to update the state of the component. The way I want to update it is by using concat to add the new value in the todoList array. Doing so will set the value for todoList inside the setState() method. Here’s how that should look:

handleSubmit = (event) => { event.preventDefault() const value = (event.target.elements.todoitem.value) this.setState(({todoList}) => ({ todoList: todoList.concat(value) }))
}

The event context is obtained each time the submit button is clicked. We use event.preventDefault() to stop the default action of submission which would reload the page. The value entered in the input field is assigned a variable called value, which is then passed an argument when todoList.concat() is called. React updates the state of todoList by adding the new value to the initial empty array. This new array becomes the current state of todoList. When another item is added, the cycle repeats.

A chart illustrating the cycle explained above.

The goal here is to pass the individual item to a child component as props. For this tutorial, we’ll call it the TodoItem component. Add the code snippet below inside the parent div which you have in render() method.

<div> <h2>Your todo lists include:</h2> { todoList.map(i => <TodoItem item={i} /> )}
</div>

You’re using map to loop through the todoList array, which means the individual item is then passed to the TodoItem component as props. To make use of this, you need to have a TodoItem component that receives props and renders it on the DOM. I will show you how to do this using functional and class components.

Written as a functional component:

const TodoItem = (props) => { return ( <div> {props.item} </div> )
}

For the class component, it would be:

class TodoItem extends React.Component { constructor(props) { super(props) } render() { const {item} = this.props return ( <div> {item} </div> ) }
}

If there is no need to manage state in this component, you are better off using functional component.

Leveling Up

You will be handling state very often while developing React application. With all the areas covered above, you should have the confidence of being able to dive into the advanced part of state management in React. To dig deeper, I recommend React’s official documentation on State and Lifecycle as well as Uber’s React Guide on Props vs State.

The post React State From the Ground Up appeared first on CSS-Tricks.

Microsoft Edge Variable Fonts Demo

The Edge team put together a thorough demo of variable fonts, showcasing them in all of their shape-shifting and adaptive glory. Equally interesting as the demo itself is a history of web typography and where variable fonts fit in the grand scheme of things.

This demo pairs well with v-fonts.com, which is an interactive collection of variable fonts that allows you to play around with the variable features each font provides.

Direct Link to Article — Permalink

The post Microsoft Edge Variable Fonts Demo appeared first on CSS-Tricks.

A simple resource for finding and trying variable fonts

This is a website designed to showcase fonts that support OpenType Variations and let you drag a whole bunch of sliders around to manipulate a typeface’s width, height, and any other settings that the type designer might’ve added to the design.

I think the striking thing about this project is that I had no idea just how many variable fonts were out there in the wild until now.

Direct Link to Article — Permalink

The post A simple resource for finding and trying variable fonts appeared first on CSS-Tricks.

Theming With Variables: Globals and Locals

Cliff Pyles contributed to this post.

Setting CSS variables to theme a design system can be tricky: if they are too scoped, the system will lose consistency. If they are too global, you lose granularity.

Maybe we can fix both issues. I’d like to try to boil design system variables down to two types: Global and Component variables. Global variables will give us consistency across components. Component variables will give us granularity and isolation. Let me show you how to do it by taking a fairly simple component as an example.

Heads up, I’ll be using CSS variables for this article but the concept applies to preprocessor variables as well.

Global-scoped variables

System-wide variables are general concepts defined to keep consistency across your components.

Starting with an .alert component as an example, let’s say we want to keep consistency for all of our spaces on margins and paddings. We can first define global spacers:

:root { --spacer-sm: .5rem; --spacer-md: 1rem; --spacer-lg: 2rem;
}

And then use on our components:

/* Defines the btn component */
.btn { padding: var(--spacer-sm) var(--spacer-md);
} /* Defines the alert component */
.alert { padding: var(--spacer-sm) var(--spacer-md);
}

The main benefits of this approach are:

  • It generates a single source of truth for spacers, and a single point for the author using our system to customize it.
  • It achieves consistency since every component follows the same spacing.
  • It produces a common point of reference for designers and developers to work from. As long as the designers follow the same spacing restrictions, the translation to code is seamless.

But it also presents a few problems:

  • The system loses modularity by generating a dependency tree. Since components depend on global variables, they are no longer isolated.
  • It doesn’t allow authors to customize a single component without overwriting the CSS. For example, to change the padding of the alert without generating a system wide shift, they’d have to overwrite the alert component:
.alert { padding-left: 1rem; padding-right: 1rem;
}

Chris Coyier explains the idea of theming with global variables using custom elements in this article.

Component-scoped variables

As Robin Rendle explain in his article, component variables are scoped to each module. If we generate the alert with these variables, we’d get:

.alert { --alert-color: #222; color: var(--alert-color); border-color: var(--alert-color);
}

The main advantages are:

  • It creates a modular system with isolated components.
  • Authors get granular control over components without overwriting them. They’d just redefine the value of the variable.

There is no way to keep consistency across components or to make a system wide change following this method.

Let’s see how we can get the best of both worlds!

The two-tier theming system

The solution is a two-layer theming system where global variables always inform component variables. Each one of those layers follow a set of very specific rules.

First tier: Global variables

The main reason to have global variables is to maintain consistency, and they adhere to these rules:

  • They are prefixed with the word global and follow the formula --global--concept--modifier--state--PropertyCamelCase
    • a concept is something like a spacer or main-title
    • a state is something like hover, or expanded
    • a modifier is something like sm, or lg
    • and a PropertyCamelCase is something like BackgroundColor or FontSize
  • They are concepts, never tied to an element or component
    • this is wrong: --global-h1-font-size
    • this is right: --global--main-title--FontSize

For example, a global variable setup would look like:

:root { /* --global--concept--size */ --global--spacer--sm: .5rem; --global--spacer--md: 1rem; --global--spacer--lg: 2rem; /* --global--concept--PropertyCamelCase */ --global--main-title--FontSize: 2rem; --global--secondary-title--FontSize: 1.8rem; --global--body--FontSize: 1rem; /* --global--state--PropertyCamelCase */ --global--hover--BackgroundColor: #ccc;
}

Second tier: Component variables

The second layer is scoped to theme-able component properties and follow these rules:

  • Assuming we are writing BEM, they follow this formula: --block__element--modifier--state--PropertyCamelCase
    • The block__element--modifier the selector name is something like alert__actions or alert--primary
    • a state is something like hover or active
    • and if you are not writing BEM class names the same principles apply, just replace the block__element--modifier with your classname
  • The value of component scoped variables is always defined by a global variable
  • A component variable always has a default value as a fallback in case the component doesn’t have the dependency on the global variables

For example:

.alert { /* Component scoped variables are always defined by global variables */ --alert--Padding: var(--global--spacer--md); --alert--primary--BackgroundColor: var(--global--primary-color); --alert__title--FontSize: var(--global--secondary-title--FontSize); /* --block--PropertyCamelCase */ padding: var(--alert--Padding, 1rem); /* Sets the fallback to 1rem. */
} /* --block--state--PropertyCamelCase */
.alert--primary { background-color: var(--alert--primary--BackgroundColor, #ccc);
} /* --block__element--PropertyCamelCase */
.alert__title { font-size: var(--alert__title--FontSize, 1.8rem);
}

You’ll notice that we are defining locally-scoped variables with global variables. This is key for the system to work since it allows authors to theme the system as a whole. For example, if they want to change the primary color across all components they just need to redefine --global--primary-color.

On the other hand each component variable has a default value so a component can stand on its own, it doesn’t depend on anything and authors can use it in isolation.

This setup allows for consistency across components, it generates a common language between designers and developers since we can set the same global variables in Sketch as bumpers for designers, and it gives granular control to authors.

Why does this system work?

In an ideal world, we as creators of a design system, expect “authors” or users of our system to implement it without modifications, but of course, the world is not ideal and that never happens.

If we allow authors to easily theme the system without having to overwrite CSS, we’ll not only make their lives easier but also reduce the risk of breaking modules. At the end of the day, a maintainable system is a good system.

The two-tier theming system generates modular and isolated components where authors have the possibility to customize them at a global and at a component level. For example:

:root { /* Changes the secondary title size across the system */ --global--secondary-title--FontSize: 2rem;
} .alert { /* Changes the padding on the alert only */ --alert--Padding: 3rem;
}

What values should became variables?

CSS variables open windows to the code. The more we allow authors in, the more vulnerable the system is to implementation issues.

To keep consistency, set global variables for everything except layout values; you wouldn’t want authors to break the layout. And as a general rule, I’d recommend allowing access to components for everything you are willing to give support.

For the next version of PatternFly, an open source design system I work on, we’ll allow customization for almost everything that’s not layout related: colors, spacer, typography treatment, shadows, etc.

Putting everything together

To show this concept in action I’ve created a CodePen project:

Global variables are nestled in _global-variables.scss. They are the base to keep consistency across the system and will allow the author to make global changes.

There are two components: alert and button. They are isolated and modular entities with scoped variables that allow authors to fine tune components.

Remember that authors will use our system as a dependency in their project. By letting them modify the look and feel of the system through CSS variables, we are creating a solid code base that’s easier to maintain for the creators of the system and better to implement, modify, and upgrade to authors using the system.

For example, if an author wants to:

  • change the primary color to pink across the system;
  • change the danger color to orange just on the buttons;
  • and change the padding left to 2.3rem only on the alert…

…then this is how it’s done:

:root { // Changes the primary color on both the alert and the button --global--primary--Color: hotpink;
} .button { // Changes the danger color on the button only without affecting the alert --button--danger--BackgroundColor: orange; --button--danger--hover--BorderColor: darkgoldenrod;
} .alert { // Changes the padding left on the alert only without affecting the button --alert--PaddingLeft: 2.3rem;
}

The design system code base is intact and it’s just a better dependency to have.

I am aware that this is just one way to do it and I am sure there are other ways to successfully set up variables on a system. Please let me know what you think on the comments or send me a tweet. I’d love to hear about what you are doing and learn from it.

The post Theming With Variables: Globals and Locals appeared first on CSS-Tricks.

Building A Static Site With Components Using Nunjucks

We’re so used to either a backend language or a JavaScript framework powering our data-backed components. I love me a Rails partial with a bunch of locals: {} or a <Component ...props /> but you don’t have to give up on components even if working in static HTML. With Nunjucks, which has includes and templates and macros, we have a robust toolset for building component-based sites that are easy, fast, and secure to host.

Direct Link to Article — Permalink

The post Building A Static Site With Components Using Nunjucks appeared first on CSS-Tricks.

Animate a Container on Mouse Over Using Perspective and Transform

I’ve been working on a website in which large pictures are displayed to the user. Instead of creating a typical lightbox effect (a zoom-in animation with a black overlay) for these large pictures, I decided to try and make something more interactive and fun. I ended up coding an image container that tilts as the user moves the mouse cursor above it.

Here’s the final version:

See the Pen MrLopq by Mihai (@MihaiIonescu) on CodePen.

This effect is achieved through CSS and JavaScript. I figured I’d make a little tutorial explaining how each part works so you could easily reproduce it or extend it.

I recommend reading up on the almanac entries for perspective and transform before we get started. We’re going to refer to these properties through the post and it’s a good idea to be familiar with them.

Let’s get down to it.

Setup

First, we need a container with another inner element. The container will help with the perspective.

<div id="container"> <div id="inner"></div>
</div>

For demonstration purposes, let’s center the card exactly in the middle of the screen:

body { /* Full screen width and height */ width: 100%; min-height: 100vh; /* Centers the container in the middle of the screen */ display: flex; justify-content: center; align-items: center; margin: 0; background-color: rgb(220, 220, 220);
} #container { /* This will come into play later */ perspective: 40px;
} #inner { width: 20em; height: 18em; background-color: white;
}

This gives us a white card that is positioned directly in the center of a light gray background. Note that we’ve set the perspective of the #container to 40px which does nothing at this point because we have not created any transforms. That will be handled later in the JavaScript.

See the Pen 3D Image Container – Part 0 by Mihai (@MihaiIonescu) on CodePen.

Let’s Start Scripting

Here’s the outline for what we’re doing:

var container = document.getElementById('container');
var inner = document.getElementById('inner'); var onMouseEnterHandler = function(event) { update(event);
};
var onMouseLeaveHandler = function() { inner.style = "";
};
var onMouseMoveHandler = function(event) { if (isTimeToUpdate()) { update(event); }
}; container.onmouseenter = onMouseEnterHandler;
container.onmouseleave = onMouseLeaveHandler;
container.onmousemove = onMouseMoveHandler;

And here is what all those things are (or will) be doing:

  • Handler Functions: these functions handle the events as they happen. We want to decide what happens when the cursor enters, moves over, and leaves the container, so each of those has a handler.
  • Update Function: We haven’t coded this yet but its goal will be to update the 3D rotation of our #inner div.
  • Time to Update Function: This is another function we haven’t coded yet but it will return true when an update is required. This is a way to reduce the number of calls to the update() function and improve the performance of our script.
  • Event: This is a JavaScript object that describes the event that occurred.

The code above will:

  • Update the 3D rotation of the inner div as soon as the mouse enters the container.
  • Update the 3D rotation of the inner div when the appropriate time comes as the mouse moves over the container.
  • Reset the style of the inner div when the mouse leaves the container.

Is it Time to Update?

Let’s add the function that decides when to update the 3D rotation of the #inner div.

var counter = 0;
var updateRate = 10;
var isTimeToUpdate = function() { return counter++ % updateRate === 0;
};

When the counter reaches the updateRate, an update will be made.

At this point, you can try replacing the update function by a console.log() and play with the updateRate to see how it all works together.

The Mouse

Next up is the mouse object. This one is a little more complex than the other sections. Still, it’s not that difficult to understand, but the code can seem intimidating, especially if you’re new to JavaScript.

// Init
var container = document.getElementById('container');
var inner = document.getElementById('inner');
// Mouse var mouse = { _x: 0, _y: 0, x: 0, y: 0, updatePosition: function(event) { var e = event || window.event; this.x = e.clientX - this._x; this.y = (e.clientY - this._y) * -1; }, setOrigin: function(e) { this._x = e.offsetLeft + Math.floor(e.offsetWidth/2); this._y = e.offsetTop + Math.floor(e.offsetHeight/2); }, show: function() { return '(' + this.x + ', ' + this.y + ')'; }
}
// Track the mouse position relative to the center of the container.
mouse.setOrigin(container);

Again, let’s walk through this together.

  • show(): Displays the current position of the mouse (if you want to do some debugging in the browser’s console).
  • setOrigin(e): Sets the coordinates (0,0) of our mouse object at the center of the element (e).
  • updatePosition(): Updates the current position of our mouse object, relative to (0,0).

The last line of code mouse.setOrigin(container) snaps the coordinates (0,0) of our mouse object to the center of our container. Here’s an example that illustrates it.

See the Pen 3D Image Container – Part 1 by Mihai (@MihaiIonescu) on CodePen.

The idea behind all this is to add more rotation to our #inner div as you move the mouse farther from the center of the container.

Update Styles on Mouse Position

Here’s our update function:

var update = function(event) { mouse.updatePosition(event); updateTransformStyle( (mouse.y / inner.offsetHeight/2).toFixed(2), (mouse.x / inner.offsetWidth/2).toFixed(2) );
}; var updateTransformStyle = function(x, y) { var style = "rotateX(" + x + "deg) rotateY(" + y + "deg)"; inner.style.transform = style; inner.style.webkitTransform = style; inner.style.mozTransform = style; inner.style.msTransform = style; inner.style.oTransform = style;
};
  • update(): Updates the mouse position and updates the style of the #inner div.
  • updateTransformStyle(): Updates the style for each vendor prefix.

Are We Done?

We’d better do some testing! Looks like we get a change in perspective when the mouse cursor enters and exits the card, but it’s not as smooth as it could be:

See the Pen 3D Image Container – Part 2 by Mihai (@MihaiIonescu) on CodePen.

Oh right! We told it to update the rotation of our #inner div every time the counter hits the updateRate. This produces a clunky transition between updates.

How do we solve that? CSS transitions.

Adding Transitions

#inner { transition: transform 0.5s;
}

These are arbitrary numbers. You can play with the perspective and transform values to make the effect more or less dramatic as you see fit.

See the Pen 3D Image Container – Part 3 by Mihai (@MihaiIonescu) on CodePen.

Note that resizing the page will cause some problems because the position of the container changes in the page. The solution is to re-center your mouse object in your container after the page is resized.

Wrapping Up

We’re done! Now we have a container for making an element a little more interactive. The demo at the beginning of this post uses an image inside of the container, but this can be used for other things besides images, including forms, modals, or just about any other content you drop in the container. Go experiment!

The post Animate a Container on Mouse Over Using Perspective and Transform appeared first on CSS-Tricks.

​HelloSign API: Everything IT requires and Developers love.

(This is a sponsored post.)

We know that no API can write your code for you (unfortunately), but ours comes close. With in-depth documentation, customizable features, amazing support, and a dashboard that makes your code easy to debug, you won’t find an eSignature product with an easier path to implementation. Or that’s more liked by your team.

We wanted an API built by a team that valued user experience as much as we do. At the end of the day we chose HelloSign because it was the best combination of these features, price and user experience.

– Max Mullen Co-Founder of Instacart

Test drive HelloSign API for free today.

Direct Link to Article — Permalink

The post ​HelloSign API: Everything IT requires and Developers love. appeared first on CSS-Tricks.

CSS-Tricks Chronicle XXXIII

It’s been many months since our last CSS-Tricks Chronicle. As a reminder, these are just little roundups of news of a slightly more personal nature and that of the site itself and surrounding projects.

Last update, I wasn’t even a dad yet! That’s changed 😍. My daughter is going in for her four-month checkup today!


I’m also working out of a brand new office here in Bend, Oregon. We split the space with CraftCMS. It’s the first time I’ve had an office that I have real (part) ownership over. We’ve built out a kitchen area in it and are decorating it and fleshing it out to be useful and fun for all of us.

One particularly cool thing, we splurged on a VocalBooth. It’s got the whole medium-fancy podcasting setup in there, so it’s pretty darn good sound quality for the podcasting we do. Plus it’s a nice place to take a call or meeting as well.


I made a round of updates to my microsite The Power of Serverless for Front-End Developers. My goal with that site is to explain the idea to the best of my ability and how it can be a useful thing to know about particular for front-end developers to do more with the skills they already have. Once you’re sold on that, it’s still a huge world to wrap your head around. One of the issues is understanding how many different services are out there and what roles they are trying to play. So the Services section is decently fleshed out and organized to help with that.

Over on CodePen Radio, I got to chat about all this with Marie Mosley. That’s the first time I’ve really talked about it, so it kinda resulted in a big ol’ thought dump.


I’ve had so many thoughts about this “serverless” stuff, I figured I’d formulate them into a proper conference talk. I’m not doing too many of those this year, but I’ll definitely be at An Event Apart Seattle (April 2-4), and Front-End Design Conference (April 25-27). Come!


I got to speak with Jonathan Denwood and John Locke on the WP-Tonic Podcast.


Tons going on at CodePen, of course. We’re always podcasting all about that, so if you’re particularly interested in behind-the-scenes CodePen, CodePen Radio is your friend. As I imagine any business, we’re always hard at work on a mix of projects. Some largely internal, like rearchitechting our email system, and some directly for our users, like rewriting our realtime systems to make features like Collab Mode way better.

As the year flipped over, of course we rounded up the Most Hearted list, so if you missed that, check it out.


ShopTalk just had a major milestone! Our 300th episode! Dave and I take the opportunity to talk about then and now. We’ve had loads of fun and educational episodes this year though, so if you just pick and choose episodes to listen to, I bet you’ll find one worth a crack.

The post CSS-Tricks Chronicle XXXIII appeared first on CSS-Tricks.

Design Microsites

Google, Airbnb, Slack, MailChimp, Facebook, Etsy, IBM, Dropbox… everybody has a design site these days.

Direct Link to Article — Permalink

The post Design Microsites appeared first on CSS-Tricks.

Extinct & Endangered

I’ve been watching a lot of nature documentaries lately. I like how you can either pay super close attention to them, or use them as background TV. I was a massive fan of the original Blue Planet, so it’s been cool watching the Blue Planet II episodes drop recently, as one example. A typical nature documentary will always have a little look how bad we’re screwing up the environment twist, which is the perfect time and place for such a message.

Speaking of perfect time and place, why not remind ourselves of all the endangered animals out there with placeholder images! That’s what Endangered Species Placeholders is. It’s like PlaceKitten, but for environmental good.

I also just came across this free icon set of extinct animals. 😢

Direct Link to Article — Permalink

The post Extinct & Endangered appeared first on CSS-Tricks.