Archiwum kategorii: CSS

A Front End Developer’s Guide to GraphQL

Post pobrano z: A Front End Developer’s Guide to GraphQL

No matter how large or small your application is, you’ll have to deal with fetching data from a remote server at some point. On the front end, this usually involves hitting a REST endpoint, transforming the response, caching it, and updating your UI. For years, REST has been the status quo for APIs, but over the past year, a new API technology called GraphQL has exploded in popularity due to its excellent developer experience and declarative approach to data fetching.

In this post, we’ll walk through a couple of hands-on examples to show you how integrating GraphQL into your application will solve many pain points working with remote data. If you’re new to GraphQL, don’t panic! I’ll also highlight some resources to help you learn GraphQL using the Apollo stack, so you can start off 2018 ahead of the curve.

GraphQL 101

Before we dive into how GraphQL makes your life as a front end developer easier, we should first clarify what it is. When we talk about GraphQL, we’re either referring to the language itself or its rich ecosystem of tools. At its core, GraphQL is a typed query language developed by Facebook that allows you to describe your data requirements in a declarative way. The shape of your result matches the shape of your query: in the example below, we can expect to receive back an object with a currency property and a rates property containing an array of objects with both currency and rate keys.

{
  rates(currency: "USD") {
    currency
    rates {
      currency
      rate
    }
  }
}

When we talk about GraphQL in a broader sense, we’re often referring to the ecosystem of tools that help you implement GraphQL in your application. On the backend, you’ll use Apollo Server to create a GraphQL server, which is a single endpoint that parses a GraphQL request and returns data. How does the server know which data to return? You’ll use GraphQL Tools to build a schema (like a blueprint for your data) and a resolver map (just a series of functions that retrieve your data from a REST endpoint, database, or wherever else you choose).

This all sounds more complicated than it actually is — with Apollo Launchpad, a GraphQL server playground, you can create a working GraphQL server in your browser in less than 60 lines of code! 😮 We’ll reference this Launchpad I created that wraps the Coinbase API throughout this post.

You’ll connect your GraphQL server to your application with Apollo Client, a fast and flexible client that fetches, caches, and updates your data for you. Since Apollo Client isn’t coupled to your view layer, you can use it with React, Angular, Vue, or plain JavaScript. Not only is Apollo cross-framework, it’s also cross-platform, with React Native & Ionic supported out of the box.

Let’s give it a try! 🚀

Now that you’re well-versed in what GraphQL is, let’s get our hands dirty with a couple of practical examples that illustrate what it’s like to develop your front end with Apollo. By the end, I think you’ll be convinced that a GraphQL-based architecture with Apollo can help you ship features faster than before.

1. Add new data requirements without adding a new endpoint

We’ve all been here before: You spend hours building a perfect UI component when suddenly, product requirements change. You quickly realize that the data you need to fulfill these new requirements would either require a complicated waterfall of API requests or worse, a new REST endpoint. Now blocked on your work, you ask the backend team to build you a new endpoint just to satisfy the data needs for one component.

This common frustration no longer exists with GraphQL because the data you consume on the client is no longer coupled to an endpoint’s resource. Instead, you always hit the same endpoint for your GraphQL server. Your server specifies all of the resources it has available via your schema and lets your query determine the shape of the result. Let’s illustrate these concepts using our Launchpad from before:

In our schema, look at lines 22–26 where we define our ExchangeRate type. These fields list out all the available resources we can query in our application.

type ExchangeRate {
  currency: String
  rate: String
  name: String
}

With REST, you’re limited to the data your resource provides. If your /exchange-rates endpoint doesn’t include name, then you’ll need to either hit a different endpoint like /currency for the data or create it if it doesn’t exist.

With GraphQL, we know that name is already available to us by inspecting our schema, so we can query for it in our application. Try running this example in Launchpad by adding the name field on the right side panel!

{
  rates(currency: "USD") {
    currency
    rates {
      currency
      rate
      name
    }
  }
}

Now, remove the name field and run the same query. See how the shape of our result changes?

the data changes as you describe your query differently

Your GraphQL server always gives you back exactly the data you ask for. Nothing more. This differs significantly from REST, where you often have to filter and transform the data you get back from the server into the shape your UI components need. Not only does this save you time, it also results in smaller network payloads and CPU savings from loading and parsing the response.

2. Reduce your state management boilerplate

