Archiwum kategorii: CSS

All About React Router 4

Post pobrano z: All About React Router 4

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:

match:

  • 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

Post pobrano z: How We Solve CSS Versioning Conflicts Here at New Relic

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

Browser Compatibility for CSS Grid Layouts with Simple Sass Mixins

Post pobrano z: Browser Compatibility for CSS Grid Layouts with Simple Sass Mixins

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.

Conclusion

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

A Personal Journey to Fix a Grunt File Permissions issue

Post pobrano z: A Personal Journey to Fix a Grunt File Permissions issue

I was working on a personal project this past week and got a weird error when I tried to compile my Sass files. Unfortunately, I did not screenshot the exact error, but was something along the lines of this:

Failed to write to location cssmin: style.css EACCES

That EACCES code threw me for a loop but I was able to deduce that it was a file permissions issue, based on the error description saying it was unable to write the file and from some quick StackOverflow searching.

I couldn’t find a lot of answers for how to fix this, so I made an attempt to fix it myself. Many of the forum threads I found suggested it could a permissions issue with Node, so I went through the painful exercise of reinstalling it and only made things worse because then Terminal could not even find the npm or grunt tasks.

I finally had to reach out to a buddy (thanks, Neal!) to sort things out. I thought I’d chronicle the process he took me through in case it helps other people down the road.

I’ll preface all this by saying I am working on a Mac. That said, I doubt that everything covered here will be universally applicable for all platforms.

Reinstalling Node

Before I talked to Neal, I went ahead and reinstalled Node via the installer package on nodejs.org.

I was told that my permissions issue will likely come up again on future projects until I take the step to re-install Node yet again using a package manager. Some people use Homebrew, though I’ve seen forums caution against it for various reasons. Node Version Manager appears to be a solid option because it’s designed specifically for managing multiple Node versions on the same machine, which makes it easy for future installations and version switching on projects.

Setting a Path to Node Modules

With Node installed, I expected I could point Terminal to my project:

cd /path/to/my/project/folder

…then install the Node modules I put in the project’s package.json file:

npm install

Instead, I got this:

npm: command not found

Crap. Didn’t I just reinstall Node?

Turns out Terminal (or more correctly, my system in general) was making an assumption about where Node was installed and needed to be told where to look.

I resolved this by opening the system’s .bash_profile file and adding the path there. You can get all geeky and open the file up with Terminal using something like:

touch .bash_profile
open .bask_profile

Or do what I did and simply open it with your code editor. It’s an invisible file, but most code editors show those in the folder panel. The file should be located in your user directory, which is something like Macintosh HD > Users > Your User Folder.

This is what I added to ensure Node was being referenced in the correct location:

export PATH="$HOME/.npm-packages/bin:$HOME/.node/bin:$PATH"

That’s basically telling the system to go look in the .npm-packages/bin/ directory for Node commands. In fact, If I browse into that folder, I do indeed see my NPM and Grunt commands, both of which Terminal previously could not locate.

With that little snippet in hand and saved to .bash_profile, I was stoked when I tried to install my Node modules again:

cd /path/to/my/project/folder
npm install

…and saw everything load up as expected!

Updating Permissions

My commands were up and running again, but I was still getting the same EACCES error that I started with at the beginning of this post.

The issue was that the project folders were originally created as the Root user, probably when I was in Terminal using sudo for something else. As a result, running my Grunt tasks with my user account was not enough to give Grunt permission to write files to those folders.

I changed directory to the folder where Grunt was trying to write my style.css file, then checked the permissions of that folder:

cd /path/of/the/parent/directory
ls -al

That displays the permissions for all of the files and folders in that directory. It showed me that the permissions for the folder were indeed not set for my user account to write files to the folder. I changed directory to that specific folder and used the following command to make myself the owner (replacing username with my username, of course):

sudo chown -R username:staff

I went to run my Grunt tasks again and, voila, everything ran, compiled and saved as I hoped.

In Summary

I know the issues I faced here may either be unique to me or of my own making, but I hope this helps someone else. As a web designer, the command line can be daunting or even a little scary to me, even though I feel I’m expected to be familiar with tools that rely on it.

It’s great that we have community-driven sites like StackOverflow when we need them. At the same time, there is is often no substitute for reaching out for personal help.


A Personal Journey to Fix a Grunt File Permissions issue is a post from CSS-Tricks

Designing Between Ranges

Post pobrano z: Designing Between Ranges

CSS is written slowly, line by line, and with each passing moment, we limit the space of what’s possible for our design system. Take this example:

body {
  font-family: 'Proxima-Nova', sans-serif;
  color: #333;
}

With just a couple of lines of CSS we’ve set the defaults for our entire codebase. Most elements (like paragraphs, lists and plain ol’ divs) will inherit these instructions. But what we rarely think about when we write CSS is that from here on out we’ll have to continuously override these rules if we want another typeface or color. And it’s those overrides that cause a lot of issues in terms of maintenance and scalability. And it’s those issues that cost us heartbreak, time and money.

In the example above that’s probably not an issue but I think in general we don’t recognize the true strength and dangers of the cascade and what it means to our design systems; most folks think that the cascade is designed to let us overwrite previous instructions but I would warn against that. Every time we override a style that is inherited we are making our codebase vastly more complex. How many hours have you spent inspecting an element and scrolled through each rule in order to understand why an element looks the way it does or how the long chain of inheritance has messed up your styles completely?

