Developer News

?Deliver exceptional customer experiences in your product

Css Tricks - Thu, 03/22/2018 - 3:48am

(This is a sponsored post.)

?Pendo delivers the only complete platform for product teams that helps companies create great products. The Pendo Product Experience Platform enables product teams to understand product usage, collect user feedback, measure NPS, assist users in their apps and promote new features in product - all without requiring any engineering resources. This unique combination of capabilities is all built on a common infrastructure of product data and results in improved customer satisfaction, reduced churn, and increased revenue.

Pendo is the proven choice of innovative product leaders at Salesforce, Proofpoint, Optimizely, Citrix, BMC and many more leading companies.

Request a demo of Pendo today.?

Direct Link to ArticlePermalink

The post ?Deliver exceptional customer experiences in your product appeared first on CSS-Tricks.

Putting Things in Context With React

Css Tricks - Wed, 03/21/2018 - 6:25am

Context is currently an experimental API for React - but soon to be a first class citizen! There are a lot of reasons it is interesting but perhaps the most is that it allows for parent components to pass data implicitly to their children, no matter how deep the component tree is. In other words, data can be added to a parent component and then any child can tap into it.

See the Pen React Context Lights by Neal Fennimore (@nealfennimore) on CodePen.

While this is often the use case for using something like Redux, it’s nice to use if you do not need complex data management. Think about that! We create a custom downstream of data, deciding which props are passed and at which levels. Pretty cool.

Context is great in areas of where you have a lot of components that depend on a single piece of data, but are deep within the component tree. Explicitly passing each prop to each individual component can often be overwhelming and it is a lot easier just to use context here.

For example, let’s consider how we would normally pass props down the tree. In this case, we’re passing the color red using props on each component in order to move it on down the stream.