Fetching data almost always involves updating your application’s state. Typically, you’ll write code to track at least three actions: one for when the data is loading, one if the data successfully arrives, and one if the data errors out. Once the data arrives, you have to transform it into the shape your UI components expect, normalize it, cache it, and update your UI. This process can be repetitive, requiring countless lines of boilerplate to execute one request.

Let’s see how Apollo Client eliminates this tiresome process altogether by looking at an example React app in CodeSandbox. Navigate to `list.js` and scroll to the bottom.

export default graphql(ExchangeRateQuery, {
  props: ({ data }) => {
    if (data.loading) {
      return { loading: data.loading };
    }
    if (data.error) {
      return { error: data.error };
    }
    return {
      loading: false,
      rates: data.rates.rates
    };
  }
})(ExchangeRateList);

In this example, React Apollo, Apollo Client’s React integration, is binding our exchange rate query to our ExchangeRateList component. Once Apollo Client executes that query, it tracks loading and error state automatically and adds it to the data prop. When Apollo Client receives the result, it will update the data prop with the result of the query, which will update your UI with the rates it needs to render.

Under the hood, Apollo Client normalizes and caches your data for you. Try clicking some of the currencies in the panel on the right to watch the data refresh. Now, select a currency a second time. Notice how the data appears instantaneously? That’s the Apollo cache at work! You get all of this for free just by setting up Apollo Client with no additional configuration. 😍 To see the code where we initialize Apollo Client, check out `index.js`.

3. Debug quickly & painlessly with Apollo DevTools & GraphiQL

It looks like Apollo Client does a lot for you! How do we peek inside to understand what’s going on? With features like store inspection and full visibility into your queries & mutations, Apollo DevTools not only answers that question, but also makes debugging painless and, dare I say it, fun! 🎉 It’s available as an extension for both Chrome and Firefox, with React Native coming soon.

If you want to follow along, install Apollo DevTools for your preferred browser and navigate to our CodeSandbox from the previous example. You’ll need to run the example locally by clicking Download in the top nav bar, unzipping the file, running npm install, and finally npm start. Once you open up your browser’s dev tools panel, you should see a tab that says Apollo.

First, let’s check out our store inspector. This tab mirrors what’s currently in your Apollo Client cache, making it easy to confirm your data is stored on the client properly.

store inspector

Apollo DevTools also enables you to test your queries & mutations in GraphiQL, an interactive query editor and documentation explorer. In fact, you already used GraphiQL in the first example where we experimented with adding fields to our query. To recap, GraphiQL features auto-complete as you type your query into the editor and automatically generated documentation based on GraphQL’s type system. It’s extremely useful for exploring your schema, with zero maintenance burden for developers.

Apollo Devtools

Try executing queries with GraphiQL in the right side panel of our Launchpad. To show the documentation explorer, you can hover over fields in the query editor and click on the tooltip. If your query runs successfully in GraphiQL, you can be 100% positive that the same query will run successfully in your application.

Level up your GraphQL skills

If you made it to this point, awesome job! 👏 I hope you enjoyed the exercises and got a taste of what it would be like to work with GraphQL on the front end.

Hungry for more? 🌮 Make it your 2018 New Year’s resolution to learn more about GraphQL, as I expect its popularity to grow even more in the upcoming year. Here’s an example app to get you started featuring the concepts we learned today:

Go forth and GraphQL (and be sure to tag us on Twitter @apollographql along the way)! 🚀


A Front End Developer’s Guide to GraphQL is a post from CSS-Tricks

A Front End Developer’s Guide to GraphQL

Post pobrano z: A Front End Developer’s Guide to GraphQL

No matter how large or small your application is, you’ll have to deal with fetching data from a remote server at some point. On the front end, this usually involves hitting a REST endpoint, transforming the response, caching it, and updating your UI. For years, REST has been the status quo for APIs, but over the past year, a new API technology called GraphQL has exploded in popularity due to its excellent developer experience and declarative approach to data fetching.

In this post, we’ll walk through a couple of hands-on examples to show you how integrating GraphQL into your application will solve many pain points working with remote data. If you’re new to GraphQL, don’t panic! I’ll also highlight some resources to help you learn GraphQL using the Apollo stack, so you can start off 2018 ahead of the curve.

GraphQL 101