I think the reason for this is because we often don’t set the proper default styles up for our elements. And when we want to change the style of an element, instead of taking the time to question and refactor those default styles, we simply override them – making matters worse.

So I’ve been thinking a lot about how we ought to make a codebase that incentivizes us all to write better code and how to design our CSS so that it doesn’t encourage other people to make hacky classes to override things.

One of my favorite posts on this subject was written earlier this month by Brandon Smith where he describes the ways in which CSS can become so complicated (emphasis mine):

…never be more explicit than you need to be. Web pages are responsive by default. Writing good CSS means leveraging that fact instead of overriding it. Use percentages or viewport units instead of a media query if possible. Use min-width instead of width where you can. Think in terms of rules, in terms of what you really mean to say, instead of just adding properties until things look right. Try to get a feel for how the browser resolves layout and sizing, and make your changes and additions on top of that judiciously. Work with CSS, instead of against it.

One of Brandon’s suggestions is to avoid using the width property altogether and to stick to max-width or min-width instead. Throughout that post he reminds us that whatever we’re building should sit between ranges, between one of two extremes. So here’s an example of a class with a bad default style:

.button {
  width: 300px;
}

Is that button likely to be that width always, everywhere? On mobile? In every media query? In every state? I highly doubt it and in fact, I believe that this class is just the sort that’s begging to be overwritten with yet another class:

.button-thats-just-a-bit-bigger {
  width: 310px;
}

That’s a silly example but I’ve seen code like this in a lot of teams – and it’s not because the person was writing bad code but because the system encouraged them to write bad code. Everyone is on a deadline for shipping a product and most folks don’t have the time or the inclination to dive into a large codebase and refactor those core default styles I mentioned. It’s easier to just keep writing CSS because it solves all of their problems immediately.

Along these lines, Jeremy Keith wrote about this issue just the other day:

Unlike a programming language that requires knowledge of loops, variables, and other concepts, CSS is pretty easy to pick up. Maybe it’s because of this that it has gained the reputation of being simple. It is simple in the sense of “not complex”, but that doesn’t mean it’s easy. Mistaking “simple” for “easy” will only lead to heartache.

I think that’s what’s happened with some programmers coming to CSS for the first time. They’ve heard it’s simple, so they assume it’s easy. But then when they try to use it, it doesn’t work. It must be the fault of the language because they know that they are smart, and this is supposed to be easy. So they blame the language. They say it’s broken. And so they try to “fix” it by making it conform to a more programmatic way of thinking.

I can’t help but think that they would be less frustrated if they would accept that CSS is not easy. Simple, yes, but not easy.

The reason why CSS is simple is because of the cascade, but it’s not as easy as we might first think because of the cascade, too. It’s those default styles that filter down into everything that is the biggest strength and greatest weakness of the language. And I don’t think JavaScript-based solutions will help with that as much as everyone argues to the contrary.

So what’s the solution? I think that by designing in a range, thinking between states and looking at each and every line of CSS as a suggestion instead of an absolute, unbreakable law is the first step forward. What’s the step after that? Container queries. Container queries. Container queries.


Designing Between Ranges is a post from CSS-Tricks

What is Timeless Web Design?

Post pobrano z: What is Timeless Web Design?

Let’s say you took on a client, and they wanted something very specific from you. They wanted a website that without any changes at all, would still look good in 10 years.

Turns out, when you pose this question to a bunch of web designers and developers, the responses are hugely variant!

The Bring It On Crowd

There are certain folks who see this as an intreguing challenge and would relish the opportunity.

Accept.

With glee.

— Jeremy Keith (@adactio) July 27, 2017

Accept the challenge 👌

— Dick (@michaeldick) July 27, 2017

Totally deliver 👍

— Kevin Nagurski (@knagurski) July 27, 2017

The „Keep It Simple” Crowd

This is mostly where my own mind went:

focus on minimalist design and great typography.

— Zach Leatherman (@zachleat) July 27, 2017

I would avoid extremes: no extremely vivid colors; a classic font set; clean but not overly minimal; moderate border radiuses

— keith•j•grant (@keithjgrant) July 27, 2017

Focus on the typography.

— Daniel Sellers (@daniel_sellers) July 27, 2017

Keep it clean and minimal with excellent typography.

— ⌘ Sean Bunton (@seanbunton) July 27, 2017

Plus of course some nods to Motherfucking website and Better Motherfucking Website.

The „Nope” Crowd

An awful lot of folks would straight up just say no. Half?

Decline.

— Cennydd (@Cennydd) July 27, 2017

To be fair, we didn’t exactly set the stage with a lot of detail here. I bet some folks imagined these clients as dummies that don’t know what they are asking.

Decline the business, because that’s not a reasonable expectation.

— Len Damico (@lendamico) July 27, 2017

Refuse.

— Jez McKean (@jezmck) July 27, 2017

I wonder if the client presented themselves well, clearly knew what they were asking, and were happy to pay for it, if many of these designers would have responded differently.

Laugh

— Woman Code Warrior (@amberweinberg) July 28, 2017

Still, curious that so many designers didn’t see any the challenge here, just the absurdity.

The „Let’s Get Technical” Crowd

I’m partially in this group! What things can and should we reach for in this project, and what should we avoid?

A) system fonts
B) semantic HTML
C) let the browser's shifting sands on how to render the page update the site for you
D) git drnk

— Sean T. McBeth (@Sean_McBeth) July 28, 2017

mobile-first, svg graphics, time spent on ux analysis (card sort analysis etc), decoupled modular micro-service front+back end

