Subscribe to CSS-Tricks feed
Tips, Tricks, and Techniques on using Cascading Style Sheets.
Updated: 9 hours 1 min ago

​The #1 Website for Coding Challenges

Thu, 08/10/2017 - 13:10

Coderbyte is a web application built to help you practice programming and improve your algorithm skills. We offer a collection of coding challenges and web development courses that can help you prepare for an upcoming job interview or general technical assessment. All of our coding challenges can be completed directly in our online editor, and if you need help along the way you can view thousands of user-submitted code solutions as well.

View all Coding Challenges

Direct Link to ArticlePermalink

​The #1 Website for Coding Challenges is a post from CSS-Tricks

The Difference Between Explicit and Implicit Grids

Thu, 08/10/2017 - 13:09

Grid Layout finally gives us the ability to define grids in CSS and place items into grid cells. This on its own is great, but the fact that we don't have to specify each track and we don't have to place every item manually makes the new module even better. Grids are flexible enough to adapt to their items.

This is all handled by the so called explicit and implicit grid.

All code samples in this post are accompanied by images in order to display grid lines and tracks. If you want to tinker with the code yourself, I recommend you download Firefox Nightly because it currently has the best DevTools to debug grids.

Explicit Grids

We can define a fixed number of lines and tracks that form a grid by using the properties grid-template-rows, grid-template-columns, and grid-template-areas. This manually defined grid is called the explicit grid.

An explicit grid with 4 vertical tracks (columns) and 2 horizontal tracks (rows). (View Pen) .grid { display: grid; grid-template-columns: 1fr 1fr 1fr 1fr; grid-template-rows: 100px 100px; grid-gap: 20px; } Repeating tracks

When we define grid-template-columns: 1fr 1fr 1fr 1fr; we get four vertical tracks each with a width of 1fr. We can automate that by using the repeat() notation like so grid-template-columns: repeat(4, 1fr);. The first argument specifies the number of repetitions, the second a track list, which is repeated that number of times.

A track list? Yes, you can actually repeat multiple tracks.

See the Pen CSS Grid Layout: Repeating track lists by Manuel Matuzovic (@matuzo) on CodePen.

Automatic repetition of tracks An explicit grid with 4 vertical tracks each 100px wide, generated by the repeat notation. (View Pen)

The repeat notation is quite useful, but it can be automated even further. Instead of setting a fixed number of repetitions we can use the auto-fill and auto-fit keywords.

Auto-filling tracks

The auto-fill keyword creates as many tracks as fit into the grid container without causing the grid to overflow it.

Repetition of as many vertical tracks with a width of 100px as fit into the grid container. (View Pen) .grid { display: grid; grid-template-columns: repeat(auto-fill, 100px); grid-gap: 20px; }

Note that repeat(auto-fill, 1fr); will only create one track because a single track with a width of 1fr already fills the whole grid container.

Auto-fitting tracks

The auto-fit keyword behaves the same way as auto-fill, except that after grid item placement it will only create as many tracks as needed and any empty repeated track collapses.

.grid { display: grid; grid-template-columns: repeat(auto-fit, 100px); grid-gap: 20px; }

In the example used in this section the grid will look the same with repeat(auto-fit, 100px); and repeat(4, 100px);. The difference is visible when there are more than 4 grid items.

If there are more items, auto-fit creates more columns.

The repeat notation with the auto-fit keyword creates as many tracks as needed and as many as fit into the grid container. (View Pen)

On the other hand, if a fixed number of vertical tracks is used in the repeat notation and the number of items exceeds this value more rows are added. You can read more about that in the next section: implicit grids.

If there are more items than vertical tracks, more rows are added. (View Pen)

I've used grid-template-columns in the above examples out of convenience, but all rules also apply to grid-template-rows.

.grid { display: grid; grid-template-columns: repeat(auto-fill, 100px); grid-template-rows: repeat(auto-fill, 100px); grid-gap: 20px; height: 100%; } html, body { height: 100%; } The repeat notation with the auto-fill keyword on both axes. (View Pen) Implicit Grids

If there are more grid items than cells in the grid or when a grid item is placed outside of the explicit grid, the grid container automatically generates grid tracks by adding grid lines to the grid. The explicit grid together with these additional implicit tracks and lines forms the so called implicit grid.

Two items placed outside of the explicit grid causing the creation of implicit lines and tracks (View Pen) .item:first-child { grid-column-start: -1; } .item:nth-child(2) { grid-row-start: 4; }

The widths and heights of the implicit tracks are set automatically. They are only big enough to fit the placed grid items, but it's possible to change this default behavior.

Sizing implicit tracks

The grid-auto-rows and grid-auto-columns properties give us control over the size of implicit tracks.

.grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: 100px 100px; grid-gap: 20px; grid-auto-columns: 200px; grid-auto-rows: 60px; }

Implicit tracks will now always have a width of 200px and a height of 60px, no matter if the grid item fits or not.

Fixed widths and heights for implicit tracks (View in CodePen)

You can make sized implicit tracks more flexible by specifying a range using the minmax() notation.

.grid { grid-auto-columns: minmax(200px, auto); grid-auto-rows: minmax(60px, auto); }

Implicit tracks are now at least 200px wide and 60px high, but will expand if the content demands it.

Extending the grid to the start

Implicit tracks may not just be added to the end of the explicit grid. It may also happen that the explicit grid needs to be extended to the start.

An implicit grid extended by one row and one column to the start (View Pen) .item:first-child { grid-row-end: 2; grid-row-start: span 2; } .item:nth-child(2) { grid-column-end: 2; grid-column-start: span 2; }

Each item ends on the second line and spans 2 cells (one vertically, the other horizontally). Since there is only one cell before the second line respectively another implicit track is added to the grid at the start of each side.

Automatic Placement

As already mentioned, implicit tracks are also added if the number of items exceeds the number of cells. By default, the auto-placement algorithm places items by filling each row consecutively, adding new rows as necessary. We can specify how auto-placed items get flowed into the grid by using the grid-auto-flow property.

Instead of rows, new columns are added if the number of items exceeds the number of cells (View in CodePen) .grid { display: grid; grid-template-columns: repeat(4, 1fr); grid-template-rows: 100px 100px; grid-gap: 20px; grid-auto-flow: column; }

Instead of rows, columns are being filled with items and additional implicit columns are created.

Not defining an explicit grid

Due to the fact that it's possible to automatically size cells using grid-auto-rows and grid-auto-columns it's not obligatory to define an explicit grid.

An implicit grid without explicit lines and tracks (View in CodePen) .grid { display: grid; grid-auto-columns: minmax(60px, 200px); grid-auto-rows: 60px; grid-gap: 20px; } .item:first-child { grid-row: span 2; } .item:nth-child(2) { grid-column: 1 / span 2; } .item:nth-child(5) { grid-column: 3; }

Relying solely on the implicit grid can get confusing and difficult to understand in combination with explicit placement. In this example the first item is placed auto and spans 2 rows, the second item is placed explicitly in the first column and spans 2 columns creating a second vertical track. The third and fourth item would actually both be placed automatically in the fourth row, but the fifth item is placed explicitly in the previously non-existent third column. This creates a third vertical track and due to Grids auto-placement, the third item moves up a row to fill the space.


This article doesn't cover everything there is to know about the explicit and implicit grid, but it should give you more than a solid understanding of the concept. Knowing why and how implicit lines and tracks a created is vital for working with Grid Layout.

You can find all the examples used in this article in a Collection on CodePen.

If you want to learn more about Grids check out The Complete Guide to Grid, Getting Started with CSS Grid, Grid By Example and A Collection of Interesting Facts about CSS Grid Layout.

The Difference Between Explicit and Implicit Grids is a post from CSS-Tricks


Wed, 08/09/2017 - 21:28

Novelty site with a message (and reference articles) by Rob Lafratta.

Direct Link to ArticlePermalink

abovethefold.fyi is a post from CSS-Tricks

Removing that ugly :focus ring (and keeping it too)

Wed, 08/09/2017 - 13:02

David Gilbertson:

Removing the focus outline is like removing the wheelchair ramp from a school because it doesn't fit in with the aesthetic.

So David shows how you can remove it unless you detect that the user is tabbing, then show it. Essentially you add "user-is-tabbing" class to the body when you detect the tabbing, and use that class to remove the focus styles if it's not there (plus handle the edge cases).

Direct Link to ArticlePermalink

Removing that ugly :focus ring (and keeping it too) is a post from CSS-Tricks

The Best Way to Implement a “Wrapper” in CSS

Wed, 08/09/2017 - 12:20

Sometimes the first bit of HTML we write in a new document is an element that wraps everything else on the page. The term wrapper is common for that. We give it a class, and that class is responsible for encapsulating all visual elements on the page.

I've always struggled to with the best way to implement it. I found a related thread on StackOverflow that has more than 250,000 views, so obviously I'm not the only one wondering! I'll sum up my latest thoughts in this article.

Before we dive into it, let's first examine the difference between the "wrapper" and the "container".

"Wrapper" vs "Container"

I believe there is a difference between wrapper and container elements.