Before we dive into how GraphQL makes your life as a front end developer easier, we should first clarify what it is. When we talk about GraphQL, we’re either referring to the language itself or its rich ecosystem of tools. At its core, GraphQL is a typed query language developed by Facebook that allows you to describe your data requirements in a declarative way. The shape of your result matches the shape of your query: in the example below, we can expect to receive back an object with a currency property and a rates property containing an array of objects with both currency and rate keys.

{
  rates(currency: "USD") {
    currency
    rates {
      currency
      rate
    }
  }
}

When we talk about GraphQL in a broader sense, we’re often referring to the ecosystem of tools that help you implement GraphQL in your application. On the backend, you’ll use Apollo Server to create a GraphQL server, which is a single endpoint that parses a GraphQL request and returns data. How does the server know which data to return? You’ll use GraphQL Tools to build a schema (like a blueprint for your data) and a resolver map (just a series of functions that retrieve your data from a REST endpoint, database, or wherever else you choose).

This all sounds more complicated than it actually is — with Apollo Launchpad, a GraphQL server playground, you can create a working GraphQL server in your browser in less than 60 lines of code! 😮 We’ll reference this Launchpad I created that wraps the Coinbase API throughout this post.

You’ll connect your GraphQL server to your application with Apollo Client, a fast and flexible client that fetches, caches, and updates your data for you. Since Apollo Client isn’t coupled to your view layer, you can use it with React, Angular, Vue, or plain JavaScript. Not only is Apollo cross-framework, it’s also cross-platform, with React Native & Ionic supported out of the box.

Let’s give it a try! 🚀

Now that you’re well-versed in what GraphQL is, let’s get our hands dirty with a couple of practical examples that illustrate what it’s like to develop your front end with Apollo. By the end, I think you’ll be convinced that a GraphQL-based architecture with Apollo can help you ship features faster than before.

1. Add new data requirements without adding a new endpoint

We’ve all been here before: You spend hours building a perfect UI component when suddenly, product requirements change. You quickly realize that the data you need to fulfill these new requirements would either require a complicated waterfall of API requests or worse, a new REST endpoint. Now blocked on your work, you ask the backend team to build you a new endpoint just to satisfy the data needs for one component.

This common frustration no longer exists with GraphQL because the data you consume on the client is no longer coupled to an endpoint’s resource. Instead, you always hit the same endpoint for your GraphQL server. Your server specifies all of the resources it has available via your schema and lets your query determine the shape of the result. Let’s illustrate these concepts using our Launchpad from before:

In our schema, look at lines 22–26 where we define our ExchangeRate type. These fields list out all the available resources we can query in our application.

type ExchangeRate {
  currency: String
  rate: String
  name: String
}

With REST, you’re limited to the data your resource provides. If your /exchange-rates endpoint doesn’t include name, then you’ll need to either hit a different endpoint like /currency for the data or create it if it doesn’t exist.

With GraphQL, we know that name is already available to us by inspecting our schema, so we can query for it in our application. Try running this example in Launchpad by adding the name field on the right side panel!

{
  rates(currency: "USD") {
    currency
    rates {
      currency
      rate
      name
    }
  }
}

Now, remove the name field and run the same query. See how the shape of our result changes?

the data changes as you describe your query differently

Your GraphQL server always gives you back exactly the data you ask for. Nothing more. This differs significantly from REST, where you often have to filter and transform the data you get back from the server into the shape your UI components need. Not only does this save you time, it also results in smaller network payloads and CPU savings from loading and parsing the response.

2. Reduce your state management boilerplate

Fetching data almost always involves updating your application’s state. Typically, you’ll write code to track at least three actions: one for when the data is loading, one if the data successfully arrives, and one if the data errors out. Once the data arrives, you have to transform it into the shape your UI components expect, normalize it, cache it, and update your UI. This process can be repetitive, requiring countless lines of boilerplate to execute one request.

Let’s see how Apollo Client eliminates this tiresome process altogether by looking at an example React app in CodeSandbox. Navigate to `list.js` and scroll to the bottom.

export default graphql(ExchangeRateQuery, {
  props: ({ data }) => {
    if (data.loading) {
      return { loading: data.loading };
    }
    if (data.error) {
      return { error: data.error };
    }
    return {
      loading: false,
      rates: data.rates.rates
    };
  }
})(ExchangeRateList);

In this example, React Apollo, Apollo Client’s React integration, is binding our exchange rate query to our ExchangeRateList component. Once Apollo Client executes that query, it tracks loading and error state automatically and adds it to the data prop. When Apollo Client receives the result, it will update the data prop with the result of the query, which will update your UI with the rates it needs to render.