— Adam Mackintosh (@agm1984) July 27, 2017

Honestly an SPA, no external dependents, and build an archive and entry mechanism to handle content. Wildcard redirect and buy 10 yr hosting

— Jeff (@etisdew) July 28, 2017

If you're looking for an actual answer besides no, maybe html only, inline styles, nothing dynamic, no external calls.

— David v2.9.5 (@davidlaietta) July 28, 2017

„No external calls” seems particularly smart here.

Based on experience and observation in my time in the industry, I’d say it’s somewhere around 75% of websites are completely gone after 10 years, let alone particular URL’s on those websites being exactly the same (reliable external resources).

The „It’s About The Content” Crowd

Simple, driven by content

— Eric Shuff (@ericshuff) July 27, 2017

Focus on making it easy to publish and manage great content. Because great content can easily outlive 10 years.

— Deepti Boddapati (@DeeptiBoddapati) July 27, 2017

Very basic, content focus without all the pretty things.

— Bethany (@fleshskeleton) July 27, 2017

Minimal. Large text elements with a few images mixed in with the content and little color.

— Veronica Domeier (@hellodomeier) July 27, 2017

The „See Existing Examples” Crowd

Adopt the Craigslist design philosophy.

— Chris Cashdollar (@ccashdollar) July 27, 2017

Borrow from @daringfireball

— Joe Casabona (@jcasabona) July 27, 2017

Hand them the Google homepage.

— Darth Seh (@seh) July 27, 2017

https://t.co/wu3bjk5zoA that would work I guess

— Pascal (@murindwaz) July 27, 2017

Plus things like Wikipedia and Space Jam. Also see Brutalist Websites.

Interesting Takes

Our very own Robin Rendle had an interesting take. Due to population growth, growing networks, and mobile device ubiquity, they site may not want to be in English, especially if it has a global audience. Or at least, be in multiple major world languages.

Leave it to Sarah to come in for the side tackle:

shape the culture that uses the app/site to hate change

— Overactive Algorithm (@sarah_edo) July 28, 2017

And Christopher to give us some options to keep them on their toes:

A) say, “Is this one of those tricky Google job interview questions?”
B) say, “GeoCities lasted 10,000 years, so this will be easy.”
C) 👀

— Christopher Schmitt (@teleject) July 28, 2017

Why do any design at all?

text file on the server root

— Eric Bailey (@ericwbailey) July 27, 2017

Although I might argue in that case, you might as well make it an `.html` file instead of `.txt` so you can at least hyperlink things.

My Take

Clearly „it depends” on what this website is supposed to accomplish.

I can tell you what I picture though when I think about it.

I picture a business card style website. I picture black-and-white. I picture a clean and simple logo.

I picture really (really) good typography. Typography is way older than the web and will be around long after. Pick typefaces that have already stood the test of time.

I picture some, but minimal copy. Even words go stale.

I picture the bare minimum call to action. Probably just a displayed email address. I’d bet on email over phones.

Technically, I think you can count on HTML, CSS, and JavaScript. I don’t think anything you can do now with those languages will be deprecated in 10 years.

Layout-wise, I’d look at doing as much as you can with viewport units. Screens will absolutely change in size and density in 10 years. Anything you can make SVG, make SVG. That will reduce worry about new screens. Responsive design is an obvious choice.

Anything that even passably smells like a trend, avoid.

Inputs will also definitely change. We’re already starting to assume a touch screen. Presumably, you won’t have to do anything overly interactive, but if you do, I wouldn’t bet on a keyboard and mouse.

I’d also spend time on the hosting aspects. Register the domain name for the full 10 years. See if you can pre-buy hosting that long. Pick a company you’re reasonably sure will last that long. Use a credit card that you’re reasonable sure will last that long. Make sure anything that needs to renew renews automatically, like SSL certificates.


More thoughts, as always, welcome in the comments.


What is Timeless Web Design? is a post from CSS-Tricks

The Critical Request

Post pobrano z: The Critical Request

Serving a website seems pretty simple: Send some HTML, the browser figures out what resources to load next. Then we wait patiently for the page to be ready.

Little may you know, a lot is going on under the hood.

Have you ever wondered how browser figures out which assets should be requested and in what order?

Today we’re going to take a look at how we can use resource priorities to improve the speed of delivery.

Resource priority at work

Most browsers parse HTML using a streaming parser—assets are discovered within the markup before it has been fully delivered. As assets are found, they’re added to a network queue along with a predetermined priority.

In Chrome today, there are a number of asset prioritization levels: Very Low, Low, Medium, High and Very high. Peeking into Chrome DevTools source shows that these are aliased to slightly different labels: Lowest, Low, Medium, High and Highest.

To see how your site is prioritizing requests, you can enable a priority column in the Chrome DevTools network request table.

If you’re using Safari Technology preview, the (new!) Priority column can be shown in exactly the same way.

Show the Priority column by right clicking any of the request table headings.

You’ll also find the priority for a given request in the Performance tab.

Resource timings and priorities are shown on hover

How does Chrome prioritize resources?

Each resource type (CSS, JavaScript, fonts, etc.) has their own set of rules that dictate how they’ll be prioritized. What follows is a non-exhaustive list of network priority plans:

HTML— Highest priority.

Styles—Highest priority. Stylesheets that are referenced using an @import directive will also be prioritized Highest, but they’ll be queued after blocking scripts.