class Parent extends React.Component { render(){ return <Child color="red" />; } } class Child extends React.Component { render(){ return <GrandChild color={this.props.color} /> } } class GrandChild extends React.Component { render(){ return ( <div style={{color: this.props.color}}> Yep, I'm the GrandChild </div> ); } }

What if we never wanted the Child component to have the prop in the first place? Context saves us having to go through the Child component with color and pass it directly from the Parent to the GrandChild:

class Parent extends React.Component { // Allow children to use context getChildContext() { return { color: 'red' }; } render(){ return <Child />; } } Parent.childContextTypes = { color: PropTypes.string }; class Child extends React.Component { render() { // Props is removed and context flows through to GrandChild return <GrandChild /> } } class GrandChild extends React.Component { render() { return ( <div style={{color: this.context.color}}> Yep, I'm still the GrandChild </div> ); } } // Expose color to the GrandChild GrandChild.contextTypes = { color: PropTypes.string };

While slightly more verbose, the upside is exposing the color anywhere down in the component tree. Well, sometimes…

There’s Some Gotchas

You can’t always have your cake and eat it too, and context in it’s current form is no exception. There are a few underlying issues that you’ll more than likely come into contact with if you end up using context for all but the simplest cases.

Context is great for being used on an initial render. Updating context on the fly? Not so much. A common issue with context is that context changes are not always reflected in a component.

Let’s dissect these gotchas in more detail.

Gotcha 1: Using Pure Components

Context is hard when using PureComponent since by default it does not perform any shallow diffing by default with context. Shallow diffing with PureComponent is testing for whether the values of the object are strictly equal. If they're not, then (and only then) will the component update. But since context is not checked, well... nothing happens.

See the Pen React Context Lights with PureComponents by Neal Fennimore (@nealfennimore) on CodePen.

Gotcha 2: Should Component Update? Maybe.

Context also does not update if a component’s shouldComponentUpdate returns false. If you have a custom shouldComponentUpdate method, then you’ll also need to take context into consideration. To enable updates with context, we could update each individual component with a custom shouldComponentUpdate that looks something like this.

import shallowEqual from 'fbjs/lib/shallowEqual'; class ComponentThatNeedsColorContext extends React.PureComponent { // nextContext will show color as soon as we apply ComponentThatNeedsColorContext.contextTypes // NOTE: Doing the below will show a console error come react v16.1.1 shouldComponentUpdate(nextProps, nextState, nextContext){ return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState) || !shallowEqual(this.context, nextContext); } } ComponentThatNeedsColorContext.contextTypes = { color: PropTypes.string };

However, this does not solve the issue of an intermediary PureComponent between the parent and the child blocking context updates. This means that every PureComponent between the parent and child would need to have contextTypes defined on it, and they would also need to have an updated shouldComponentUpdate method. And at this point, that's a lot of work for very little gain.

Better Approaches to the Gotchas

Fortunately, we have some ways to work around the gotchas.

Approach 1: Use a Higher Order Component

A Higher Order Component can read from context and pass the needed values on to the next component as a prop.

import React from 'react'; const withColor = (WrappedComponent) => { class ColorHOC extends React.Component { render() { const { color } = this.context; return <WrappedComponent style={{color: color}} {...this.props} /> } } ColorHOC.contextTypes = { color: React.PropTypes.string }; return ColorHOC; }; export const Button = (props)=> <button {...props}>Button</button> // ColoredButton will render with whatever color is currently in context with a style prop export const ColoredButton = withColor( Button );

See the Pen React Context Lights with HOC by Neal Fennimore (@nealfennimore) on CodePen.

Approach 2: Use Render Props

Render Props allow us to use props to share code between two components.

class App extends React.Component { getChildContext() { return { color: 'red' } } render() { return <Button /> } } App.childContextTypes = { color: React.PropTypes.string } // Hook 'Color' into 'App' context class Color extends React.Component { render() { return this.props.render(this.context.color); } } Color.contextTypes = { color: React.PropTypes.string } class Button extends React.Component { render() { return ( <button type="button"> {/* Return colored text within Button */} <Color render={ color => ( <Text color={color} text="Button Text" /> ) } /> </button> ) } } class Text extends React.Component { render(){ return ( {this.props.text} ) } } Text.propTypes = { text: React.PropTypes.string, color: React.PropTypes.string, }</Color></button> Approach 3: Dependency Injection

A third way we can work around these gotchas is to use Dependency Injection to limit the context API and allow components to subscribe as needed.

The New Context

The new way of using context, which is currently slated for the next minor release of React (16.3), has the benefits of being more readable and easier to write without the “gotchas” from previous versions. We now have a new method called createContext, which defines a new context and returns both a Provider and Consumer.

The Provider establishes a context that all sub-components can hook into. It’s hooked in via Consumer which uses a render prop. The first argument of that render prop function, is the value which we have given to the Provider. By updating the value within the Provider, all consumers will update to reflect the new value.

As a side benefit with using the new context, we no longer have to use childContextTypes, getChildContext, and contextTypes.

const ColorContext = React.createContext('color'); class ColorProvider extends React.Component { render(){ return ( <ColorContext.Provider value={'red'}> { this.props.children } </ColorContext.Provider> ) } } class Parent extends React.Component { render(){ // Wrap 'Child' with our color provider return ( <ColorProvider> <Child /> </ColorProvider> ); } } class Child extends React.Component { render(){ return <GrandChild /> } } class GrandChild extends React.Component { render(){ // Consume our context and pass the color into the style attribute return ( <ColorContext.Consumer> {/* 'color' is the value from our Provider */} { color => ( <div style={{color: color}}> Yep, I'm still the GrandChild </div> ) } </ColorContext.Consumer> ); } } Separate Contexts

Since we have more granular control in how we expose context and to what components are allowed to use it, we can individually wrap components with different contexts, even if they live within the same component. We can see this in the next example, whereby using the LightProvider twice, we can give two components a separate context.

See the Pen React Context Lights with new Context by Neal Fennimore (@nealfennimore) on CodePen.

Conclusion

Context is a powerful API, but it's also very easy to use incorrectly. There are also a few caveats to using it, and it can be very hard to figure out issues when components go awry. While Higher-Order Components and dependency injection offer alternatives for most cases, context can be used beneficially in isolated portions of your code base.

With the next context though, we no longer have to worry about the gotchas we had with the previous version. It removes having to define contextTypes on individual components and opens up the potential for defining new contexts in a reusable manner.

The post Putting Things in Context With React appeared first on CSS-Tricks.

Going From Dumb Little Idea to Real Website in Like 10 Minutes

Css Tricks - Tue, 03/20/2018 - 3:43am

I live in Bend, Oregon. I woke up with the dumbest idea ever that there should be a little food truck map website and it should be called Vend, Oregon. It's not my finest idea, but hey, I'm full of those. Fortunately, we don't have to spend all day on this.

1) Figure out what's going to go on this dumb little website

Fortunately, all the hard work was already done. One of our local rags already created a list of them. They allude to a map multiple times, but it's hard to dig it up. In searching around a bit, I found this which does have an embedded Google Map.

Perhaps this can be useful then! Let's blow up this map and embed it properly!

2) Make the dumb site

Fortunately, Google Maps are embeddable. Let's just slap their embed code in an HTML document:

<body> <iframe src="https://www.google.com/maps/d/embed?mid=1bg2tr60F_w395jAY-WW8JGbwSCM" width="640" height="480"></iframe> </body>

And have it cover the entire page:

html, body { margin: 0; height: 100%; overflow: hidden; } iframe { postion: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 0; }

Let's use CodePen Projects for this, as that'll get us another step closer to having this live.

The extra files there are just a Bend logo I fired through RealFaviconGenerator. 3) Buy the dumb domain name

This is the point where you really start to question the idea. But, go ahead and pull the trigger anyway. The internet needs you.

4) It's dumb, but it it might as well be HTTPS

One big reason to use CloudFlare is you get HTTPS even on their free plan. Might as well take advantage of that. This means pointing the nameservers from your domain registrar over to CloudFlare.

5) Deploy the CodePen Project

You can deploy the site right out of CodePen Projects.

Note that you get some IP addresses there. Add those as A Records right in CloudFlare and you're done!

6) Bask in your dumb idea

Swear to god, 10 minutes from start to finish.

The post Going From Dumb Little Idea to Real Website in Like 10 Minutes appeared first on CSS-Tricks.

The Vue Cookbook

Css Tricks - Mon, 03/19/2018 - 8:59am

I'm extremely excited to announce that the Vue Cookbook is officially in beta! For the past few months, the Vue team has been writing, and editing and accepting PRs from the community to build a new section of our docs called the Cookbook. Each recipe stands on its own, meaning that recipes can focus on one specific aspect of Vue or something that integrates with Vue, and do a small deep dive into that subject. We can then include more complex examples, combining features in interesting ways.

One of my favorite parts of the cookbook is the Alternative Patterns section of each recipe. Usually when people write blog posts or document something, they're also selling you on the concept that they're explaining. In the cookbook, we strive to consider that we're all building different kinds of applications and websites, and thus a variety of choices will be valid, given divergent scenarios. The cookbook spends a little time in each recipe weighing the tradeoffs, and considering when one might need another path.

For advanced features, we assume some ecosystem knowledge. For example, if you want to use single-file components in Webpack, we don’t explain how to configure the non-Vue parts of the Webpack config. In the cookbook, we have the space to explore these ecosystem libraries in more depth—at least to the extent that is universally useful for Vue developers.

This section will continue to be in development! We have more recipes that we're writing, we're still accepting PRs, and the more community involvement, the richer a resource it becomes! I hope you enjoy it and find it useful.

Direct Link to ArticlePermalink

The post The Vue Cookbook appeared first on CSS-Tricks.

React State From the Ground Up

Css Tricks - Mon, 03/19/2018 - 3:26am

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.

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

Css Tricks - Fri, 03/16/2018 - 7:23am

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 ArticlePermalink

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

A simple resource for finding and trying variable fonts

Css Tricks - Fri, 03/16/2018 - 7:23am

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 ArticlePermalink

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

Theming With Variables: Globals and Locals

Css Tricks - Fri, 03/16/2018 - 4:04am

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

Css Tricks - Thu, 03/15/2018 - 6:57am

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 ArticlePermalink

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

Css Tricks - Thu, 03/15/2018 - 5:55am

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.

Css Tricks - Thu, 03/15/2018 - 5:55am

(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 ArticlePermalink

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

Short note on what CSS display properties do to table semantics

Css Tricks - Wed, 03/14/2018 - 10:14am

We've blogged about responsive tables a number of times over the years. There's a variety of techniques, and which you choose should be based on the data in the table and the UX you're going for. But many of them rely upon resetting a table element's natural display value to something else, for example display: block. Steve Faulkner warns us:

When CSS display: block or display: grid or display: flex is set on the table element, bad things happen. The table is no longer represented as a table in the accessibility tree, row elements/semantics are no longer represented in any form.

He argues that the browser is making a mistake here by altering those semantics, but since they do, it's good to know it's fixable with (a slew of) ARIA roles.

Here's more from Adrian Roselli including a demo with proper markup.

Direct Link to ArticlePermalink

The post Short note on what CSS display properties do to table semantics appeared first on CSS-Tricks.

A Browser-Based, Open Source Tool for Alternative Communication

Css Tricks - Wed, 03/14/2018 - 5:15am

Shay Cojocaru contributed to this post.

Have you ever lost your voice? How did you handle that? Perhaps you carried a notebook and pen to scribble notes. Or jotted quick texts on your phone.

Have you ever traveled somewhere that you didn't speak or understand the language everyone around you was speaking? How did you order food, or buy a train ticket? Perhaps you used a translation phrasebook, or Google translate. Perhaps you relied mostly on physical gestures.

All of these solutions are examples of communication methods — tools and strategies — that you may have used before to solve everyday communicative challenges. The preceding examples are temporary solutions to temporary challenges. Your laryngitis cleared up. You returned home, where accomplishing daily tasks in your native tongue is almost effortless. Now imagine that these situational obstacles were somehow permanent.

I grew up knowing the challenges and creativity needed for effective communication when verbal speech is impeded. My younger sister speaks one word: “mama.” When we were little, I remember our mom laying a white sheet over a chair to take pictures of everyday items — an apple, a fork, a toothbrush. She painstakingly printed, cut out, laminated, and organized these images for my sister to use to point at what she wanted to say. We carried her words in plastic baggies.

As we both grew up, and technology evolved, her communication options expanded exponentially. From laminated paper, to a proprietary touchscreen device with text-to-speech functionality, to a communication app on the iTouch, and later the iPad.

Different people experience difficulty verbalizing speech for a multitude of reasons. As in my sister’s case, sometimes it’s genetic. Sometimes it’s situational. The reasons may be temporary, chronic, or permanent. Augmentative and alternative communication (AAC) is an umbrella term encompassing various communication methods used to supplement or replace speech. The United States Society for Augmentative and Alternative Communication (USAAC) defines AAC-devices as including “all forms of communication (other than oral speech) that are used to express thoughts, needs, wants, and ideas.” The fact that you’re reading these words is an example of AAC — writing is a mechanism that augments my verbal communication.

The range of communication solutions people employ are as varied as the reasons they are needed. Examples range from printed picture grids, to text-to-speech apps, to switches which enable typing using morse code, to software that tracks eye movement or detects facial movements. (The software behind Stephen Hawking’s AAC is open source!)

The Convention on the Rights of Persons with Disabilities (CRPD), an international human rights treaty intended to protect the rights and dignity of people with disabilities, includes accessibility to communication and information. Huge challenges exist in making this access universal. Current solutions can be prohibitively expensive. According to the World Health Organization, in many low-income and middle-income countries, only 5-15% of the people who need assistive devices and technologies are able to obtain them. Additionally, many apps come in a limited number of languages. Many require a specific app store or proprietary device. Commercial AAC solutions can be expensive, and/or have limited language support, which can render them largely inaccessible to many people in low-income countries.

Enter Cboard, an open source project (recently supported by the UNICEF Innovation Fund!) powered by people dedicated to the idea of providing a solution that works for everyone, everywhere; a free, web-based communication board that leverages the thriving open source ecosystem and the built-in functionality of modern browsers.

It’s a complex problem, but, by taking advantage of available open source software and key ways in which the web has evolved over the last couple of years (in terms of modern browser API development and web standards), we can build a free, multilingual, open source, web-based alternative. Let’s talk about a few of those pieces — the Web Speech API, React, the Internationalization API, and the “progressive web app” concept.

Web Speech API

The challenge of artificially producing human speech is not new. Speech recognition and synthesis tools have been available for quite some time already — from voice dictation software to accessibility tools like screen readers. But the availability of a browser-based API makes it possible to start looking toward producing web services that have a low barrier to entry to provide speech synthesis, and that provide a consistent experience of that speech synthesis.

The Web Speech API provides an interface for speech recognition (speech-to-text) and speech synthesis (text-to-speech) in the browser. With Cboard, we are primarily concerned with the SpeechSynthesis interface, which is used to produce text-to-speech (TTS) output. Using the API, we can retrieve information about the synthesis voices available on the device (which varies by browser and operating system), start and pause speech, etc. Browsers tend to use the speech services available by default on the device’s operating system — the API exposes methods to interact with these services. We’ve done our own mapping of some of the voice and language offerings by digesting data returned from the SpeechSynthesis interface on different devices running different operating systems, using different browsers:

You can see, for example, Chrome on MacOS shows 66 voices — that’s because it uses MacOS native voices, as well as 19 additional voices provided from the browser. (Interested to see what voices and languages are available to you? Check out browserspeechsupport.me.)

Comprehensive support for the Web Speech API is still getting there, but most major modern browsers support it. (The Speech Synthesis API is available to 78.81% of users globally at time of writing). The draft specification was introduced in 2012, and is not yet a standard.

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

DesktopChromeOperaFirefoxIEEdgeSafari332749No147Mobile / TabletiOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid Firefox7.0-7.1NoNoNo64No React

React is a JavaScript library for building user interfaces. One of the most unambiguous insights from the 2017 “State of JavaScript” — a survey of over 23,000 developers — was that React is currently the “dominant front-end library” in terms of sheer numbers, and with high marks for usage level and developer satisfaction.

That doesn’t mean it’s the best for every situation, and it doesn’t mean it will be dominant in the long-term. But its features, and the relative ubiquity of adoption (at this point, at least), make it a great option for our project, because there is a lower barrier to entry for people to begin contributing — there is a strong community for learning and troubleshooting.

React makes use of the concept of the “virtual” DOM, where a virtual representation of UI is kept in memory. Any changes to the state of your application are compared against the state of the “real” DOM, using a “diffing” algorithm. This allows us to make efficient changes to the view layer of an application, and represent the state of our application in a predictable way, without requiring manual DOM manipulation (for the most part). React also emphasizes the use of component-based architecture.

React is supported by all popular browsers. (For some older browsers like IE 9 / IE 10, polyfills are required).

ECMAScript Internationalization API

As noted earlier, one area in which current AAC offerings fall short is broad multi-language support. The combination of the Web Speech API, the Internationalization API (and the open source offerings around it), and React, allow us to support up to 33 languages. (For reasons described earlier, this support varies between operating systems).

Internationalization is the process of designing and developing an application and its content “in a way that ensures it will work well for, or can be easily adapted for, users from any culture, region, or language.” The Internationalization API provides functionality for three key areas: string comparison, number formatting, and date and time formatting. The API is exposed on the global Intl object.

FormatJS, a collection of libraries that build on the Intl standard, has a suite of integrations with common component libraries (like React!) that ship with the FormatJS core libraries built in. We use the React integration, react-intl, which provides bindings to internationalize React apps.

Most browsers in the world support the ES Intl API (84.16% of users globally at time of writing).

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

DesktopChromeOperaFirefoxIEEdgeSafari241529111210Mobile / TabletiOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid Firefox10.0-10.237No4.46457 Progressive Web Apps

Progressive Web Apps (PWAs) are regular websites that take advantage of modern browser features to deliver a web experience with the same benefits (or even better ones) as native mobile apps. Any website is technically a PWA if it fulfills three requirements: it runs under HTTPS, has a Web App Manifest, and has a service worker. A service worker essentially acts as a proxy, sitting between web applications, the browser, and the network. It runs in the background, deciding to serve network or cached content based on connectivity, allowing for management of an offline experience.

Beyond those three base requirements, things get a bit more murky. When Alex Russell and Frances Berriman introduced and named “progressive web app” they enumerated ten attributes that characterize a PWA — responsive, connectivity independent, app-like, fresh, safe, discoverable, re-engageable, installable, and linkable.

This concept ends up as the key puzzle piece in our attempt to build something that solves the problems described earlier — that most existing AAC solutions can be prohibitively expensive, offer limited languages, or remain stuck in an app store or proprietary device. Using the PWA approach we can tie together the features modern browsers have to offer — the Web Speech API, Internationalization API, etc — coupled with an app-like experience regardless of operating systems, un-beholden to centralized app distribution methods, and with support for seamlessly continued offline use.

This browser support data is from Caniuse, which has more detail. A number indicates that browser supports the feature at that version and up.

DesktopChromeOperaFirefoxIEEdgeSafari453244No1711.1Mobile / TabletiOS SafariOpera MobileOpera MiniAndroidAndroid ChromeAndroid Firefox11.337No626457

The current state of the web provides all the foundational ingredients we need to build a more inclusive, more broadly accessible AAC solution for people around the world. In the spirit of the open web, and with a great nod to the work that has been done to codify web standards, we know that a free and open communication solution is in sight.

Sound interesting to you? We invite you to come take a look and perhaps even dig in as a contributor!

References

The post A Browser-Based, Open Source Tool for Alternative Communication appeared first on CSS-Tricks.

Chrome DevTools “Local Overrides”

Css Tricks - Tue, 03/13/2018 - 7:38am

There's been two really interesting videos released recently that use the "Local Overrides" feature of Chrome DevTools in order to play with web performance without even touching the original source code.

The big idea is that you can literally edit CSS and reload the page and your changes stick. Meaning you can use the other performance testing tools inside DevTools to see if your changes had the effect you wanted them to have. Great for showing a client a change without them having to set up a whole dev environment for you.

Direct Link to ArticlePermalink

The post Chrome DevTools “Local Overrides” appeared first on CSS-Tricks.

Notched Boxes

Css Tricks - Tue, 03/13/2018 - 7:30am

Say you're trying to pull off a design effect where the corner of an element are cut off. Maybe you're a Battlestar Galactica fan? Or maybe you just like the unusual effect of it, since it avoids looking like a typical rectangle.

I suspect there are many ways to do it. Certainly, you could use multiple backgrounds to place images in the corners. You could just as well use a flexible SVG shape placed in the background. I bet there is also an exotic way to use gradients to pull it off.

But, I like the idea of simply taking some scissors and clipping off the dang corners. We essentially can do just that thanks to clip-path. We can use the polygon() function, provide it a list of X and Y coordinates and clip away what is outside of them.

Check out what happens if we list three points: middle top, bottom right, bottom left.

.module { clip-path: polygon( 50% 0, 100% 100%, 0 100% ); }

Instead of just three points, let's list all eight points needed for our notched corners. We could use pixels, but that would be dangerous. We probably don't really know the pixel width or height of the element. Even if we did, it could change. So, here it is using percentages:

.module { clip-path: polygon( 0% 5%, /* top left */ 5% 0%, /* top left */ 95% 0%, /* top right */ 100% 5%, /* top right */ 100% 95%, /* bottom right */ 95% 100%, /* bottom right */ 5% 100%, /* bottom left */ 0 95% /* bottom left */ ); }

That's OK, but notice how the notches aren't at perfect 45 degree angles. That's because the element itself isn't a square. That gets worse the less square the element is.

We can use the calc() function to fix that. We'll use percentages when we have to, but just subtract from a percentage to get the position and angle we need.

.module { clip-path: polygon( 0% 20px, /* top left */ 20px 0%, /* top left */ calc(100% - 20px) 0%, /* top right */ 100% 20px, /* top right */ 100% calc(100% - 20px), /* bottom right */ calc(100% - 20px) 100%, /* bottom right */ 20px 100%, /* bottom left */ 0 calc(100% - 20px) /* bottom left */ ); }

And you know what? That number is repeated so many times that we may as well make it a variable. If we ever need to update the number later, then all it takes is changing it once instead of all those individual times.

.module { --notchSize: 20px; clip-path: polygon( 0% var(--notchSize), var(--notchSize) 0%, calc(100% - var(--notchSize)) 0%, 100% var(--notchSize), 100% calc(100% - var(--notchSize)), calc(100% - var(--notchSize)) 100%, var(--notchSize) 100%, 0% calc(100% - var(--notchSize)) ); }

Ship it.

See the Pen Notched Boxes by Chris Coyier (@chriscoyier) on CodePen.

This may go without saying, but make sure you have enough padding to handle the clipping. If you wanna get really fancy, you might use CSS variables in your padding value as well, so the more you notch, the more padding there is.

The post Notched Boxes appeared first on CSS-Tricks.

A Better Sketch File, a Better Designer, a Better You

Css Tricks - Mon, 03/12/2018 - 9:27am

I’ve been thinking about this post by Isabel Lee for the last couple of weeks — it’s all about how we should be more considerate when making designs in Sketch. They argue that we’re more likely to see real efficiency and organizational improvements in our work if we name our layers, artboards, and pages properly. Isabel writes:

Keeping a super organized Sketch file has helped me smooth out my design process and saved me time when I was trying to find a specific component or understand an archived design. For instance, I was looking for an icon that I used six months ago and it was (relatively) easy to find because all my artboards and layers were well-named and grouped reverse-chronologically. I was also able to cross-reference it with my meeting notes from around that time. If I hadn’t done any of that work (thanks Past Isabel!), I probably would’ve had to dig through all my old designs and look at each layer. Or worse?—?I would’ve had to recreate that icon.

Since I read this I’ve been doing the same thing and effectively making “daily commits” with the naming of my pages and it’s been genuinely helpful when looking back through work that I’ve forgotten about. But what I really like about this tidy-up process is how Isabel describes the way in which they could easily look back on their work, identify weaknesses in their design process, and how to become a better designer:

Aside from making it easier to find things, it’s also helped me cultivate good documentation habits when I want to analyze my old work and see where I could’ve made improvements. I revisited one of my old Sketch files and realized that I didn’t do enough research before diving into a million iterations for an initial idea I had.

Direct Link to ArticlePermalink

The post A Better Sketch File, a Better Designer, a Better You appeared first on CSS-Tricks.

Consistent Design Systems in Sketch With Atomic Design and the Auto-Layout Plugin

Css Tricks - Mon, 03/12/2018 - 3:15am

Do you design digital products (or websites) and hand design files off to developers for implementation? If you answered yes, settle in! While the should-designers-code debate rages on, we're going to look at how adding a methodology to your design workflow can make you faster, more consistent, and loved by all developers... even if you don't code.

Let's dig in!

Why a methodology?

In the development world, it seems like at least half of your career is about staying up to date with new tech and leveling up your skills. While the pace may not be quite as frantic in the design landscape as it is in development, there definitely has been a huge shift in tools over the past three years or so.

Tools like Sketch have made a lot of the old pain of working in design files a thing of the past. Smart combinations of text styles, object styles, symbols, and libraries now mean sweeping changes are just one click away. No more picking through 40 Photoshop layers to make a single color change.

Yet, sweeping color changes in a marketing landing page is no longer the biggest design challenge. Design and development teams are now expected to deliver complex interfaces loaded with interaction and conditional states... for every device available now and the next day. Working as both a designer and developer, I have seen the workflow friction from both sides.

Beyond tools, designers need an approach.

Thinking in terms of "components"

If you work in the tech space in any capacity, you have likely heard of development frameworks such as React, Angular, or Vue.

Um yeah, I'm a designer so that doesn't really concern me, bye.

Kinda. But if you're hoping to do design work for modern digital products, there is a pretty big chance that said products will be built using one of these frameworks. No one expects an architect to build the structures themselves, but they better have a high-level understanding of the what the tools are and how they will be used.

So here's what you need to know about modern front-end frameworks:

They have brought on a paradigm shift for developers in which products are built by combining a series of smaller components into complex systems which can adapt to different contexts and devices. This makes the code easier to maintain, and the entire system more flexible.

For a variety of legitimate reasons, many designers have not caught on to this paradigm shift as quickly as developers. We are missing a mental model for creating the pieces that make up these interfaces independently from their environment/pages/screens/viewports etc.

One such approach is Atomic Design.

What is Atomic Design?

First coined by Brad Frost, Atomic Design is a methodology which tries to answer a simple question: if hundreds of device sizes mean we can no longer effectively design "pages," then how do we even design?

The answer lies in breaking down everything that could make up a "page" or "view" into smaller and smaller pieces, creating a "system" of blocks which can then be recombined into an infinite number of variations for our project.

You can think of it like the ingredients in a recipe. Sure, you could make muffins, but you could just as easily make a cake with the same list of ingredients.

Brad decided to use the chemistry analogy, and so he proposes that our systems are made up of:

  • Atoms
  • Molecules
  • Organisms

For the sake of simplicity, let's take a look at how we might apply this to a website.

Atoms

Atoms represent the smallest building blocks which make up our user interfaces. Imagine a form label, a form input, and a button. Each one of those represents an atom:

A header, text block, and link each serve as atoms. Molecules

Molecules are simply groups of atoms combined to create something new. For our purposes, we can think of molecules as groups of disjointed UI pieces which are combined to create a meaningful component.

The atoms come together to form a "card" component. Organisms

Organisms are made up of groups of molecules (or atoms or other organisms). These are the pieces of an interface which we might think of as a "section." In an invoicing application, an organism could be a dashboard combining a "new invoice" button (atom), a search form (molecule), a "total open" card (molecule), and table listing overdue invoices. You get the idea.

Let's look at what a "featured block" organism might look like in our simple website:

A header (atom), three cards (molecules), an image (atom), and a teaser (molecule) are combined to form one featured block organism. Using stacks for consistency

So, now that we have a mental model for the "stuff," how do we go about creating these building blocks? Sketch is great out of the box, but the plugins available for it provide huge performance tools… just like text editors for developers. We will be using Sketch's built-in symbols tools, as well as the amazing Stacks feature from Anima App's Auto-Layout plugin.

Using these tools will bring some priceless benefits which I will point out as we go, but at the very least you can count on:

  • better design consistency and faster iteration
  • a sanity check from using consistent spacing multipliers
  • faster reordering of content
  • help identifying design problems quickly and early on
What exactly are stacks?

If you've ever heard developers excitedly talk about flexbox for building layouts in CSS, then you can think of stacks as the Sketch equivalent. Stacks (like flexbox) allow you to group a series of layers together and then define their spacing and alignment on a vertical or horizontal axis.

Here we group three items, align them through their center, and set 48px vertical space between each one:

A simple stacked folder aligning and distributing three items.

The layers will automatically be group into a blue folder with an icon of vertical or horizontal dots to show what kind of stack you have.

Look at that! You just learned flexbox without touching a line of code. &#x1f602;

Nested stacks

The real power of stacks comes from nesting stacks inside other stacks:

Stacks can be nested inside of each other to create complex spacing systems.]

Here, we can see a card component made up of multiple stacks:

  • card__cta link from the previous example.
  • card__copy stack which handles the alignment & space for the header and text.
  • card__content which controls the spacing and alignment between the card__cta and card__copy stacks.
A quick note about layer naming

I almost always use the BEM naming convention for my components. Developers appreciate the logic when I have to to hand off design files because it often aligns with the naming conventions they are using in code. In the case where I'm developing the project myself, it gives me a bit of a head start as I've started thinking about the markup at the design stage.

If that's super confusing, don't worry about it. Please just make your colleagues' job a little easier by organizing your layers and giving them descriptive names.

Stacks shmacks, I have great attention to detail and can do all this manually!

You're absolutely right! But what about when you have carefully laid out 10 items, all of varying sizes, and now they need extra space between them? Or, you need to add a line of text to one of those items? Or, you need to split content into three columns rather than four?

That never happens, right? &#x1f631;

One of two things usually happens at this stage:

  1. You start manually reorganizing all the things and someone's paying for wasted time (whether it’s you or the client).
  2. You kinda fudge it… after all, the developer surely knows what your original intentions were before you left every margin off by a couple pixels in your layout. ¯\_(?)_/¯

Here's what stacks get you:

  • You can change the alignment or spacing options as much as you like with a simple value adjustment and things will just magically update.
  • You can resize elements without having to pick at your artboard to rejig all the things.
  • You can reorder, add, or remove items from the stack folder and watch the items redistribute themselves according to your settings—just like code. &#x1f389;

Notice how fast it is to edit content and experiment with different layouts all while maintaining consistency:

Stacks and symbols make experimentation cheap and consistent.

OK, so now we know why stacks are amazing, how do we actually use them?

Creating stacks

Creating a stack is a matter of selecting two (or more) layers and hitting the stacks folder icon in the inspector. From there, you can decide if you are stacking your layers horizontally or vertically, and set the distance between the items.

Here’s an example of how we’d create an atom component using stacks:

Creating a horizontal stack with 20px spacing between the text and icon.

And, now let’s apply the stacks concept to a more complex molecule component:

Creating a card molecule using nested stacks. Creating symbols from stacks

We’ve talked about the many benefits of stacks, but we can make them even more efficient by applying Sketch’s symbol tool to them. The result we get is a stack that can be managed from one source instance and reused anywhere.

Creating an atom symbol

We can grab that call-to-action stack we just created and make it a symbol. Then, we can use overrides for the text and know that stacks will honor the spacing:

Creating a symbol from a stack is great for ensuring space consistency with overrides.

If I decide later that I want to change the space by a few pixels, I can just tweak the stack spacing on the symbol and have it update on every instance &#x1f389;

Creating a molecule symbol

Similarly, I can group multiple stacked atoms into a component and make that into a symbol:

Creating a card symbol from our stacks and call-to-action symbol. Symbols + stacks = &#x1f4aa;

Wouldn't it be nice if we could maintain the spacial requirements we set regardless of the tweaks we might bring to them down the line? Yes!

Replacing one item with another inside a component

Let's assume our card component now requires a button rather than a link as a call-to-action. As long as we place that button in the correct stack folder, all the pixel-nudging happens automagically:

Because our symbol uses stacks, the distance between the copy and the call-to-action will automatically be respected. Editing molecules and organisms on the fly &#x1f525;

You might be thinking that this isn't a huge deal and that adjusting the tiny spacial issue from the previous example would have taken just a moment without stacks. And you wouldn't be wrong. But let's refer back to our notions about atomic design for a moment, and ask what happens when we have far more complex "organisms" (groups of atoms and molecules) to deal with?

Similar to our mobile example from the beginning, this is where the built-in power of stacks really shines:

Stacks and symbols makes experimentation cheap and consistent.

With a library of basic symbols (atoms) at our fingertips, and powerful spacing/alignment tools, we can experiment and create endless variations of components. The key is that we can do it quickly and without sacrificing design consistency.

Complex layouts and mega stacks

Keeping with the elements we have already designed, let's see what a layer stack might look like for a simple marketing page:

An example of an expanded layer stack.

Don't let the initial impression of complexity of those stacks scare you. A non-stacked version of this artboard would not look so different aside from the color of the folder icons.

However it's those very folders that give us all the power:

Layout experimentation can be fast and cheap! We may not need to code, but we have a responsibility to master our tools for efficiency and figure out new workflows with our developer colleagues.

This means moving away from thinking of design in the context of pages, and creating collections of components… modules… ingredients… legos… figure out a metaphor that works for you and then make sure the whole team shares the vocabulary.

Once we do this, issues around workflow and collaboration melt away:

Speed and Flexibility

Carefully building components with symbols and using automated and consistent spacing/alignment with stacks does require a bit of time investment upfront. However, the return of easy experimentation and ability to change course quickly and at low cost is well worth it.

Consistency and UX

Having to think about how elements work as combinations and in different contexts will catch UX-smells early and expose issues around consistency before you’re 13 screens in. Changing direction by adjusting a few variables/components/spacing units beats nudging elements around an artboard all day.

Responsibility and Governance

A single 1440px page view of the thing you are building simply does not provided a developer with enough context for multiple screens and interaction. At the same time, crafting multiple high fidelity comps one tiny element at a time is a budget buster (and this is particularly true of app designs). So, what tends to happen on small teams? The developer gets the one gorgeous 1440px view… aaaaand all the cognitive overhead of filling in the gaps for everything else.

Providing the details is our job.

Atomic design gave us speed, creative freedom, and flexibility. It changed everything.”

—From the forward of Atomic Design

If we work with developers on digital products, we should be excited about learning how the sausage is made and adapt our approach to design accordingly. Our tools may not evolve quite as quickly as JavaScript frameworks, but if you haven’t taken a peek under to hood of some of these apps in the last couple of years, this is a great time to dig in!

The post Consistent Design Systems in Sketch With Atomic Design and the Auto-Layout Plugin appeared first on CSS-Tricks.

CSS-Tricks Chronicle XXXIII

Css Tricks - Sun, 03/11/2018 - 4:48am

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 &#x1f60d;. 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

Css Tricks - Sat, 03/10/2018 - 7:31am

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

Direct Link to ArticlePermalink

The post Design Microsites appeared first on CSS-Tricks.

Extinct & Endangered

Css Tricks - Fri, 03/09/2018 - 10:07am

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. &#x1f622;

Direct Link to ArticlePermalink

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

Syndicate content
©2003 - Present Akamai Design & Development.