Under the hood, Apollo Client normalizes and caches your data for you. Try clicking some of the currencies in the panel on the right to watch the data refresh. Now, select a currency a second time. Notice how the data appears instantaneously? That’s the Apollo cache at work! You get all of this for free just by setting up Apollo Client with no additional configuration. 😍 To see the code where we initialize Apollo Client, check out `index.js`.

3. Debug quickly & painlessly with Apollo DevTools & GraphiQL

It looks like Apollo Client does a lot for you! How do we peek inside to understand what’s going on? With features like store inspection and full visibility into your queries & mutations, Apollo DevTools not only answers that question, but also makes debugging painless and, dare I say it, fun! 🎉 It’s available as an extension for both Chrome and Firefox, with React Native coming soon.

If you want to follow along, install Apollo DevTools for your preferred browser and navigate to our CodeSandbox from the previous example. You’ll need to run the example locally by clicking Download in the top nav bar, unzipping the file, running npm install, and finally npm start. Once you open up your browser’s dev tools panel, you should see a tab that says Apollo.

First, let’s check out our store inspector. This tab mirrors what’s currently in your Apollo Client cache, making it easy to confirm your data is stored on the client properly.

store inspector

Apollo DevTools also enables you to test your queries & mutations in GraphiQL, an interactive query editor and documentation explorer. In fact, you already used GraphiQL in the first example where we experimented with adding fields to our query. To recap, GraphiQL features auto-complete as you type your query into the editor and automatically generated documentation based on GraphQL’s type system. It’s extremely useful for exploring your schema, with zero maintenance burden for developers.

Apollo Devtools

Try executing queries with GraphiQL in the right side panel of our Launchpad. To show the documentation explorer, you can hover over fields in the query editor and click on the tooltip. If your query runs successfully in GraphiQL, you can be 100% positive that the same query will run successfully in your application.

Level up your GraphQL skills

If you made it to this point, awesome job! 👏 I hope you enjoyed the exercises and got a taste of what it would be like to work with GraphQL on the front end.

Hungry for more? 🌮 Make it your 2018 New Year’s resolution to learn more about GraphQL, as I expect its popularity to grow even more in the upcoming year. Here’s an example app to get you started featuring the concepts we learned today:

Go forth and GraphQL (and be sure to tag us on Twitter @apollographql along the way)! 🚀


A Front End Developer’s Guide to GraphQL is a post from CSS-Tricks

The Three Developers and the Insightful User Tester

Post pobrano z: The Three Developers and the Insightful User Tester

A story by Scott O’Hara:

The first of the developers, why he thought he knew best.
“I’ll get this done ever so quick!” he said, puffing out his chest.

“While the others review wikis, knowledge bases, and specifications,
I’ll lean on my deep knowledge of CSS to circumvent such onerous proclamations.

Specificity will be lax, and BEM classes will be king!
Everyone will marvel at the CSS of this thing.

Direct Link to ArticlePermalink


The Three Developers and the Insightful User Tester is a post from CSS-Tricks

The Three Developers and the Insightful User Tester

Post pobrano z: The Three Developers and the Insightful User Tester

A story by Scott O’Hara:

The first of the developers, why he thought he knew best.
“I’ll get this done ever so quick!” he said, puffing out his chest.

“While the others review wikis, knowledge bases, and specifications,
I’ll lean on my deep knowledge of CSS to circumvent such onerous proclamations.

Specificity will be lax, and BEM classes will be king!
Everyone will marvel at the CSS of this thing.

Direct Link to ArticlePermalink


The Three Developers and the Insightful User Tester is a post from CSS-Tricks

Animating Layouts with the FLIP Technique

Post pobrano z: Animating Layouts with the FLIP Technique

User interfaces are most effective when they are intuitive and easily understandable to the user. Animation plays a major role in this – as Nick Babich said, animation brings user interfaces to life. However, adding meaningful transitions and micro-interactions is often an afterthought, or something that is “nice to have” if time permits. All too often, we experience web apps that simply “jump” from view to view without giving the user time to process what just happened in the current context.

This leads to unintuitive user experiences, but we can do better, by avoiding “jump cuts” and “teleportation” in creating UIs. After all, what’s more natural than real life, where nothing teleports (except maybe car keys), and everything you interact with moves with natural motion?