Images are the only assets that can vary priority based on viewport heuristics. All images start with a priority of Low but will be upgraded to Medium priority when to be rendered within the visible viewport. Images outside the viewport (also known as „below the fold”) will remain at Low priority.

During the process of researching this article, I discovered (with the help of Paul Irish) that Chrome DevTools are currently misreporting images that have been upgraded to Medium as Low priority. Paul wrote up a bug report, which you can track here.

If you’re interested in reading the Chrome source that handles the image priority upgrade, start with UpdateAllImageResourcePriorities and ComputeResourcePriority.

Ajax/XHR/fetch()—High priority.

Scripts follow a complex loading prioritization scheme. (Jake Archibald wrote about this in detail during 2013. If you want to know the science behind it, I suggest you grab a cuppa and dive in). The TL;DR version is:

  • Scripts loaded using <script src="name.js"></script> will be prioritized as High if they appear in the markup before an image.
  • Scripts loaded using <script src="name.js"></script> will be prioritized as Medium if they’re appear in the markup after an image.
  • Scripts that use async or defer attributes will be prioritized as Low.
  • Scripts using type="module" will be prioritized as Low.

Fonts are a bit of a strange beast; they’re hugely important resources (who else loves the „’I see it!”, „Now it’s gone”, „Whoa, a new font!” game?), so it makes sense that fonts are downloaded at the Highest priority.

Unfortunately, most @font-face rules are found within an external stylesheet (loaded using something like: <link rel="stylesheet" href="file.css">). This means that web fonts are usually delayed until after the stylesheet has downloaded.

Even if your CSS file references a @font-face font, it will not be requested until it is used on a selector and that selector matches an element on the page. If you’ve built a single page app that doesn’t render any text until it renders, you’re delaying the fonts even further.

What makes a request critical?

Most websites effectively ask the browser to load everything for the page to be fully rendered, there is no concrete concept of „above the fold”.

Back in the day, browsers wouldn’t make more than 6 simultaneous requests per domain — people hacked around this by using assets-1.domain.tld, assets-2.domain.tld hosts to increase the number of asynchronous downloads but failed to recognize that there would be a DNS hit and TCP connection for each new domain and asset.

While this approach had some merits, many of us didn’t understand the full impacts and certainly didn’t have good quality browser developer tools to confirm these experiments.

Thankfully today, we have great tools at our disposal. Using CNN as an example, let’s identify assets that are absolutely required for the viewport to be visually ready (also known as useful to a someone trying to read it).

The user critical content is the masthead, and leading article.

There’s really only 5 things that are necessary to display this screen (and not all of them need to be loaded before the site is usable):

  • Most importantly, the HTML. If all else fails the user can still read the page.
  • CSS
  • The logo (A PNG background-image placed by CSS. This could probably be an inline SVG).
  • 4(!) web font weights.
  • The leading article image.

These assets (note the lack of JavaScript) are essential to the visuals that make up the main viewport of the page. These assets are the ones that should be loaded first.

Diving into the performance panel in Chrome shows us that around 50 requests are made before the fonts and leading image are requested.

CNN.com becomes fully rendered somewhere around the 9s mark. This was recorded using a 4G connection, with reasonably spotty connectivity.

There’s a clear mismatch between the requests that are required for viewing and the requests that are being made.

Controlling resource priorities

Now that we’ve defined what critical requests are, we can start to prioritize them using a few simple, powerful tweaks.

Preload (<link rel="preload" href="font.woff" />) instructs the browser to add font.woff to the browser’s download queue at a „High” priority.

Note: as="font" is the reason why font.woff would be downloaded as High priority — It’s a font, so it follows the priority plan discussed earlier in the „How does Chrome prioritise resources?” section.

Essentially, you’re telling the browser: You might not know it yet, but we’re going to need this.

This is perfect for those critical requests that we identified earlier. Web fonts can nearly always be categorized as absolutely critical, but there are some fundamental issues with how fonts are discovered and loaded:

  • We wait for the CSS to be loaded, parsed and applied before @font-face rules are discovered.
  • A font is not added to the browser’s network queue until it matches up its CSS rules to the DOM via the selectors.
  • This selector matching occurs during style recalculation. It doesn’t necessarily happen immediately after download. It can be delayed if the main thread is busy.

In most cases, fonts are delayed by a number of seconds, just because we’re not instructing the browser to download them in a timely fashion.

On a mobile device with a slow CPU, laggy connectivity, and without a properly-constructed fallback this can be an absolute deal breaker.

Preload in action: fonts

I ran two tests against calibreapp.com. On the first run, I’d changed nothing about the site at all. On the second, I added these two tags:

<link rel="preload" as="font" href="" type="font/woff2" crossorigin />

<link rel="preload" as="font" href="" type="font/woff2" crossorigin />

Below, you’ll see a visual comparison of the rendering of these two tests. The results are quite staggering:

The page rendered 3.5 seconds faster when the fonts were preloaded.

Bottom: Fonts are preloaded — The site finishes rendering in 5 seconds on a „emerging markets” 3G connection.

<link rel="preload"> also accepts a media="" attribute, which will selectively prioritize resources based on @media query rules:

<link rel="preload" href="article-lead-sm.jpg" as="image" type="image/jpeg" media="only screen and (max-width: 48rem)">

Here, we’re able to preload a particular image for small screen devices. Perfect for that „main hero image”.

As demonstrated above, a simple audit and a couple of tags later and we’ve vastly improved the delivery & render phase. Super.

Getting tough on web fonts