In programming languages, the word container is generally used for structures that can contain more than one element. A wrapper, on the other hand, is something that wraps around a single object to provide more functionality and interface to it.

So, in my opinion, it makes sense to have two different names because they intend different functions.

Speaking of the wrapper, it's common to think of a <div> that contains all the rest of the HTML of the document. I'm sure many of us have lived through a time where we set that to 960px in width and center aligned all our main content. Wrappers are also used for things like applying a sticky footer.

The container, on the other hand, usually intends another kind of containment. One that sometimes necessary to implement a behavior or styling of multiple components. It serves the purpose of grouping elements both semantically and visually. As an example, Bootstrap has "container classes" that house their grid system or contain various other components.

The terms wrapper and container can also mean the same thing depending on the developer and what they intend. There might be other conventions too, so the best advice is usually to implement whatever makes the most sense to you. But remember, naming is one of the most fundamental and important parts of developer activities. Naming conventions make our code more readable and predictable. Choose carefully!

Here's an example of a general page wrapper:

/** * 1. Centers the content. Yes, it's a bit opinionated. * 2. See the "width vs max-width" section * 3. See the "Additional Padding" section */ .wrapper { margin-right: auto; /* 1 */ margin-left: auto; /* 1 */ max-width: 960px; /* 2 */ padding-right: 10px; /* 3 */ padding-left: 10px; /* 3 */ } width vs max-width

Setting the width of a block-level element will prevent it from stretching out to the edges of its container (good for things like readable line lengths). Therefore, the wrapper element will take up the specified width. The problem occurs when the browser window is narrower than the specific width of the wrapper. That will trigger a horizontal scrollbar, which is almost always undesirable.

Using max-width instead, in this situation, is better for narrower browser windows. This is important when making a site usable on small devices. Here's a good example showcasing the problem.

See the Pen CSS-Tricks: The Best Way to Implement a CSS Wrapper by Kaloyan Kosev (@superKalo) on CodePen.

In terms of responsiveness, max-width is the better choice!

Additional Padding

I've seen a lot of developers forget one particular edge case. Let's say we have a wrapper with max-width set to 980px. The edge case appears when the user's device screen width is exactly 980px. The content then will exactly glue to the edges of the screen with no breathing room left.

The "no breathing room left" problem.

We usually want a bit of padding on the edges. That's why if I need to implement a wrapper with a total width of 980px, I'd do it like so:

.wrapper { max-width: 960px; /* 20px smaller, to fit the paddings on the sides */ padding-right: 10px; padding-left: 10px; /* ... */ }

Therefore, that's why adding padding-left and padding-right to your wrapper might be a good idea, especially on mobile.

Or, consider using box-sizing so that the padding doesn't change the overall width at all.

Which HTML Element to Choose

A wrapper has no semantic meaning. It simply holds all visual elements and content on the page. It's just a generic container. In terms of semantics, <div> is the best choice. The <div> also has no semantic meaning and it just a generic container.

One might wonder if maybe a <section> element could fit this purpose. However, here's what the W3C spec says:

The <section> element is not a generic container element. When an element is needed only for styling purposes or as a convenience for scripting, authors are encouraged to use the div element instead. A general rule is that the section element is appropriate only if the element's contents would be listed explicitly in the document's outline.

The <section> element carries it's own semantics. It represents a thematic grouping of content. The theme of each section should be identified, typically by including a heading (h1-h6 element) as a child of the section element.

Examples of sections would be chapters, the various tabbed pages in a tabbed dialog box, or the numbered sections of a thesis. A Web site's home page could be split into sections for an introduction, news items, and contact information.

It might not seem very obvious at first sight, but yes! The plain ol' <div> fits best for a wrapper!

Using the <body> tag vs. Using an additional <div>

It's worth mentioning that there will be some instances where one could use the <body> element as a wrapper. The following implementation will work perfectly fine:

body { margin-right: auto; margin-left: auto; max-width: 960px; padding-right: 10px; padding-left: 10px; }

And it will result in one less element in your markup because you can drop that unnecessary wrapper <div> this way.

However, I wouldn't recommend this, due to flexibility and resilience to changes. Imagine if on a later stage of the project any of these scenarios happen:

  • You need to enforce a footer to "stick" to the end of the document (bottom of the viewport when the document is short). Even if you can use the most modern way to do it - with flexbox, you need an additional wrapper <div>.
  • You need to set the background-color of the whole page. Since the body tag has a max-width, it won't be possible to use it. But then you could set the background color with the <html> tag instead of the <body> tag. Well, I don't know about that. I've read the HTML vs Body in CSS and it just sounds a bit uncommon to me. However, I haven't heard any issues or difficulties raised due to applying a background color to the <html> element. But it still does sound a bit weird, doesn't it?

I would conclude it is still best practice to have an additional <div> for implementing a CSS wrapper. This way if spec requirements change later on you don't have to add the wrapper later and deal with moving the styles around. After all, we're only talking about one extra DOM element.

The Best Way to Implement a “Wrapper” in CSS is a post from CSS-Tricks

Browser Compatibility for CSS Grid Layouts with Simple Sass Mixins

Tue, 08/08/2017 - 11:54

According to an article from A List Apart about CSS Grid, a "new era in digital design is dawning right now." With Flexbox and Grid, we have the ability to create layouts that used to be extremely difficult to implement, if not impossible. There's an entirely new system available for creating layouts, especially with Grid. However, as with most web technologies, browser support is always something of an issue. Let's look at how we can make the fundamental aspects of Grid work across the browsers that support it, including older versions of Internet Explorer that supported an older and slightly different version of Grid.

The Sales Pitch

If you visit caniuse.com, you'll see that CSS Grid is supported in current versions of all major browsers except Opera Mini. So why not start using it? Rachel Andrew wrote extensively on the subject of if it's "safe to use" or not. It is, assuming you're OK with a fallback scenario that doesn't replicate exactly what Grid can do:

If your website really needs to look the same in all browsers (whatever that means to you), you won't be able to use any features only available by using Grid. In that case, don't use Grid Layout! Use Grid Layout if you want to achieve something that you can't do in a good way with older technologies.

If you'd like to get started learning Grid, Jen Simmons has a nice collection of links and there is a reference guide here.

Grid is a major change to CSS layout. It's powerful, (fairly) easy to use, and, if you're working on open source or on a team, easy for fellow developers to read. In this article, we're going to look at how we can write Grid code to be as compatible as we can possibly make it, including some degree of fallback.

The Sauce

The main thing we want to do in this post is address browser compatibility for the fundamentals of CSS Grid. We'll cover how to construct a parent grid element and place child grid elements within.

The outliers are going to be Internet Explorer and Edge. Edge is just starting to ship the modern CSS grid syntax, and it's an evergreen browser so ultimately we won't have to worry about Edge too much, but at the time of this writing, it matters. IE 10 and 11 are rather locked in time, and both support the old syntax.

Again, Rachel Andrew has information on this old syntax, what it supports, and how to use it. The old syntax, for example, doesn't support display: grid;, we have to do display: -ms-grid;. And there are similarly prefixed for many of the properties.

Even then, many of the properties themselves are not the same. But it's okay. The differences are not that great and we can get some help from Sass. The saving grace here is that we only need vendor prefixes for IE/Edge. Any other browsers will be addressed by the "standard" properties.

First, let's define a Grid parent using a Sass @mixin:

@mixin display-grid { display: -ms-grid; display: grid; } .grid-parent { @include display-grid; }

Here's a demo of that, which also defines and lays out a simple grid:

See the Pen CSS Grid Demo 1 by Farley (@farleykreynolds) on CodePen.

This is helpful, but the grid itself isn't yet compatible with the old CSS Grid style.

Next we need to cover the differences in defining the grid parent rows and columns. Let's beef up the grid a little bit and define it to be compatible across all browsers (for example, by using -ms-grid-columns in addition to grid-template-columns):

See the Pen CSS Grid Demo 2 by Farley (@farleykreynolds) on CodePen.

The -ms- prefixed properties will work for IE/Edge and the non-prefixed properties will work for other grid-supporting browsers. This particular demo will give us the following dimensions:

  • One column 150px wide.
  • One column that takes up all available space left over by the other columns (1fr = 1 fraction of the remaining space after other elements are calculated).
  • Two columns at 100px wide apiece.
  • Three rows at 1fr tall apiece.

Check out the value for grouping on line 19. IE and Edge don't have syntax for grouping a set of rows or columns that are all the same dimensions. We can accomplish the same thing in any other browser using the repeat() function:

repeat([number of columns or rows], [width of columns or height of rows])

No vendor prefix can help us here, we'll need to write out each column manually with the old syntax.

Now we have a grid that's compatible across all browsers, but we still need to address the grid children. The following Pen illustrates how they can be made compatible:

See the Pen CSS Grid Demo 2.5 by Farley (@farleykreynolds) on CodePen.

Here's the mixin for placing the grid items in both the old and new syntax:

@mixin grid-child ($col-start, $col-end, $row-start, $row-end) { -ms-grid-column: $col-start; -ms-grid-column-span: $col-end - $col-start; -ms-grid-row: $row-start; -ms-grid-row-span: $row-end - $row-start; grid-column: #{$col-start}/#{$col-end}; grid-row: #{$row-start}/#{$row-end}; } .child { @include grid-child(2, 3, 2, 3); }

Here's what you need to know about the difference between properties for the grid children in different browsers. In most browsers, you define a grid child by the grid lines where it starts and ends. Grid lines are the lines that exist between the columns and rows you've defined. The syntax looks like this:

grid-column-start: 3; grid-column-end: 5; /* or the shorthand version: */ grid-column: 3 / 5;

This element will span column lines 3 through 5 in your grid.

In IE and Edge, you define a grid child by the line it starts on and how many rows or columns it spans (There is no shorthand version as in the previous example). The syntax looks like this:

-ms-grid-column: 3; -ms-grid-column-span: 2;

This element will start on line 3 and span 2 columns. The two code snippets above will effectively create the same element. Notice that 5 - 3 (from the first snippet) is 2, which is the column span from the IE/Edge example. This allows us to do some quick math in our @mixin and get all the needed information from four numbers. The subtraction on lines 17 and 19 sets your span number for IE/Edge.

Using @include grid-element; allows you to define a grid child for any browser using only four numbers: The column start and end, and row start and end.

So now we've got grid parents and children that work for all browsers.

Drawbacks and Fallbacks

It's an unfortunate reality that not all browsers support CSS Grid, and that the old syntax doesn't support everything from the modern syntax. For example, grid-gap and grid-auto-rows or grid-auto-columns are very useful properties in the modern syntax that there isn't any equivalent to in the old syntax.

Sometimes you can use the @supports for help. @supports works a bit like a media query, where if it matches the CSS inside it applies.

This can get very tricky though, as @supports is not supported in IE. This kind of creates a puzzle when you want to use features like grid-auto-rows or grid-gap to automate portions of the layout, as you have three scenarios now: modern grid support, old grid support with @supports, old grid support without @supports.

@supports (display: -ms-grid) { /* This will apply in Edge (old syntax), but not IE 10 or 11 */ }

For the old syntax, you'll have to place your grid children and set their margins explicitly so the CSS is recognized by IE, which would nullify the need for auto placement or grid-gap in other browsers.

The following Pen is kind of a hodge-podge, due to the issue of @supports compatibility. You can see how grid-auto-rows works, and how to set the gaps for IE/Edge where grid-gap won't work. Again, if you have to support IE, the need for explicitly setting values may nullify the need for properties that set layout styles automatically.

See the Pen Grid Demo 3 by Farley (@farleykreynolds) on CodePen.

The grid-auto-rows property will automatically generate successive rows of a specified height as the columns fill up. You can play with it in the Pen by adding more divs. Another row will be added each time you increase the number of divs past a multiple of three (the number of columns).

The grid-gap property essentially turns the lines between your grid children into gutters. You can set its value using all the usual CSS size units like rems, ems, pixels, etc. In the demo above, the properties involving nth-child set margins that replicate the gutter effect of grid-gap for IE and Edge. It's not that difficult to account for with simple grids but you can see how it could get out of hand quickly with more advanced or flexible grids.

These two properties and others can be used as a basis for some very powerful layouts. If you're responsible for supporting IE and Edge, it will come down to a judgment call on whether or not your project warrants the code it takes to account for them. It's also true that sites don't necessarily have to look the same in all browsers. And because grid layouts are so easy to construct, they're probably worth the extra time.

I think it's worth taking some time to consider whether your project would benefit from CSS Grid and use the @supports rule if it would.


CSS Grid is changing the way layouts on the web are constructed and how they work. Browser support is probably always going to be an issue for web technologies but the saving grace here is that it's really not that bad for CSS Grid. And even then, the differences are easily accounted for in our code. CSS Grid layouts are awesome and powerful and with a little convenience help from tools like Sass, they can also be compatible.

Browser Compatibility for CSS Grid Layouts with Simple Sass Mixins is a post from CSS-Tricks

The Evolution of Trust

Mon, 08/07/2017 - 12:31

Nicky Case's games are a damn treasure in this world. Most importantly, they are fun and compelling to play. They also make gameplay the vehicle for education on tricky, intricate, and important issues. Issues that would be much harder to learn about by just reading. They are also a masterclass in design: clear calls to action, clear onboarding, meaningful interactions and animations, and good copy.

This latest one is no different.

Direct Link to ArticlePermalink

The Evolution of Trust is a post from CSS-Tricks

All About React Router 4

Mon, 08/07/2017 - 11:53

I met Michael Jackson for the first time at React Rally 2016, soon after writing an article on React Router 3. Michael is one of the principal authors of React Router along with Ryan Florence. It was exciting to meet someone who built a tool I liked so much, but I was shocked when he said. "Let me show you our ideas React Router 4, it's way different!" Truthfully, I didn't understand the new direction and why it needed such big changes. Since the router is such a big part of an application's architecture, this would potentially change some patterns I've grown to love. The idea of these changes gave me anxiety. Considering community cohesiveness and being that React Router plays a huge role in so many React applications, I didn't know how the community would accept the changes.

A few months later, React Router 4 was released, and I could tell just from the Twitter buzz there was mixed feelings on the drastic re-write. It reminded me of the push-back the first version of React Router had for its progressive concepts. In some ways, earlier versions of React Router resembled our traditional mental model of what an application router "should be" by placing all the routes rules in one place. However, the use of nested JSX routes wasn't accepted by everyone. But just as JSX itself overcame its critics (at least most of them), many came around to believe that a nested JSX router was a pretty cool idea.

So, I learned React Router 4. Admittedly, it was a struggle the first day. The struggle was not with the API, but more so the patterns and strategy for using it. My mental model for using React Router 3 wasn't migrating well to v4. I would have to change how I thought about the relationship between the router and the layout components if I was going to be successful. Eventually, new patterns emerged that made sense to me and I became very happy with the router's new direction. React Router 4 allowed me to do everything I could do with v3, and more. Also, at first, I was over-complicating the use of v4. Once I gained a new mental model for it, I realized that this new direction is amazing!

My intentions for this article aren't to rehash the already well-written documentation for React Router 4. I will cover the most common API concepts, but the real focus is on patterns and strategies that I've found to be successful.

Here are some JavaScript concepts you need to be familiar with for this article:

If you're the type that prefers jumping right to a working demo, here you go:

View Demo

A New API and A New Mental Model

Earlier versions of React Router centralized the routing rules into one place, keeping them separate from layout components. Sure, the router could be partitioned and organized into several files, but conceptually the router was a unit, and basically a glorified configuration file.

Perhaps the best way to see how v4 is different is to write a simple two-page app in each version and compare. The example app has just two routes for a home page and a user's page.

Here it is in v3:

import { Router, Route, IndexRoute } from 'react-router' const PrimaryLayout = props => ( <div className="primary-layout"> <header> Our React Router 3 App </header> <main> {props.children} </main> </div> ) const HomePage =() => <div>Home Page</div> const UsersPage = () => <div>Users Page</div> const App = () => ( <Router history={browserHistory}> <Route path="/" component={PrimaryLayout}> <IndexRoute component={HomePage} /> <Route path="/users" component={UsersPage} /> </Route> </Router> ) render(<App />, document.getElementById('root'))

Here are some key concepts in v3 that are not true in v4 anymore:

  • The router is centralized to one place.
  • Layout and page nesting is derived by the nesting of <Route> components.
  • Layout and page components are completely naive that they are a part of a router.

React Router 4 does not advocate for a centralized router anymore. Instead, routing rules live within the layout and amongst the UI itself. As an example, here's the same application in v4:

import { BrowserRouter, Route } from 'react-router-dom' const PrimaryLayout = () => ( <div className="primary-layout"> <header> Our React Router 4 App </header> <main> <Route path="/" exact component={HomePage} /> <Route path="/users" component={UsersPage} /> </main> </div> ) const HomePage =() => <div>Home Page</div> const UsersPage = () => <div>Users Page</div> const App = () => ( <BrowserRouter> <PrimaryLayout /> </BrowserRouter> ) render(<App />, document.getElementById('root'))

New API Concept: Since our app is meant for the browser, we need to wrap it in <BrowserRouter> which comes from v4. Also notice we import from react-router-dom now (which means we npm install react-router-dom not react-router). Hint! It's called react-router-dom now because there's also a native version.

The first thing that stands out when looking at an app built with React Router v4 is that the "router" seems to be missing. In v3 the router was this giant thing we rendered directly to the DOM which orchestrated our application. Now, besides <BrowserRouter>, the first thing we throw into the DOM is our application itself.

Another v3-staple missing from the v4 example is the use of {props.children} to nest components. This is because in v4, wherever the <Route> component is written is where the sub-component will render to if the route matches.

Inclusive Routing

In the previous example, you may have noticed the exact prop. So what's that all about? V3 routing rules were "exclusive" which meant that only one route would win. V4 routes are "inclusive" by default which means more than one <Route> can match and render at the same time.

In the previous example, we're trying to render either the HomePage or the UsersPage depending on the path. If the exact prop were removed from the example, both the HomePage and UsersPage components would have rendered at the same time when visiting `/users` in the browser.

To understand the matching logic better, review path-to-regexp which is what v4 now uses to determine whether routes match the URL.

To demonstrate how inclusive routing is helpful, let's include a UserMenu in the header, but only if we're in the user's part of our application:

const PrimaryLayout = () => ( <div className="primary-layout"> <header> Our React Router 4 App <Route path="/users" component={UsersMenu} /> </header> <main> <Route path="/" exact component={HomePage} /> <Route path="/users" component={UsersPage} /> </main> </div> )

Now, when the user visits `/users`, both components will render. Something like this was doable in v3 with certain patterns, but it was more difficult. Thanks to v4's inclusive routes, it's now a breeze.

Exclusive Routing

If you need just one route to match in a group, use <Switch> to enable exclusive routing:

const PrimaryLayout = () => ( <div className="primary-layout"> <PrimaryHeader /> <main> <Switch> <Route path="/" exact component={HomePage} /> <Route path="/users/add" component={UserAddPage} /> <Route path="/users" component={UsersPage} /> <Redirect to="/" /> </Switch> </main> </div> )

Only one of the routes in a given <Switch> will render. We still need exact on the HomePage route though if we're going to list it first. Otherwise the home page route would match when visiting paths like `/users` or `/users/add`. In fact, strategic placement is the name-of-the-game when using an exclusive routing strategy (as it always has been with traditional routers). Notice that we strategically place the routes for /users/add before /users to ensure the correct matching. Since the path /users/add would match for `/users` and `/users/add`, putting the /users/add first is best.

Sure, we could put them in any order if we use exact in certain ways, but at least we have options.

The <Redirect> component will always do a browser-redirect if encountered, but when it's in a <Switch> statement, the redirect component only gets rendered if no other routes match first. To see how <Redirect> might be used in a non-switch circumstance, see Authorized Route below.

"Index Routes" and "Not Found"

While there is no more <IndexRoute> in v4, using <Route exact> achieves the same thing. Or if no routes resolved, then use <Switch> with <Redirect> to redirect to a default page with a valid path (as I did with HomePage in the example), or even a not-found page.

Nested Layouts

You're probably starting to anticipate nested sub layouts and how you might achieve them. I didn't think I would struggle with this concept, but I did. React Router v4 gives us a lot of options, which makes it powerful. Options, though, means the freedom to choose strategies that are not ideal. On the surface, nested layouts are trivial, but depending on your choices you may experience friction because of the way you organized the router.

To demonstrate, let's imagine that we want to expand our users section so we have a "browse users" page and a "user profile" page. We also want similar pages for products. Users and products both need sub-layout that are special and unique to each respective section. For example, each might have different navigation tabs. There are a few approaches to solve this, some good and some bad. The first approach is not very good but I want to show you so you don't fall into this trap. The second approach is much better.

For the first, let's modify our PrimaryLayout to accommodate the browsing and profile pages for users and products:

const PrimaryLayout = props => { return ( <div className="primary-layout"> <PrimaryHeader /> <main> <Switch> <Route path="/" exact component={HomePage} /> <Route path="/users" exact component={BrowseUsersPage} /> <Route path="/users/:userId" component={UserProfilePage} /> <Route path="/products" exact component={BrowseProductsPage} /> <Route path="/products/:productId" component={ProductProfilePage} /> <Redirect to="/" /> </Switch> </main> </div> ) }

While this does technically work, taking a closer look at the two user pages starts to reveal the problem:

const BrowseUsersPage = () => ( <div className="user-sub-layout"> <aside> <UserNav /> </aside> <div className="primary-content"> <BrowseUserTable /> </div> </div> ) const UserProfilePage = props => ( <div className="user-sub-layout"> <aside> <UserNav /> </aside> <div className="primary-content"> <UserProfile userId={props.match.params.userId} /> </div> </div> )

New API Concept: props.match is given to any component rendered by <Route>. As you can see, the userId is provided by props.match.params. See more in v4 documentation. Alternatively, if any component needs access to props.match but the component wasn't rendered by a <Route> directly, we can use the withRouter() Higher Order Component.

Each user page not only renders its respective content but also has to be concerned with the sub layout itself (and the sub layout is repeated for each). While this example is small and might seem trivial, repeated code can be a problem in a real application. Not to mention, each time a BrowseUsersPage or UserProfilePage is rendered, it will create a new instance of UserNav which means all of its lifecycle methods start over. Had the navigation tabs required initial network traffic, this would cause unnecessary requests — all because of how we decided to use the router.

Here's a different approach which is better:

const PrimaryLayout = props => { return ( <div className="primary-layout"> <PrimaryHeader /> <main> <Switch> <Route path="/" exact component={HomePage} /> <Route path="/users" component={UserSubLayout} /> <Route path="/products" component={ProductSubLayout} /> <Redirect to="/" /> </Switch> </main> </div> ) }

Instead of four routes corresponding to each of the user's and product's pages, we have two routes for each section's layout instead.

Notice the above routes do not use the exact prop anymore because we want /users to match any route that starts with /users and similarly for products.

With this strategy, it becomes the task of the sub layouts to render additional routes. Here's what the UserSubLayout could look like:

const UserSubLayout = () => ( <div className="user-sub-layout"> <aside> <UserNav /> </aside> <div className="primary-content"> <Switch> <Route path="/users" exact component={BrowseUsersPage} /> <Route path="/users/:userId" component={UserProfilePage} /> </Switch> </div> </div> )

The most obvious win in the new strategy is that the layout isn't repeated among all the user pages. It's a double win too because it won't have the same lifecycle problems as with the first example.

One thing to notice is that even though we're deeply nested in our layout structure, the routes still need to identify their full path in order to match. To save yourself the repetitive typing (and in case you decide to change the word "users" to something else), use props.match.path instead:

const UserSubLayout = props => ( <div className="user-sub-layout"> <aside> <UserNav /> </aside> <div className="primary-content"> <Switch> <Route path={props.match.path} exact component={BrowseUsersPage} /> <Route path={`${props.match.path}/:userId`} component={UserProfilePage} /> </Switch> </div> </div> ) Match

As we've seen so far, props.match is useful for knowing what userId the profile is rendering and also for writing our routes. The match object gives us several properties including match.params, match.path, match.url and several more.

match.path vs match.url

The differences between these two can seem unclear at first. Console logging them can sometimes reveal the same output making their differences even more unclear. For example, both these console logs will output the same value when the browser path is `/users`:

const UserSubLayout = ({ match }) => { console.log(match.url) // output: "/users" console.log(match.path) // output: "/users" return ( <div className="user-sub-layout"> <aside> <UserNav /> </aside> <div className="primary-content"> <Switch> <Route path={match.path} exact component={BrowseUsersPage} /> <Route path={`${match.path}/:userId`} component={UserProfilePage} /> </Switch> </div> </div> ) }

ES2015 Concept: match is being destructured at the parameter level of the component function. This means we can type match.path instead of props.match.path.

While we can't see the difference yet, match.url is the actual path in the browser URL and match.path is the path written for the router. This is why they are the same, at least so far. However, if we did the same console logs one level deeper in UserProfilePage and visit `/users/5` in the browser, match.url would be "/users/5" and match.path would be "/users/:userId".

Which to choose?

If you're going to use one of these to help build your route paths, I urge you to choose match.path. Using match.url to build route paths will eventually lead a scenario that you don't want. Here's a scenario which happened to me. Inside a component like UserProfilePage (which is rendered when the user visits `/users/5`), I rendered sub components like these:

const UserComments = ({ match }) => ( <div>UserId: {match.params.userId}</div> ) const UserSettings = ({ match }) => ( <div>UserId: {match.params.userId}</div> ) const UserProfilePage = ({ match }) => ( <div> User Profile: <Route path={`${match.url}/comments`} component={UserComments} /> <Route path={`${match.path}/settings`} component={UserSettings} /> </div> )

To illustrate the problem, I'm rendering two sub components with one route path being made from match.url and one from match.path. Here's what happens when visiting these pages in the browser:

  • Visiting `/users/5/comments` renders "UserId: undefined".
  • Visiting `/users/5/settings` renders "UserId: 5".

So why does match.path work for helping to build our paths and match.url doesn't? The answer lies in the fact that {${match.url}/comments} is basically the same thing as if I had hard-coded {'/users/5/comments'}. Doing this means the subsequent component won't be able to fill match.params correctly because there were no params in the path, only a hardcoded 5.

It wasn't until later that I saw this part of the documentation and realized how important it was:


  • path - (string) The path pattern used to match. Useful for building nested <Route>s
  • url - (string) The matched portion of the URL. Useful for building nested <Link>s
Avoiding Match Collisions

Let's assume the app we're making is a dashboard so we want to be able to add and edit users by visiting `/users/add` and `/users/5/edit`. But with the previous examples, users/:userId already points to a UserProfilePage. So does that mean that the route with users/:userId now needs to point to yet another sub-sub-layout to accomodate editing and the profile? I don't think so. Since both the edit and profile pages share the same user-sub-layout, this strategy works out fine:

const UserSubLayout = ({ match }) => ( <div className="user-sub-layout"> <aside> <UserNav /> </aside> <div className="primary-content"> <Switch> <Route exact path={props.match.path} component={BrowseUsersPage} /> <Route path={`${match.path}/add`} component={AddUserPage} /> <Route path={`${match.path}/:userId/edit`} component={EditUserPage} /> <Route path={`${match.path}/:userId`} component={UserProfilePage} /> </Switch> </div> </div> )

Notice that the add and edit routes strategically come before the profile route to ensure there the proper matching. Had the profile path been first, visiting `/users/add` would have matched the profile (because "add" would have matched the :userId.

Alternatively, we can put the profile route first if we make the path ${match.path}/:userId(\\d+) which ensures that :userId must be a number. Then visiting `/users/add` wouldn't create a conflict. I learned this trick in the docs for path-to-regexp.

Authorized Route

It's very common in applications to restrict the user's ability to visit certain routes depending on their login status. Also common is to have a "look-and-feel" for the unauthorized pages (like "log in" and "forgot password") vs the "look-and-feel" for the authorized ones (the main part of the application). To solve each of these needs, consider this main entry point to an application:

class App extends React.Component { render() { return ( <Provider store={store}> <BrowserRouter> <Switch> <Route path="/auth" component={UnauthorizedLayout} /> <AuthorizedRoute path="/app" component={PrimaryLayout} /> </Switch> </BrowserRouter> </Provider> ) } }

Using react-redux works very similarly with React Router v4 as it did before, simply wrap <BrowserRouter> in <Provider> and it's all set.

There are a few takeaways with this approach. The first being that I'm choosing between two top-level layouts depending on which section of the application we're in. Visiting paths like `/auth/login` or `/auth/forgot-password` will utilize the UnauthorizedLayout — one that looks appropriate for those contexts. When the user is logged in, we'll ensure all paths have an `/app` prefix which uses AuthorizedRoute to determine if the user is logged in or not. If the user tries to visit a page starting with `/app` and they aren't logged in, they will be redirected to the login page.

AuthorizedRoute isn't a part of v4 though. I made it myself with the help of v4 docs. One amazing new feature in v4 is the ability to create your own routes for specialized purposes. Instead of passing a component prop into <Route>, pass a render callback instead:

class AuthorizedRoute extends React.Component { componentWillMount() { getLoggedUser() } render() { const { component: Component, pending, logged, ...rest } = this.props return ( <Route {...rest} render={props => { if (pending) return <div>Loading...</div> return logged ? <Component {...props} /> : <Redirect to="/auth/login" /> }} /> ) } } const stateToProps = ({ loggedUserState }) => ({ pending: loggedUserState.pending, logged: loggedUserState.logged }) export default connect(stateToProps)(AuthorizedRoute)

While your login strategy might differ from mine, I use a network request to getLoggedUser() and plug pending and logged into Redux state. pending just means the request is still in route.

Click here to see a fully working Authentication Example at CodePen.

Other mentions

There's a lot of other cool aspects React Router v4. To wrap up though, let's be sure to mention a few small things so they don't catch you off guard.

<Link> vs <NavLink>

In v4, there are two ways to integrate an anchor tag with the router: <Link> and <NavLink>

<NavLink> works the same as <Link> but gives you some extra styling abilities depending on if the <NavLink> matches the browser's URL. For instance, in the example application, there is a <PrimaryHeader> component that looks like this:

const PrimaryHeader = () => ( <header className="primary-header"> <h1>Welcome to our app!</h1> <nav> <NavLink to="/app" exact activeClassName="active">Home</NavLink> <NavLink to="/app/users" activeClassName="active">Users</NavLink> <NavLink to="/app/products" activeClassName="active">Products</NavLink> </nav> </header> )

The use of <NavLink> allows me to set a class of active to whichever link is active. But also, notice that I can use exact on these as well. Without exact the home page link would be active when visiting `/app/users` because of the inclusive matching strategies of v4. In my personal experiences, <NavLink> with the option of exact is a lot more stable than the v3 <Link> equivalent.

URL Query Strings

There is no longer way to get the query-string of a URL from React Router v4. It seems to me that the decision was made because there is no standard for how to deal with complex query strings. So instead of v4 baking an opinion into the module, they decided to just let the developer choose how to deal with query strings. This is a good thing.

Personally, I use query-string which is made by the always awesome sindresorhus.

Dynamic Routes

One of the best parts about v4 is that almost everything (including <Route>) is just a React component. Routes aren't magical things anymore. We can render them conditionally whenever we want. Imagine an entire section of your application is available to route to when certain conditions are met. When those conditions aren't met, we can remove routes. We can even do some crazy cool recursive route stuff.

React Router 4 is easier because it's Just Components™

All About React Router 4 is a post from CSS-Tricks

How We Solve CSS Versioning Conflicts Here at New Relic

Fri, 08/04/2017 - 14:09

At first the title made me think of Git conflicts, but that's not what this is about. It's about namespacing selectors for components. Ultimately, they decided to use a Webpack loader (not open source, it doesn't appear) to prefix every single class with a hashed string representing the version. I guess that must happen in both the HTML and CSS so they match. Lots of folks landing on style-scoping in one way or another to solve their problems.

It makes me think about another smaller-in-scope issue. Say you have an alternate version of a header that you're going to send to 5% of your users. It has different HTML and CSS. Easy enough to send different HTML to users from the server. But CSS tends to be bundled, and it seems slightly impractical to make an entirely different CSS bundle for a handful of lines of CSS. One solution: add an additional attribute to the new header and ship the new CSS with artificially-boosted specificity to avoid all the old CSS. Then when you go live, remove the new attribute from both.

.header[new] { }

Direct Link to ArticlePermalink

How We Solve CSS Versioning Conflicts Here at New Relic is a post from CSS-Tricks

IntersectionObserver comes to Firefox

Fri, 08/04/2017 - 13:46

A great intro by Dan Callahan on why IntersectionObserver is so damn useful:

What do infinite scrolling, lazy loading, and online advertisements all have in common?

They need to know about—and react to—the visibility of elements on a page!

Unfortunately, knowing whether or not an element is visible has traditionally been difficult on the Web. Most solutions listen for scroll and resize events, then use DOM APIs like getBoundingClientRect() to manually calculate where elements are relative to the viewport. This usually works, but it's inefficient and doesn't take into account other ways in which an element's visibility can change, such as a large image finally loading higher up on the page, which pushes everything else downward.

The API is deliciously simple.

Direct Link to ArticlePermalink

IntersectionObserver comes to Firefox is a post from CSS-Tricks

Creating Photorealistic 3D Graphics on the Web

Fri, 08/04/2017 - 13:40

Before becoming a web developer, I worked in the visual effects industry, creating award-winning, high-end 3D effects for movies and TV Shows such as Tron, The Thing, Resident Evil, and Vikings. To be able to create these effects, we would need to use highly sophisticated animation software such as Maya, 3Ds Max or Houdini and do long hours of offline rendering on Render Farms that consisted of hundreds of machines. It's because I worked with these tools for so long that I am now amazed by the state of the current web technology. We can now create and display high-quality 3D content right inside the web browser, in real time, using WebGL and Three.js.

Here is an example of a project that is built using these technologies. You can find more projects that use three.js on their website.

Some projects using three.js

As the examples on the three.js website demonstrate, 3D visualizations have a vast potential in the domains of e-commerce, retail, entertainment, and advertisement.

WebGL is a low-level JavaScript API that enables creation and display of 3D content inside the browser using the GPU. Unfortunately, since WebGL is a low-level API, it can be a bit hard and tedious to use. You need to write hundreds of lines of code to perform even the simplest tasks. Three.js, on the other hand, is an open source JavaScript library that abstracts away the complexity of WebGL and allows you to create real-time 3D content in a much easier manner.

In this tutorial, I will be introducing the basics of the three.js library. It makes sense to start with a simple example to communicate the fundamentals better when introducing a new programming library but I would like to take this a step further. I will also aim to build a scene that is aesthetically pleasant and even photorealistic to a degree.

We will just start out with a simple plane and sphere but in the end it will end up looking like this:

See the Pen learning-threejs-final by Engin Arslan (@enginarslan) on CodePen.

Photorealism is the pinnacle of computer graphics but achieving is not necessarily a factor of the processing power at your disposal but a smart deployment of techniques from your toolbox. Here are a few techniques that you will be learning about in this tutorial that will help your scenes achieve photo-realism.

  • Color, Bump and Roughness Maps.
  • Physically Based Materials.
  • Lighting with Shadows.
Photorealistic 3D portrait by Ian Spriggs

The basic 3D principles and techniques that you will learn here are relevant in any other 3D content creation environment whether it is Blender, Unity, Maya or 3Ds Max.

This is going to be a long tutorial. If you are more of a video person or would like to learn more about the capabilities of three.js you should check out my video training on the subject from Lynda.com.


When using three.js, if you are working locally, it helps to serve the HTML file through a local server to be able to load in scene assets such as external 3D geometry, images, etc. If you are looking for a server that is easy to setup, you can use Python to spin up a simple HTTP Server. Python is pre-installed on many operating systems.

You don't have to worry about setting a local dev server to follow this tutorial though. You will instead rely on data URL's to load in assets like images to remove the overhead of setting up a server. Using this method you will be able to easily execute your three.js scene in online code editors such as CodePen.

This tutorial assumes a prior, basic to intermediate, knowledge of JavaScript and some understanding of front-end web development. If you are not comfortable with JavaScript but want to get started with it in an easy manner you might want to check out the course/book "Coding for Visual Learners: Learning JavaScript with p5.js". (Disclaimer: I am the author)

Let's get started with building 3D graphics on the Web!

Getting Started

I have already prepared a Pen that you can use to follow this tutorial with.

The HTML code that you will be using is going to be super simple. It just needs to have a div element to host the canvas that is going the display the 3D graphics. It also loads up the three.js library (release 86) from a CDN.

<div id="webgl"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/86/three.min.js"></script>

Codepen hides some of the HTML structure that is currently present for your convenience. If you were building this scene on some other online editors or on your local your HTML would need to have something like this code below where main.js would be the file that would hold the JavaScript code.

<!DOCTYPE html> <html> <head> <title>Three.js</title> <style type="text/css"> html, body { margin: 0; padding: 0; overflow: hidden; } </style> </head> <body> <div id="webgl"></div> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/86/three.min.js"></script> <script src="./main.js"></script> </body> </html>

Notice the simple CSS declaration inside the HTML. This is what you would have in the CSS tab of Codepen:

html, body { margin: 0; padding: 0; overflow: hidden; }

This is to ensure that you don't have any margin and padding values that might be applied by your browser and you don't get a scrollbar so that you can have the graphics fill the entire screen. This is all we need to get started with building 3D Graphics.

Part 1 - Three.js Scene Basics

When working with three.js and with 3D in general, there are a couple of required objects you need to have. These objects are scene, camera and the renderer.

First, you should create a scene. You can think of a scene object as a container for every other 3D object that you are going to work with. It represents the 3D world that you will be building. You can create the scene object by doing this:

var scene = new THREE.Scene();

Another thing that you need to have when working with 3D is the camera. Think of camera like the eyes that you will be viewing this 3D world through. When working with a 2D visualization, the concept of a camera usually doesn't exist. What you see is what you get. But in 3D, you need a camera to define your point of view as there are many positions and angles that you could be looking at a scene from. A camera doesn't only define a position but also other information like the field of view or the aspect ratio.

var camera = new THREE.PerspectiveCamera( 45, // field of view window.innerWidth / window.innerHeight, // aspect ratio 1, // near clipping plane (beyond which nothing is visible) 1000 // far clipping plane (beyond which nothing is visible) );

The camera captures the scene for display purposes but for us to actually see anything, the 3D data needs to be converted into a 2D image. This process is called rendering and you need a renderer to render the scene in three.js. You can initialize a renderer like this:

var renderer = new THREE.WebGLRenderer();

And then set the size of the renderer. This will dictate the size of the output image. You will make it cover the window size.

renderer.setSize(window.innerWidth, window.innerHeight);

To be able to display the results of the render you need to append the domElement property of the renderer to your HTML content. You will use the empty div element that you created that has the id webgl for this purpose.


And having done all this you can call the render method on the renderer by providing the scene and the camera as the arguments.

renderer.render( scene, camera );

To have things a bit tidier, put everything inside a function called init and execute that function.


And now you would see nothing... but a black screen. Don't worry, this is normal. The scene is working but since you didn't include any objects inside the scene, what you are looking at is basically empty space. Next, you will be populating this scene with 3D objects.

See the Pen learning-threejs-01 by Engin Arslan (@enginarslan) on CodePen.

Adding Objects to the Scene

Geometric objects in three.js are made up of two parts. A geometry that defines the shape of the object and a material that defines the surface quality, the appearance, of the object. The combination of these two things makes up a mesh in three.js which forms the 3D object.

Three.js allows you to create some simple shapes like a cube or a sphere in an easy manner. You can create a simple sphere by providing the radius value.

var geo = new THREE.SphereGeometry(1);

There are various kinds of materials that you could use on geometries. Materials determine how an object reacts to the scene lighting. We can use a material to make an object reflective, rough, transparent, etc.. The default material that three.js objects are created with is the MeshBasicMaterial. MeshBasicMaterial is not affected by the scene lighting at all. This means that your geometry is going to be visible even when there is no lighting in the scene. You can pass an object with a color property and a hex value to the MeshBasicMaterial to be able to set the desired color for the object. You will use this material for now but later update it to have your objects be affected by the scene lighting. You don't have any lighting in the scene for now so MeshBasicMaterial should be a good enough choice.

var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });

You can combine the geometry and material to create a mesh which is going to form the 3D object.

var mesh = new THREE.Mesh(geometry, material);

Create a function to encapsulate this code that creates a sphere. You won't be creating more than one sphere in this tutorial but it is still good to keep things neat and tidy.

function getSphere(radius) { var geometry = new THREE.SphereGeometry(radius); var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); var sphere = new THREE.Mesh(geometry, material); return sphere; } var sphere = getSphere(1);

Then you need to add this newly created object to the scene for it to be visible.


Let's check out the scene again. You will still see a black screen.

See the Pen learning-threejs-02 by Engin Arslan (@enginarslan) on CodePen.

The reason why you don't see anything right now is that whenever you add an object to the scene in three.js, the object gets placed at the center of the scene, at the coordinates of 0, 0, 0 for x, y and z. This simply means that you currently have the camera and the sphere at the same position. You should change the position of either one of them to be able to start seeing things.

3D coordinates

Let's move the camera 20 units on the z axis. This is achieved by setting the position.z property on the camera. 3D objects have position, rotation and scale properties that would allow you to transform them into the 3D space.

camera.position.z = 20;

You could move the camera on other axises as well.

camera.position.x = 0; camera.position.y = 5; camera.position.z = 20;

The camera is positioned higher now but the sphere is not at the center of the frame anymore. You need to point the camera to it. To be able to do so, you can call a method on the camera called lookAt. The lookAt method on the camera determines which point the camera is looking at. The points in the 3D space are represented by Vectors. So you can pass a new Vector3 object to this lookAt method to be able to have the camera look at the 0, 0, 0 coordinates.

camera.lookAt(new THREE.Vector3(0, 0, 0));

The sphere object doesn't look too smooth right now. The reason for that is the SphereGeometry function actually accepts two additional parameters, the width and height segments, that affects the resolution of the surface. Higher these values, smoother the curved surfaces will appear. I will set this value to be 24 for width and height segments.

var geo = new THREE.SphereGeometry(radius, 24, 24);

See the Pen learning-threejs-03 by Engin Arslan (@enginarslan) on CodePen.

Now you will create a simple plane geometry for the sphere to be sitting on. PlaneGeometry function requires a width and height parameter. In 3D, 2D objects don't have both of their sides rendering by default so you need to pass a side property to the material to have both sides of the plane geometry to render.

function getPlane(w, h) { var geo = new THREE.PlaneGeometry(w, h); var material = new THREE.MeshBasicMaterial({ color: 0x00ff00, side: THREE.DoubleSide, }); var mesh = new THREE.Mesh(geo, material); return mesh; }

You can now add this plane object to the scene as well. You will notice that the initial rotation of the plane geometry is parallel to the y-axis but you will likely need it to be horizontal for it to act as a ground plane. There is one important thing you should keep in mind regarding the rotations in three.js though. They use radians as a unit, not degrees. A rotation of 90 degrees in radians is equivalent to Math.PI/2.

var plane = getPlane(50, 50); scene.add(plane); plane.rotation.x = Math.PI/2;

When you created the sphere object, it got positioned using its center point. If you would like to move it above the ground plane then you can just increase its position.y value by the current radius amount. But that wouldn't be a programmatic way of doing things. If you would like the sphere to stay on the plane whatever its radius value is, you should make use of the radius value for the positioning.

sphere.position.y = sphere.geometry.parameters.radius;

See the Pen learning-threejs-04 by Engin Arslan (@enginarslan) on CodePen.


You are almost done with the first part of this tutorial. But before we wrap it up, I want to illustrate how to do animations in three.js. Animations in three.js make use of the requestAnimationFrame method on the window object which repeatedly executes a given function. It is somewhat like a setInterval function but optimized for the browser drawing performance.

Create an update function and pass the renderer, scene, and camera in there to execute the render method of the renderer inside this function. You will also declare a requestAnimationFrame function inside there and call this update function recursively from a callback function that is passed to the requestAnimationFrame function. It is better to illustrate this in code than to write about it.

function update(renderer, scene, camera) { renderer.render(scene, camera); requestAnimationFrame(function() { update(renderer, scene, camera); }); }

Everything might look same to you at this point but the core difference is that the requestAnimationFrame function is making the scene render around 60 frames per second with a recursive call to the update function. Which means that if you are to execute a statement inside the update function, that statement would get executed at around 60 times per second. Let's add a scaling animation to the sphere object. To be able to select the sphere object from inside the update function you could pass it as an argument but we will use a different technique. First, set a name attribute on the sphere object and give it a name of your liking.

sphere.name = 'sphere';

Inside the update function, you could find this object using its name by using the getObjectByName method on its parent object, the scene.

var sphere = scene.getObjectByName('sphere'); sphere.scale.x += 0.01; sphere.scale.z += 0.01;

With this code, the sphere is now scaling on its x and z axises. Our intention is not to create a scaling sphere though. We are setting up the update function so that you can leverage for different animations later on. Now that you have seen how it works you can remove this scaling animation.

See the Pen learning-threejs-05 by Engin Arslan (@enginarslan) on CodePen.

Part 2 - Adding Realism to the Scene

Currently, we are using MeshBasicMaterial which displays the given color even when there is no lighting in the scene which results in a very flat look. Real-world materials don't work this way though. The visibility of the surface in the real world depends on how much light is reflecting back from the surface back to our eyes. Three.js comes with a couple of different materials that provide a better approximation of how real-world surfaces behave and one of them is the MeshStandardMaterial. MeshStandardMaterial is a physically based rendering material that can help you achieve photorealistic results. This is the kind of material that modern game engines like Unreal or Unity use and is an industry standard in gaming and visual effects.

Let's start using the MeshStandardMaterial on our objects and change the color of the materials to white.

var material = new THREE.MeshStandardMaterial({ color: 0xffffff, });

You will once again get a black render at this point. That is normal. For objects to be visible we need to have lights in the scene. This wasn't a requirement with MeshBasicMaterial as it is a simple material that displays the given color at all conditions but other materials require an interaction with light to be visible. Let's create a SpotLight creating function. You will be creating two spotlights using this function.

function getSpotLight(color, intensity) { var light = new THREE.SpotLight(color, intensity); return light; } var spotLight_01 = getSpotlight(0xffffff, 1); scene.add(spotLight_01);

You might start seeing something at this point. Position the light and the camera a bit differently for a better framing and shading. Also create a secondary light as well.

var spotLight_02 = getSpotlight(0xffffff, 1); scene.add(spotLight_02); camera.position.x = 0; camera.position.y = 6; camera.position.z = 6; spotLight_01.position.x = 6; spotLight_01.position.y = 8; spotLight_01.position.z = -20; spotLight_02.position.x = -12; spotLight_02.position.y = 6; spotLight_02.position.z = -10;

Having done this you have two light sources in the scene, illuminating the sphere from two different positions. The lighting is helping a bit in understanding the dimensionality of the scene, but things are still looking extremely fake at this point because the lighting is missing a critical component: the shadows!

Rendering a shadow in Three.js is unfortunately not too straightforward. This is because shadows are computationally expensive and we need to activate shadow rendering on multiple places. First, you need to tell the renderer to start rendering shadows:

var renderer = new THREE.WebGLRenderer(); renderer.shadowMap.enabled = true;

Then you need to tell the light to cast shadows. Do that in the getSpotLight function.

light.castShadow = true;

You should also tell the objects to cast and/or receive shadows. In this case, you will make the sphere cast shadows and the plane to receive shadows.

mesh.castShadow = true; mesh.receiveShadow = true;

After all these settings we should start seeing shadows in the scene. Initially, they might be a bit lower quality. You can increase the resolution of the shadows by setting the light shadow map size.

light.shadow.mapSize.x = 4096; light.shadow.mapSize.y = 4096;

MeshStandardMaterial has a couple of properties such as the roughness and metalness that controls the interaction of the surface with the light. The properties take values in between 0 and 1 and they control the corresponding behavior of the surface. Increase the roughness value on the plane material to 1 to see the surface look more like a rubber as the reflections get blurrier.

// material adjustments var planeMaterial = plane.material; planeMaterial.roughness = 1;

We won't be using 1 as a value in this tutorial though. Feel free to experiment with values but set it back to 0.65 for roughness and 0.75 for metalness.

planeMaterial.roughness = 0.65; planeMaterial.metalness = 0.75;

Even though the scene should be looking much more promising right now it is still hard to call it realistic. The truth is, it is very hard to establish photorealism in 3D without using texture maps.

See the Pen learning-threejs-06 by Engin Arslan (@enginarslan) on CodePen.

Texture Maps

Texture maps are 2D images that can be mapped on a material for the purpose of providing surface detail. So far you were only getting solid colors on the surfaces but using a texture map you can map any image you would like on a surface. Texture maps are not only used to manipulate the color information of surfaces but they can also be used to manipulate other qualities of the surface like reflectiveness, shininess, roughness, etc.

Textures can be derived from photographic sources or can also be painted from scratch as well. For a texture to be useful in a 3D context it should be captured in a certain manner. Images that have reflections or shadows in them, or images where the perspective is too distorted wouldn't make great texture maps. There are several dedicated websites for finding textures online. One of them is textures.com which has a pretty good archive. They have some free download options but requires you to register to be able to do so. Another website for 3D textures is Megascans which does high resolution, high-quality environment scans that are of high-end production quality.

I have used a website called mb3d.co.uk for this example. This site provides seamless, free to use textures. A seamless texture implies a texture that can be repeated on the surface many times without having any discontinuations where the edges meet. This is the link to the texture file that I have used. I have decreased the size to 512px for width and height and converted the image file to data URI using an online service called ezgif to be able to include it as part of the JavaScript code as opposed to loading it in as a separate asset. (hint: don't include tags as you are outputting the data if you are to use this service)

Create a function that returns the data URI we have generated so that we don't have to put that huge string in the middle of our code.

function getTexture() { var data = 'data:image/jpeg;base64,/...'; // paste your data URI inside the quotation marks. return data }

Next, you need to load in the texture and apply it on the plane surface. You will be using the three.js TextureLoader for this purpose. After loading in the texture you will load in the texture to the map property of the desired material to have it as a color map on the surface.

var textureLoader = new THREE.TextureLoader(); var texture = textureLoader.load(getTexture()); planeMaterial.map = texture;

Things would be looking rather ugly right now as the texture on the surface is pixelated. The image is stretching too much to cover the entire surface. What you can do is to make the image repeat itself instead of scaling so that it doesn't get as pixelated. To do so, you need to set the wrapS and wrapT properties on the desired map to THREE.RepeatWrapping and specify a repetition value. Since you will be doing this for other kinds of maps as well (like bump or roughness map) it is better to create a loop for this:

var repetition = 6; var textures = ['map']// we will add 'bumpMap' and 'roughnessMap' textures.forEach((mapName) => { planeMaterial[mapName].wrapS = THREE.RepeatWrapping; planeMaterial[mapName].wrapT = THREE.RepeatWrapping; planeMaterial[mapName].repeat.set(repetition, repetition); });

This should look much better. Since the texture you are using is seamless you wouldn't notice any disconnections around the edges where the repetition happens.

Loading of a texture is actually an asynchronous operation. This means that your 3D scene is generated before the image file is loaded in. But since you are continuously rendering the scene using requestAnimationFrame this doesn't cause any issues in this example. If you weren't doing this, you would need to use callbacks or other async methods to manage the loading order.

See the Pen learning-threejs-07 by Engin Arslan (@enginarslan) on CodePen.

Other Texture Maps

As mentioned in the previous chapter, textures are not only used to define the color of the surfaces but to define other qualities of it as well. One other way that textures can be used as are bump maps. When used as a bump map, the brightness values of the texture simulates a height effect.

planeMaterial.bumpMap = texture;

Bump map should also be using the same repetition configuration as the color map so include it in the textures array.

var textures = ['map', 'bumpMap'];

With a bump map, brighter the value of a pixel, higher the corresponding surface would look. But a bump map doesn't actually change the surface, it just manipulates how the light interacts with the surface to create an illusion of uneven topology. The bump amount looks a bit too much right now. Bump maps work best when they are used in subtle amounts. So let's change the bumpScale parameter to something lower for a more subtle effect.

planeMaterial.bumpScale = 0.01;

Notice how this texture made a huge difference in appearance. The reflections are not perfect anymore but nicely broken up as they would be in real life. Another kind of map slot that is available to the StandardMaterial is the roughness map. A texture map used as a roughness map allows you to control the sharpness of the reflections using the brightness values of a given image.

planeMaterial.roughnessMap = texture; var textures = ['map', 'bumpMap', 'roughnessMap'];

According to the three.js documentation, the StandardMaterial works best when used in conjunction with an environment map. An environment map simulates a distant environment reflecting off of the reflective surfaces in the scene. It really helps when you are trying to simulate reflectivity on objects. Environment maps in three.js are in the form of cube maps. A Cube map is a panoramic view of a scene that is mapped inside a cube. A cube map is made up of 6 separate images that correspond to each face of a cube. Since loading 6 mode images inside an online editor is going to be a bit too much work you won't actually be using an environment map in this example. But to be able to make this sphere object a bit more interesting, add a roughness map to it as well. You will be using this texture but 320x320px in size and as a data URI.

Create a new function called getMetalTexture

function getMetalTexture() { var data = 'data:image/jpeg;base64,/...'; // paste your data URI inside the quotation marks. return data }

And apply it on the sphere material as bumpMap and roughnessMap:

var sphereMaterial = sphere.material; var metalTexture = textureLoader.load(getMetalTexture()); sphereMaterial.bumpMap = metalTexture; sphereMaterial.roughnessMap = metalTexture; sphereMaterial.bumpScale = 0.01; sphereMaterial.roughness = 0.75; sphereMaterial.metalness = 0.25;

See the Pen learning-threejs-08 by Engin Arslan (@enginarslan) on CodePen.

Wrapping it up!

You are almost done! Here you will do just a couple of small tweaks. You can see the final version of this scene file in this Pen.

Provide a non-white color to the lights. Notice how you can actually use CSS color values as strings to specify color:

var spotLight_01 = getSpotlight('rgb(145, 200, 255)', 1); var spotLight_02 = getSpotlight('rgb(255, 220, 180)', 1);

And add some subtle random flickering animation to the lights to add some life to the scene. First, assign a name property to the lights so you can locate them inside the update function using the getObjectByName method.

spotLight_01.name = 'spotLight_01'; spotLight_02.name = 'spotLight_02';

And then create the animation inside the update function using the Math.random() function.

var spotLight_01 = scene.getObjectByName('spotLight_01'); spotLight_01.intensity += (Math.random() - 0.5) * 0.15; spotLight_01.intensity = Math.abs(spotLight_01.intensity); var spotLight_02 = scene.getObjectByName('spotLight_02'); spotLight_02.intensity += (Math.random() - 0.5) * 0.05; spotLight_02.intensity = Math.abs(spotLight_02.intensity);

And as a bonus, inside the scene file, I have included the OrbitControls script for the three.js camera which means that you can actually drag your mouse on the scene to interact with the camera! I have also made it so that the scene resizes with the changing window size. I have achieved this using an external script for convenience.

See the Pen learning-threejs-final by Engin Arslan (@enginarslan) on CodePen.

Now, this scene is somewhat close to becoming photorealistic. There are still many missing pieces though. The sphere ball is too dark due to lack of reflections and ambient lighting. The ground plane is looking too flat in the glancing angles. The profile of the sphere is too perfect - it is CG (Computer Graphics) perfect. The lighting is not actually as realistic as it could be; It doesn't decay (lose intensity) with the distance from the source. You should also probably add particle effects, camera animation, and post-processing filters if you want to go all the way with this. But this still should be a good enough example to illustrate the power of three.js and the quality of graphics that you can create inside the browser. For more information on what you could achieve using this amazing library, you should definitely check out my new course on Lynda.com about the subject!

Thanks for making it this far! Hope you enjoyed this write-up and feel free to reach to me @inspiratory on Twitter or on my website with any questions you might have!

Creating Photorealistic 3D Graphics on the Web is a post from CSS-Tricks

Integrate Your Wufoo Forms Everywhere

Thu, 08/03/2017 - 15:22

At its heart, Wufoo is a form builder. If you need any type of form, you can build it super quickly by selecting and customizing the fields you need in Wufoo's fantastically easy to use form builder. I can hardly imagine a more useful web app for web designers and developers.

But what is a form, at its essence? Just a means to collect data. The important part is what you do with that data. You can do all the obvious stuff. You can have entries emailed to you. You can build reports from the data. You can explore the data inside Wufoo, or use the API to access the data outside of Wufoo.

Those things are just the tip of the iceberg of what you can do with data you collect with your Wufoo forms. There are built-in integrations! For example, say you have a form that includes an email address field, and you'd like to ship that email address over to MailChimp or Campaign Monitor into a particular mailing list. That's just a few clicks away. Or say the form has some element of lead generation and you want to send the details to Salesforce. Or you want to tweet data from the form upon submission. Same deal, just a few clicks.

One of my favorites is that Wufoo works tremendously well with Zapier. That's the whole point of Zapier, you can use it to connect services together! For example, the Ask a Question form over on the ShopTalk website not only emails Dave and I but adds the question to a Trello board for us to organize into shows. We could easily have it integrate into Evernote, dump into Google Sheets, or work with any of hundreds of other services. Wufoo is such a great source of data for integrations, it begs for playing with.

Direct Link to ArticlePermalink

Integrate Your Wufoo Forms Everywhere is a post from CSS-Tricks

If you really dislike FOUT, `font-display: optional` might be your jam

Thu, 08/03/2017 - 15:13

The story of FOUT is so fascinating. Browsers used to do it: show a "fallback" font while a custom font loads, then flop out the text once it has. The industry kinda hated it, because it felt jerky and could cause re-layout. So browsers changed and started hiding text until the custom font loaded. The industry hated that even more. Nothing worse than a page with no text at all!

Font loading got wicked complicated. Check out this video of Zach Leatherman and I talking it out.

Now browsers are saying, why don't we give control back to you in the form of API's and CSS. You can take control of the behavior with the font-display property (spec).

It seems like font-display: swap; gets most of the attention. It's for good reason. That's the value that brings back FOUT in the strongest way. The browser will not wait at all for an unloaded font. It will show text immediately in the best-matching-and-available font in the stack, then if/when a higher-matching font loads, it will "swap" to that.

@font-face { font-family: Merriweather; src: url(/path/to/fonts/Merriweather.woff) format('woff'); font-weight: 400; font-style: normal; font-display: swap; } body { font-family: Merriweather, /* Use this if it's immediately available, or swap to it if it gets downloaded within a few seconds */ Georgia, /* Use this if Merriweather isn't downloaded yet. */ serif; /* Bottom of the stack. System doesn't have Georgia. */ }

The people wanted their FOUT back, they got it. Well, as soon as font-display is supported in their browser, anyway. Right now we're looking at Chrome 60+ as the only browser shipping it (which means it won't be long for the rest of the Blink clan). It's behind a flag in Firefox already, so that's a good sign.

But what if you don't particularly like FOUT?

One option there is font-display: fallback;. It's slightly weirdly named, as it's a lot like the default behavior (auto or block). The difference is that it has a really short waiting period ("font block period"), ~100ms, where nothing is shown if the font isn't ready to go in that super short period, a fallback will be shown instead. Then the font has ~3s to get loaded and it will swap in, otherwise, it never will.

That seems pretty reasonable. What you're preventing there is a late-term swap, which is when it's the most awkward. Still that risk of FOUT though.

If you'd prefer that if the web font isn't immediately available, to just show the fallback font and not ever swap to it, even after it's downloaded. You can! That's what font-display: optional; does. It still gives the ~100ms font block period (giving the font a fighting chance to show up on first page view), but after that, the fallback is shown and will not swap. Chances are, the font did ultimately get downloaded, and next page view it will be cached and used.

This is font-display: optional; in Chrome 60. With a clean cache, the page loads with the fallback font. The font is downloaded, but not used. Then with the cache primed, the second page load uses the font.

I'm fairly open minded here. I can see how font-display: swap; is ideal for the best accessibility of content. I'm no big fan of FOUT, so I can see the appeal of font-display: optional;. I can also see how font-display: fallback; kinda splits the middle.

Aside from the browser support being vital in making use of this, there is also the matter of web font providers supporting it. For example, when using Google Fonts default font loading methods, you don't have an opportunity to use font-display because the @font-face blocks come from the Google-hosted stylesheets. There is an open discussion on that. There are ways to use Google Fonts with your own @font-face blocks though. Definitely consult Zach Leatherman's guide.

If you really dislike FOUT, `font-display: optional` might be your jam is a post from CSS-Tricks

Separate Form Submit Buttons That Go To Different URLs

Wed, 08/02/2017 - 16:01

This came up the other day. I forget where, but I jotted it down in my little notepad for blog post ideas. I wrote it down because what I was overhearing was way over-complicating things.

Say you have a form like this:

<form action="/submit"> <!-- inputs and stuff --> <input type="submit" value="Submit"> </form>

When you submit that form, it's going to go to the URL `/submit`. Say you need another submit button that submits to a different URL. It doesn't matter why. There is always a reason for things. The web is a big place and all that.

I web searched around for other ways people have tried handling this.

One way was to give up on submitting to different URL's, but give each submit button a shared name but different value, then check for that value when processing in order to do different things.

<input type="submit" name="action" value="Value-1"> <input type="submit" name="action" value="Value-2">

You could read that value during your processing and redirect if you desired. But that's a workaround for the stated problem.

Another way was to use JavaScript to change the action of the <form> when the button was clicked. There are any number of ways to do that, but it boils down to:

<form name="form"> <!-- inputs and stuff --> <input type="submit" onclick="javascript: form.action='/submit';"> <input type="submit" onclick="javascript: form.action='/submit-2';"> </form>

Which of course relies on JavaScript to work, which isn't a huge deal, but isn't quite as progressive enhancement friendly as it could be.

The correct answer (if I may be so bold) is that HTML has this covered for you already. Perhaps it's not as well-known as it should be. Hence the blog post here, I suppose.

It's all about the formaction attribute, which you can put directly on submit buttons, which overrides the action on the form itself.

<form action="/submit"> <input type="submit" value="Submit"> <input type="submit" value="Go Elsewhere" formaction="/elsewhere"> </form>

That's all. Carry on.

Separate Form Submit Buttons That Go To Different URLs is a post from CSS-Tricks