In this article, we’ll explore a technique called “FLIP” that can be used to animate the positions and dimensions of any DOM element in a performant manner, regardless of how their layout is calculated or rendered (e.g., height, width, floats, absolute positioning, transform, flexbox, grid, etc.)

Why the FLIP technique?

Have you ever tried to animate height, width, top, left, or any other properties besides transform and opacity? You might have noticed that the animations look a bit janky, and there’s a reason for that. When any property that triggers layout changes (such as `height`), the browser has to recursively check if any other element’s layout has changed as a result, and that can be expensive. If that calculation takes longer than one animation frame (around 16.7 milliseconds), then the animation frame will be skipped, resulting in „jank”
since that frame wasn’t rendered in time. In Paul Lewis’ article „Pixels are Expensive”, he goes further in depth at how pixels are rendered and the various performance expenses.

In short, our goal is to be short — we want to calculate the least amount of style changes necessary, as quickly as possible. The key to this is only animating transform and opacity, and FLIP explains how we can simulate layout changes using only transform.

What is FLIP?

FLIP is a mnemonic device and technique first coined by Paul Lewis, which stands for First, Last, Invert, Play. His article contains an excellent explanation of the technique, but I’ll outline it here:

  • First: before anything happens, record the current (i.e., first) position and dimensions of the element that will transition. You can use getBoundingClientRect() for this, as will be shown below.
  • Last: execute the code that causes the transition to instantaneously happen, and record the final (i.e., last) position and dimensions of the element.*
  • Invert: since the element is in the last position, we want to create the illusion that it’s in the first position, by using transform to modify its position and dimensions. This takes a little math, but it’s not too difficult.
  • Play: with the element inverted (and pretending to be in the first position), we can move it back to its last position by setting its transform to none.

Below is how these steps can be implemented:

const elm = document.querySelector('.some-element');

// First: get the current bounds
const first = getBoundingClientRect(elm);

// execute the script that causes layout change
doSomething();

// Last: get the final bounds
const last = getBoundingClientRect(elm);

// Invert: determine the delta between the 
// first and last bounds to invert the element
const deltaX = first.left - last.left;
const deltaY = first.top - last.top;
const deltaW = first.width / last.width;
const deltaH = first.height / last.height;

// Play: animate the final element from its first bounds
// to its last bounds (which is no transform)
elm.animate([{
  transformOrigin: 'top left',
  transform: `
    translate(${deltaX}px, ${deltaY}px)
    scale(${deltaW}, ${deltaH})
  `
}, {
  transformOrigin: 'top left',
  transform: 'none'
}], {
  duration: 300,
  easing: 'ease-in-out',
  fill: 'both'
});

See the Pen How the FLIP technique works by David Khourshid (@davidkpiano) on CodePen.

There are two important things to note:

  1. If the element’s size changed, you can transform scale in order to “resize” it with no performance penalty; however, make sure to set transformOrigin to 'top left' since that’s where we based our delta calculations.
  2. We’re using the Web Animations API to animate the element here, but you’re free to use any other animation engine, such as GSAP, Anime, Velocity, Just-Animate, Mo.js and more.

Shared Element Transitions

One common use-case for transitioning an element between app views and states is that the final element might not be the same DOM element as the initial element. In Android, this is similar to a shared element transition, except that the element isn’t “recycled” from view to view in the DOM as it is on Android.

Nevertheless, we can still achieve the FLIP transition with a little magic illusion:

const firstElm = document.querySelector('.first-element');

// First: get the bounds and then hide the element (if necessary)
const first = getBoundingClientRect(firstElm);
firstElm.style.setProperty('visibility', 'hidden');

// execute the script that causes view change
doSomething();

// Last: get the bounds of the element that just appeared
const lastElm = document.querySelector('.last-element');
const last = getBoundingClientRect(lastElm);

// continue with the other steps, just as before.
// remember: you're animating the lastElm, not the firstElm.

Below is an example of how two completely disparate elements can appear to be the same element using shared element transitions. Click one of the pictures to see the effect.

See the Pen FLIP example with WAAPI by David Khourshid (@davidkpiano) on CodePen.

Parent-Child Transitions

With the previous implementations, the element bounds are based on the window. For most use cases, this is fine, but consider this scenario:

  • An element changes position and needs to transition.
  • That element contains a child element, which itself needs to transition to a different position inside the parent.