69% of sites use web fonts, and unfortunately, they’re providing a sub-par experience in most cases. They appear, then disappear, then appear again, change weights and jolt the page around during the render sequence.

Frankly, this sucks on almost every level.

As you’ve seen above, controlling the request order and priority of fonts has a massive effect on render speed. It’s clear that we should be looking to prioritize web font requests in most cases.

We can make further improvements using the CSS font-display property. allows us to control how fonts display during the process of web fonts being requested and loaded.

There are 4 options at your disposal, but I’d suggest using font-display: swap;, which will show the fallback font until the web font has loaded—at which point it’ll be replaced.

Given a font stack like this:

body {
  font-family: Calibre, Helvetica, Arial;
}

The browser will display Helvetica (or Arial, if you don’t have Helvetica) until the Calibre font has loaded. Right now, Chrome and Opera are the only browsers that support font-display, but it’s a step forward, and there’s no reason to not use it starting today.

Keeping on top of page performance

As you’re well aware, websites are never „complete”. There are always improvements to be made and it can feel overwhelming, quickly.

Calibre is an automated tool for auditing performance, accessibility and web best practices, it’ll help you stay on top of things.

As you’ve seen above, there are a few metrics that are key to understanding user performance.

  • First paint, tells us when the browser goes from „nothing to something”.
  • First meaningful paint, tells us when the browser has „rendered something useful”.
  • Finally, First Interactive will tell you when the page has fully rendered, and the JavaScript main thread has settled (low CPU activity for a number of seconds).
Here, we set a budget on CNN’s „First meaningful paint” for <5 seconds.

You can set budgets against all these key user experience metrics. When those budgets are exceeded (or met) your team will be notified by Slack, email or wherever you like.

Calibre displays network request priority, so you can be sure of the requests being made. Tweak priorities and improve performance.

I hope that you’ve learned some valuable skills to audit requests and their priorities, as well as sparked a few ideas to experiment with to make meaningful performance improvements.

Your critical request checklist:

  • ✅ Enable the Priority column in Chrome DevTools.
  • ✅ Decide which requests must be made before users can see a fully rendered page.
  • ✅ Reduce the number of required critical requests where possible.
  • ✅ Use for assets that will probably be used on the next page of the site.
  • ✅ Use <link https://example.com/other/styles.css rel=preload as=style> nopush HTTP headers to tell the browser which resources to preload before the HTML has been fully delivered.
  • 🚫 HTTP/2 Server push is thorny. Probably avoid it. (See this informative document by Tom Bergan, Simon Pelchat and Michael Buettner, as well as Jake Archibald’s „HTTP/2 Push is tougher than I thought”)
  • ✅ Use font-display: swap; with web fonts where possible.
  • ⏱ Are web fonts being used? Can they be removed? If no: prioritize them and use WOFF2!
  • ⏱ Is a late loading script delaying your single page app from displaying anything at all?
  • 📹 Check this great free screencast by Front End Center that shows how load webfonts with the best possible fallback experience.
  • 🔍 View chrome://net-internals/#events and load a page — this logs network related events.
  • No request is faster than no request. ✌️

The Critical Request is a post from CSS-Tricks

Simple Server Side Rendering, Routing, and Page Transitions with Nuxt.js

Post pobrano z: Simple Server Side Rendering, Routing, and Page Transitions with Nuxt.js

A bit of a wordy title, huh? What is server side rendering? What does it have to do with routing and page transitions? What the heck is Nuxt.js? Funnily enough, even though it sounds complex, working with Nuxt.js and exploring the benefits of isn’t too difficult. Let’s get started!

Server side rendering

You might have heard people talking about server side rendering as of late. We looked at one method to do that with React recently. One particularly compelling aspect is the performance benefits. When we render our HTML, CSS, and JavaScript on the server, we often have less JavaScript to parse both initially and on subsequent updates. This article does really well going into more depth on the subject. My favorite takeaway is:

By rendering on the server, you can cache the final shape of your data.

Instead of grabbing JSON or other information from the server, parsing it, then using JavaScript to create layouts of that information, we’re doing a lot of those calculations upfront, and only sending down the actual HTML, CSS, and JavaScript that we need. This can reap a lot of benefits with caching, SEO, and speed up our apps and sites.

What is Nuxt.js?

Server side rendering sounds pretty nice, but you’re probably wondering if it’s difficult to set up. I’ve been using Nuxt.js for my Vue applications lately and found it surprisingly simple to work with. To be clear: you don’t need to use Nuxt.js in particular to do server side rendering. I’m just a fan of this tool for many reasons. I ran some tests last month and found that Nuxt.js had even higher lighthouse scores out of the gate than Vue’s PWA template, which I thought was impressive.

Nuxt.js is a higher-level framework that you can use with a CLI command that you can use to create universal Vue applications. Here are some, not all, of the benefits:

  • Server-Side Rendering
  • Automatic Code Splitting
  • Powerful Routing System
  • Great lighthouse scores out of the gate 🐎
  • Static File Serving
  • ES6/ES7 Transpilation
  • Hot reloading in Development
  • Pre-processors: SASS, LESS, Stylus, etc
  • Write Vue Files to create your pages and layouts!
  • My personal favorite: easily add transitions to your pages

Let’s set up a basic application with some routing to see the benefits for ourselves.

Getting Set up

The first thing we need to do if you haven’t already is download Vue’s CLI. You can do so globally with this command:

npm install -g vue-cli

# ... or ...
 
yarn add global vue-cli