Since the previously calculated bounds are relative to the window, our calculations for the child element are going to be off. To solve this, we need to ensure that the bounds are calculated relative to the parent element instead:

const parentElm = document.querySelector('.parent');
const childElm = document.querySelector('.parent > .child');

// First: parent and child
const parentFirst = getBoundingClientRect(parentElm);
const childFirst = getBoundingClientRect(childElm);

doSomething();

// Last: parent and child
const parentLast = getBoundingClientRect(parentElm);
const childLast = getBoundingClientRect(childElm);

// Invert: parent
const parentDeltaX = parentFirst.left - parentLast.left;
const parentDeltaY = parentFirst.top - parentLast.top;

// Invert: child relative to parent
const childDeltaX = (childFirst.left - parentFirst.left)
  - (childLast.left - parentLast.left);
const childDeltaY = (childFirst.top - parentFirst.top)
  - (childLast.top - parentLast.top);
  
// Play: using the WAAPI
parentElm.animate([
  { transform: `translate(${parentDeltaX}px, ${parentDeltaY}px)` },
  { transform: 'none' }
], { duration: 300, easing: 'ease-in-out' });

childElm.animate([
  { transform: `translate(${childDeltaX}px, ${childDeltaY}px)` },
  { transform: 'none' }
], { duration: 300, easing: 'ease-in-out' });

A few things to note here, as well:

  1. The timing options for the parent and child (duration, easing, etc.) do not necessarily need to match with this technique. Feel free to be creative!
  2. Changing dimensions in parent and/or child (width, height) was purposefully omitted in this example, since it is an advanced and complex topic. Let’s save that for another tutorial.
  3. You can combine the shared element and parent-child techniques for greater flexibility.

Using Flipping.js for Full Flexibility

The above techniques might seem straightforward, but they can get quite tedious to code once you have to keep track of multiple elements transitioning. Android eases this burden by:

  • baking shared element transitions into the core SDK
  • allowing developers to identify which elements are shared by using a common android:transitionName XML attribute

I’ve created a small library called Flipping.js with the same idea in mind. By adding a data-flip-key="..." attribute to HTML elements, it’s possible to predictably and efficiently keep track of elements that might change position and dimensions from state to state.

For example, consider this initial view:

    <section class="gallery">
      <div class="photo-1" data-flip-key="photo-1">
        <img src="/photo-1"/>
      </div>
      <div class="photo-2" data-flip-key="photo-2">
        <img src="/photo-2"/>
      </div>
      <div class="photo-3" data-flip-key="photo-3">
        <img src="/photo-3"/>
      </div>
    </section>

And this separate detail view:

    <section class="details">
      <div class="photo" data-flip-key="photo-1">
        <img src="/photo-1"/>
      </div>
      <p class="description">
        Lorem ipsum dolor sit amet...
      </p>
    </section>

Notice in the above example that there are 2 elements with the same data-flip-key="photo-1". Flipping.js tracks the “active” element by choosing the first element that meet these criteria:

  • The element exists in the DOM (i.e., it hasn’t been removed or detached)
  • The element is not hidden (hint: getBoundingClientRect(elm) will have { width: 0, height: 0 } for hidden elements)
  • Any custom logic specified in the selectActive option.

Getting Started with Flipping.js

There’s a few different packages for Flipping, depending on your needs:

  • flipping.js: tiny and low-level; only emits events when element bounds change
  • flipping.web.js: uses WAAPI to animate transitions
  • flipping.gsap.js: uses GSAP to animate transitions
  • More adapters coming soon!

You can grab the minified code directly from unpkg:

Or you can npm install flipping --save and import it into your projects:

// import not necessary when including the unpkg scripts in a <script src="..."> tag
import Flipping from 'flipping/adapters/web';

const flipping = new Flipping();

// First: let Flipping read all initial bounds
flipping.read();

// execute the change that causes any elements to change bounds
doSomething();

// Last, Invert, Play: the flip() method does it all
flipping.flip();

Handling FLIP transitions as a result of a function call is such a common pattern, that the .wrap(fn) method transparently wraps (or “decorates”) the given function by first calling .read(), then getting the return value of the function, then calling .flip(), then returning the return value. This leads to much less code:

const flipping = new Flipping();

const flippingDoSomething = flipping.wrap(doSomething);

// anytime this is called, FLIP will animate changed elements
flippingDoSomething();

Here is an example of using flipping.wrap() to easily achieve the shifting letters effect. Click anywhere to see the effect.