You will only need to do this once, not every time you use it.

Next, we’ll use the CLI to scaffold a new project, but we’ll use Nuxt.js as the template:

vue init nuxt/starter my-project
cd my-project
yarn  # or...  npm install
npm run dev

You’ll see the progress of the app being built and it will give you a dedicated development server to check out: http://127.0.0.1:3000/. This is what you’ll see right away (with a pretty cool little animation):

Screenshot of Nuxt starting screen

Let’s take a look at what’s creating this initial view of our application at this point. We can go to the `pages` directory, and inside see that we have an `index.vue` page. If we open that up, we’ll see all of the markup that it took to create that page. We’ll also see that it’s a `.vue` file, using single file components just like any ordinary `vue` file, with a template tag for the HTML, a script tag for our scripts, where we’re importing a component, and some styles in a style tag. (If you aren’t familiar with these, there’s more info on what those are here.) The coolest part of this whole thing is that this `.vue` file doesn’t require any special setup. It’s placed in the `pages` directory, and Nuxt.js will automatically make this server-side rendered page!

Let’s create a new page and set up some routing between them. In `pages/index.vue`, dump the content that’s already there, and replace it with:

<template>
  <div class="container">
    <h1>Welcome!</h1>
    <p><nuxt-link to="/product">Product page</nuxt-link></p>
  </div>
</template>

<style>
.container {
  font-family: "Quicksand", "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; /* 1 */
  padding: 60px;
}
</style>

Then let’s create another page in the pages directory, we’ll call it `product.vue` and put this content inside of it:

<template>
  <div class="container">
    <h1>This is the product page</h1>
    <p><nuxt-link to="/">Home page</nuxt-link></p>
  </div>
</template>

Right away, you’ll see this:

Ta-da! 🏆
Right away, we have server side rendering, routing between pages (if you check out the URL you can see it’s going between the index page and product page), and we even have a sweet little green loader that zips across the top. We didn’t have to do much at all to get that going.

You might have noticed in here, there’s a special little element: <nuxt-link to="/">. This tag can be used like an a tag, where it wraps around a bit of content, and it will set up an internal routing link between our pages. We’ll use to="/page-title-here" instead of an href.

Now, let’s add some transitions. We’ll do this in a few stages: simple to complex.

Creating Page Transitions

We already have a really cool progress bar that runs across the top of the screen as we’re routing and makes the whole thing feel very zippy. (That’s a technical term). While I like it very much, it won’t really fit the direction we’re headed in, so let’s get rid of it for now.

We’re going to go into our `nuxt.config.js` file and change the lines:

/*
** Customize the progress-bar color
*/
loading: { color: '#3B8070' },

to

loading: false,

You’ll also notice a few other things in this nuxt.config.js file. You’ll see our meta and head tags as well as the content that will be rendered inside of them. That’s because we won’t have a traditional `index.html` file as we do in our normal CLI build, Nuxt.js is going to parse and build our `index.vue` file together with these tags and then render the content for us, on the server. If you need to add CSS files, fonts, or the like, we would use this Nuxt.js config file to do so.

Now that we have all that down, let’s understand what’s available to us to create page transitions. In order to understand what’s happening on the page that we’re plugging into, we need to review how the transition component in Vue works. I’ve written an article all about this here, so if you’d like deeper knowledge on the subject, you can check that out. But what you really need to know is this: under the hood, Nuxt.js will plug into the functionality of Vue’s transition component, and gives us some defaults and hooks to work with:

transition component hooks

You can see here that we have a hook for what we want to happen right before the animation starts enter, during the animation/transition enter-active, and when it finishes. We have these same hooks for when something is leaving, prepended with leave instead. We can make simple transitions that just interpolate between states, or we could plug a full CSS or JavaScript animation into them.

Usually in a Vue application, we would wrap a component or element in <transition> in order to use this slick little functionality, but Nuxt.js will provide this for us at the get-go. Our hook for the page will begin with, thankfully- page. All we have to do to create an animation between pages is add a bit of CSS that plugs into the hooks:

.page-enter-active, .page-leave-active {
  transition: all .25s ease-out;
}
.page-enter, .page-leave-active {
  opacity: 0;
  transform-origin: 50% 50%;
}

I’m also going to add an extra bit of styling here so that you can see the page transitions a little easier:

html, body {
  font-family: "Quicksand", "Source Sans Pro", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; /* 1 */
  background: #222;
  color: white;
  width: 100vw;
  height: 100vh;
}

a, a:visited {
  color: #3edada;
  text-decoration: none;
}

.container {
  padding: 60px;
  width: 100vw;
  height: 100vh;
  background: #444;
}

Right now we’re using a CSS Transition. This only gives us the ability to designate what to do in the middle of two states. We could do something a little more interesting by having an animation adjust in a way that suggests where something is coming from and going to. For that to happen, we could separate out transitions for page-enter and page-leave-active classes, but it’s a little more DRY to use a CSS animation and specify where things are coming from and going to, and plug into each for .page-enter-active, and .page-leave-active:

.page-enter-active {
  animation: acrossIn .45s ease-out both;
} 

.page-leave-active {
  animation: acrossOut .65s ease-in both;
} 

@keyframes acrossIn {
  0% {
    transform: translate3d(-100%, 0, 0);
  }
  100% {
    transform: translate3d(0, 0, 0);
  }
}

@keyframes acrossOut {
  0% {
    transform: translate3d(0, 0, 0);
  }
  100% {
    transform: translate3d(100%, 0, 0);
  }
}

Let’s also add a little bit of special styling to the product page so we can see the difference between these two pages:

<style scoped>
  .container {
    background: #222;
  }
</style>

This scoped tag is pretty cool because it will apply the styles for this page/vue file only. If you have heard of CSS Modules, you’ll be familiar with this concept.

We would see this (this page is for demo purposes only, that’s probably too much movement for a typical page transition):

Now, let’s say we have a page with a totally different interaction. For this page, the movement up and down was too much, we just want a simple fade. For this case, we’d need to rename our transition hook to separate it out.

Let’s create another page, we’ll call it the contact page and create it in the pages directory.

<template>
  <div class="container">
    <h1>This is the contact page</h1>
    <p><nuxt-link to="/">Home page</nuxt-link></p>
  </div>
</template>

<script>
export default {
  transition: 'fadeOpacity'
}
</script>

<style>
.fadeOpacity-enter-active, .fadeOpacity-leave-active {
  transition: opacity .35s ease-out;
}

.fadeOpacity-enter, .fadeOpacity-leave-active {
  opacity: 0;
}
</style>

Now we can have two-page transitions:

You can see how we could build on these further and create more and more streamlined CSS animations per page. But from here let’s dive into my favorite, JavaScript animations, and create page transitions with a bit more horsepower.

Javascript Hooks

Vue’s <transition> component offers some hooks to use JavaScript animation in place of CSS as well. They are as follows, and each hook is optional. The :css="false" binding lets Vue know we’re going to use JS for this animation:

<transition 
  @before-enter="beforeEnter"
  @enter="enter"
  @after-enter="afterEnter"
  @enter-cancelled="enterCancelled"

  @before-Leave="beforeLeave"
  @leave="leave"
  @after-leave="afterLeave"
  @leave-cancelled="leaveCancelled"
  :css="false">
 
 </transition>

The other thing we have available to us are transition modes. I’m a big fan of these, as you can state that one animation will wait for the other animation to finish transitioning out before transitioning in. The transition mode we will work with will be called out-in.

We can do something really wild with JavaScript and the transition mode, again, we’re going a little nuts here for the purposes of demo, we would usually do something much more subtle:

In order to do something like this, I’ve run yarn add gsap because I’m using GreenSock for this animation. In my `index.vue` page, I can remove the existing CSS animation and add this into the <script> tags:

import { TweenMax, Back } from 'gsap'

export default {
  transition: {
    mode: 'out-in',
    css: false,
    beforeEnter (el) {
      TweenMax.set(el, {
        transformPerspective: 600,
        perspective: 300,
        transformStyle: 'preserve-3d'
      })
    },
    enter (el, done) {
      TweenMax.to(el, 1, {
        rotationY: 360,
        transformOrigin: '50% 50%',
        ease: Back.easeOut
      })
      done()
    },
    leave (el, done) {
      TweenMax.to(el, 1, {
        rotationY: 0,
        transformOrigin: '50% 50%',
        ease: Back.easeIn
      })
      done()
    }
  }
}

All of the code for these demos exist in my Intro to Vue repo for starter materials if you’re getting ramped up learning Vue.

One thing I want to call out here is that currently there is a bug for transition modes in Nuxt.js. This bug is fixed, but the release hasn’t come out yet. It should be all fixed and up to date in the upcoming 1.0 release, but in the meantime, here is a working simple sample demo, and the issue to track.

With this working code and those JavaScript hooks we can start to get much fancier and create unique effects, with different transitions on every page:

Here’s the site that the demo was deployed to if you’d like to see it live: https://nuxt-type.now.sh/ as well as the repo that houses the code for it: https://github.com/sdras/nuxt-type

Navigation

In that last demo you might have noticed we had a common navigation across all of the pages what we routed. In order to create this, we can go into the `layouts` directory, and we’ll see a file called `default.vue`. This directory will house the base layouts for all of our pages, „default” being the, uhm, default 🙂

Right away you’ll see this:

<template>
  <div>
    <nuxt/>
  </div>
</template>

That special <nuxt/> tag will be where our `.vue` pages files will be inserted, so in order to create a navigation, we could insert a navigation component like this:

<template>
  <div>
    <img class="moon" src="~assets/FullMoon2010.png" />
    <Navigation />
    <nuxt/>
  </div>
</template>

<script>
import Navigation from '~components/Navigation.vue'

export default {
  components: {
    Navigation
  }
}
</script>

I love this because everything is kept nice and organized between our global and local needs.

I then have a component called Navigation in a directory I’ve called `components` (this is pretty standard fare for a Vue app). In this file, you’ll see a bunch of links to the different pages:

<nav>
  <div class="title">
    <nuxt-link to="/rufina">Rufina</nuxt-link>
    <nuxt-link to="/prata">Prata</nuxt-link>
    <nuxt-link exact to="/">Playfair</nuxt-link>
  </div>
</nav>

You’ll notice I’m using that <nuxt-link> tag again even though it’s in another directory, and the routing will still work. But that last page has one extra attribute, the exact attribute: <nuxt-link exact to="/">Playfair</nuxt-link> This is because there are many routes that match just the `/` directory, all of them do, in fact. So if we specify exact, Nuxt will know that we only mean the index page in particular.

Further Resources

If you’d like more information about Nuxt, their documentation is pretty sweet and has a lot of examples to get you going. If you’d like to learn more about Vue, I’ve just made a course on Frontend Masters and all of the materials are open source here, or you can check out our Guide to Vue, or you can go to the docs which are extremely well-written. Happy coding!