See the Pen Flipping Birthstones #Codevember by David Khourshid (@davidkpiano) on CodePen.

Adding Flipping.js to Existing Projects

In another article, we created a simple React gallery app using finite state machines. It works just as expected, but the UI could use some smooth transitions between states to prevent “jumping” and improve the user experience. Let’s add Flipping.js into our React app to accomplish this. (Keep in mind, Flipping.js is framework-agnostic.)

Step 1: Initialize Flipping.js

The Flipping instance will live on the React component itself, so that it’s isolated to only changes that occur within that component. Initialize Flipping.js by setting it up in the componentDidMount lifecycle hook:

  componentDidMount() {
    const { node } = this;
    if (!node) return;
    
    this.flipping = new Flipping({
      parentElement: node
    });
    
    // initialize flipping with the initial bounds
    this.flipping.read();
  }

By specifying parentElement: node, we’re telling Flipping to only look for elements with a data-flip-key in the rendered App, instead of the entire document.

Then, modify the HTML elements with the data-flip-key attribute (similar to React’s key prop) to identify unique and “shared” elements:

  renderGallery(state) {
    return (
      <section className="ui-items" data-state={state}>
        {this.state.items.map((item, i) =>
          <img
            src={item.media.m}
            className="ui-item"
            style={{'--i': i}}
            key={item.link}
            onClick={() => this.transition({
              type: 'SELECT_PHOTO', item
            })}
            data-flip-key={item.link}
          />
        )}
      </section>
    );
  }
  renderPhoto(state) {
    if (state !== 'photo') return;
    
    return (
      <section
        className="ui-photo-detail"
        onClick={() => this.transition({ type: 'EXIT_PHOTO' })}>
        <img
          src={this.state.photo.media.m}
          className="ui-photo"
          data-flip-key={this.state.photo.link}
        />
      </section>
    )
  }

Notice how the img.ui-item and img.ui-photo are represented by data-flip-key={item.link} and data-flip-key={this.state.photo.link} respectively: when the user clicks on an img.ui-item, that item is set to this.state.photo, so the .link values will be equal.

And since they are equal, Flipping will smoothly transition from the img.ui-item thumbnail to the larger img.ui-photo.

Now we need to do two more things:

  1. call this.flipping.read() whenever the component will update
  2. call this.flipping.flip() whenever the component did update

Some of you might have already guessed where these method calls are going to occur: componentWillUpdate and componentDidUpdate, respectively:

  componentWillUpdate() {
    this.flipping.read();
  }
  
  componentDidUpdate() {
    this.flipping.flip();
  }

And, just like that, if you’re using a Flipping adapter (such as flipping.web.js or flipping.gsap.js), Flipping will keep track of all elements with a [data-flip-key] and smoothly transition them to their new bounds whenever they change. Here is the final result:

See the Pen FLIPping Gallery App by David Khourshid (@davidkpiano) on CodePen.

If you would rather implement custom animations yourself, you can use flipping.js as a simple event emitter. Read the documentation for more advanced use-cases.

Flipping.js and its adapters handle the shared element and parent-child transitions by default, as well as:

  • interrupted transitions (in adapters)
  • enter/move/leave states
  • plugin support for plugins such as mirror, which allows newly entered elements to “mirror” another element’s movement
  • and more planned in the future!

Resources

Similar libraries include:

  • FlipJS by Paul Lewis himself, which handles simple single-element FLIP transitions
  • React-Flip-Move, a useful React library by Josh Comeau
  • BarbaJS, not necessarily a FLIP library, but one that allows you to add smooth transitions between different URLs, without page jumps.

Further resources:


Animating Layouts with the FLIP Technique is a post from CSS-Tricks

V6: Typography and Proportions

Post pobrano z: V6: Typography and Proportions

Here’s a good ol’ fashion blog post by Rob Weychert where he looks into the new design system that he implemented on his personal website and specifically the typographic system that ties everything together:

According to the OED, a scale is “a graduated range of values forming a standard system for measuring or grading something.” A piece of music using a particular scale—a limited selection of notes with a shared mathematic relationship—can effect a certain emotional tenor. Want to write a sad song? Use a minor scale. Changed your mind? Switch to a major scale and suddenly that same song is in a much better mood.

Spatial relationships can likewise achieve a certain visual harmony using similar principles, and the constraints a scale provides take a lot of the arbitrary guesswork out of the process of arranging elements in space. Most of what I design that incorporates type has a typographic scale as its foundation, which informs the typeface choices and layout proportions. The process of creating that scale begins by asking what the type needs to do, and what role contrasting sizes will play in that.

Direct Link to ArticlePermalink


V6: Typography and Proportions is a post from CSS-Tricks

An Idea for a Simple Responsive Spreadsheet

Post pobrano z: An Idea for a Simple Responsive Spreadsheet

How do you make a spreadsheet-like interface responsive without the use of any JavaScript? This is the question I’ve been asking myself all week as I’ve been working on a new project and trying to figure out how to make the simplest spreadsheet possible. I wanted to avoid using a framework and instead, I decided to experiment with some new properties in order to use nothing but a light touch of CSS.

Spoilers! This is what I’ve come up with so far (oh and please note that this demo currently works in the latest version of Chrome). Try scrolling around a little bit:

See the Pen A Simple Responsive Spreadsheet – Final by Robin Rendle (@robinrendle) on CodePen.

Notice how the first column sticks to the left and the heading sticks to the top of the spreadsheet? This lets us scan lots of data without having to keep scrolling to figure out which column or row we’re in — in a lot of interfaces like this it’s pretty easy to get lost.

So how did I go about making this thing? Let’s jump in!

Adding the markup

First we need to add our markup for the table and, just to make sure that this example is as realistic as possible, we’re going to add a lot of rows and columns here:

See the Pen A Simple Responsive Spreadsheet – 1st by Robin Rendle (@robinrendle) on CodePen.

There’s nothing really complex going on. We just have a regular ol’ table with a <thead> and a <tbody>, but we do wrap the whole table in the table-wrapper div which I’ll explain in just a little bit.

Next, we’ll add basic styling to that wrapper element to move it into the center of the page and also give it a max-width. We also need to make sure that the .table-wrapper has overflow set to scroll, although at larger screen sizes we won’t need that just yet:

body {
  display: flex;
  font-family: -apple-system;
  font-size: 90%;
  color: #333;
  justify-content: center;
}

.table-wrapper {
  max-width: 700px;
  overflow: scroll;
}

See the Pen A Simple Responsive Spreadsheet – 2nd by Robin Rendle (@robinrendle) on CodePen.

Nifty! Now we can add styles for the first column of our table and the thead element as well as basic styling for each of the table cells:

table {
  border: 1px solid #ddd;
  border-collapse: collapse;
}

td, th {
  white-space: nowrap;
  border: 1px solid #ddd;
  padding: 20px;
}

See the Pen A Simple Responsive Spreadsheet – 3 by Robin Rendle (@robinrendle) on CodePen.

The problem here is that we’ve now made a pretty inaccessible table; although we can scroll around in the spreadsheet we can’t read which column or row is associated to which bit of data. This can lead to a table that is almost completely illegible and if we were to populate this with real data then it would be even worse:

position: sticky to the rescue!

position: sticky is a wonderfully handy CSS trick that I’ve started experimenting with a great deal lately. It lets you stick child elements to their parent containers so that as you scroll around the child element is always visible. And this is exactly what we need here for the first column and the heading of our table element.

We can use this relatively new feature with CSS like this:

// The heading of our table
th {
  background-color: #eee;
  position: sticky;
  top: -1px;
  z-index: 2;
  
  // The first cell that lives in the top left of our spreadsheet
  &:first-of-type {
    left: 0;
    z-index: 3;
  }
}

// The first column that we want to stick to the left
tbody tr td:first-of-type {
  background-color: #eee;
  position: sticky;
  left: -1px;
  z-index: 1;
}

This z-index values are important here because we want the header to overlap the first left hand column that will also be sticky. However! We also want that empty cell at the top left to overlap both our header and our left hand column, like this:

See the Pen A Simple Responsive Spreadsheet – Final by Robin Rendle (@robinrendle) on CodePen.

But there we have it! A simple responsive spreadsheet where you can view both the heading and the first column no matter where you are in the table. Although, it’s worth noting that your mileage may vary. position: sticky has relatively patchy support right now and so it’s worth thoroughly testing before you start using it. Or you could use something like Stickybits that would act as a lightweight polyfill.

Also, if you need to dig into tables in more depth then we’ve made a rather handy Complete Guide to the Table Element.


An Idea for a Simple Responsive Spreadsheet is a post from CSS-Tricks