Simple Server Side Rendering, Routing, and Page Transitions with Nuxt.js is a post from CSS-Tricks

A Collection of Interesting Facts about CSS Grid Layout

Post pobrano z: A Collection of Interesting Facts about CSS Grid Layout

A few weeks ago I held a CSS Grid Layout workshop. Since I’m, like most of us, also pretty new to the topic, I learned a lot while preparing the slides and demos.
I decided to share some of the stuff that was particularly interesting to me, with you.

Have fun!

Negative values lower than -1 may be used for grid-row-end and grid-column-end

In a lot of code examples and tutorials you will see that you can use grid-column-start: 1 and grid-column-end: -1 (or the shorthand grid-column: 1 / -1) to span an element from the first line to the last. My friend Max made me aware that it’s possible to use lower values than -1 as well.

.grid-item {
  grid-column: 1 / -2;
}

For example, you can set grid-column: 1 / -2 to span the cells between the first and the second to last line.

See the Pen Grid item from first to second to last by Manuel Matuzovic (@matuzo) on CodePen.

It’s possible to use negative values in grid-column/row-start

Another interesting thing about negative values is that you can use them on grid-column/row-start as well. The difference between positive and negative values is that with negative values the placement will come from the opposite side. If you set grid-column-start: -2 the item will be placed on the second to last line.

.item {
  grid-column-start: -3;
  grid-row: -2;
}

See the Pen Negative values in grid-column/row-start by Manuel Matuzovic (@matuzo) on CodePen.

Generated content pseudo-elements (::before and ::after) are treated as grid items

It may seem obvious that pseudo-elements generated with CSS become grid items if they’re within a grid container, but I wasn’t sure about that. So I created a quick demo to verify it. In the following Pen you can see that generated elements become grid- and flex-items if they are within a corresponding container.

See the Pen Experiment: Pseudo elements as grid items by Manuel Matuzovic (@matuzo) on CodePen.

Animating CSS Grid Layout properties

According to the CSS Grid Layout Module Level 1 specification there are 5 animatable grid properties:

  • grid-gap, grid-row-gap, grid-column-gap
  • grid-template-columns, grid-template-rows

Currently only the animation of grid-gap, grid-row-gap, grid-column-gap is implemented and only in Firefox and Firefox Mobile. I wrote a post about animating CSS Grid Layout properties, where you’ll find some more details and a demo.

The value of grid-column/row-end can be lower than the start value

In level 4 of the CSS Grid Garden game I learned that the value of grid-column-end or grid-row-end may be lower than the respective start equivalent.

.item:first-child {
  grid-column-end: 2;
  grid-column-start: 4;
}

The item in the above code will start on the 4th line and end on the 2nd, or in other words, start on the 2nd line and end on the 4th.

See the Pen Lower grid-column-end value than grid-column-start by Manuel Matuzovic (@matuzo) on CodePen.

Using the `span` keyword on grid-column/row-start and grid-column/row-end

A grid item by default spans a single cell. If you want to change that, the span keyword can be quite convenient. For example setting grid-column-start: 1 and grid-column-end: span 2 will make the grid item span two cells, from the first to the third line.

You can also use the span keyword with grid-column-start. If you set grid-column-end: -1 and grid-column-start: span 2 the grid-item will be placed at the last line and span 2 cells, from the last to third to last line.

See the Pen CSS Grid Layout: span keyword by Manuel Matuzovic (@matuzo) on CodePen.

grid-template-areas and implicit named lines

If you create template areas in a grid, you automatically get four implicit named lines, two naming the row-start and row-end and two for the column-start and column-end. By adding the -start or -end suffix to the name of the area, they’re applicable like any other named line.

.grid {
  display: grid;
  grid-template-columns: 1fr 200px 200px;
  grid-template-areas: 
    "header header header"
    "articles ads posts"
}

.footer {
  grid-column-start: ads-start;
  grid-column-end: posts-end;
}

See an example for implicit named lines in this Pen.

Grid is available in the insider version of Microsoft Edge

Support for CSS Grid Layout is pretty great since all major browsers, except IE and Edge, support it. For a lot of projects you can start using CSS Grid Layouts today. Support for Microsoft Edge will probably come pretty soon, because it’s already available in the insider version of Microsoft Edge.

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

Desktop

Chrome Opera Firefox IE Edge Safari
57 44 52 11* 16 10.1

Mobile / Tablet

iOS Safari Opera Mobile Opera Mini Android Android Chrome Android Firefox
10.3 No No 56 59 54

If you want to learn more about Grids check out The Complete Guide to Grid, Getting Started with CSS Grid, Grid By Example and my Collection of Grid demos on CodePen.


A Collection of Interesting Facts about CSS Grid Layout is a post from CSS-Tricks

​Edit your website, from your website

Post pobrano z: ​Edit your website, from your website

Stuck making „a few easy changes” to the website for someone? Component IO makes it quick and simple for you or your team to make edits (even for non-technical users).

You can manage content with a WYSIWYG editor or instantly update HTML, CSS, and JavaScript right from your website. Make changes faster, empower your team, and avoid redeployment bugs. Works with every web technology, from WordPress to Rails to React.

Join hundreds of projects already using Component IO, with a free tier and plans from $7.95/mo. It’s built to make web development easier for everyone.

Try it free

Direct Link to ArticlePermalink


​Edit your website, from your website is a post from CSS-Tricks