Creating a Flippable Cards UI

Cards keep showing up everywhere I look. Twitter has cards. Google has cards and cards are everywhere in Material Design. Cards are also showing up in mobile apps, such as Tinder (not that I would know anything about that).

Cards are so hot right now that some are even proclaiming them the “future of the web”. I’m not entirely convinced that a div with a drop shadow is the future of anything, but I’ve been wrong before.

Real Cards Flip

What I DO like are interaction designs and concepts that build on physical concepts that we already know, since that’s primarily how we interact with our world. We used to call this “skeuomorphic” until someone decided it was terrible and everything should look like a disabled button or link. Perhaps there is a happy medium between lots of green felt and having no idea what state a button is in.

In the spirit of those physical interactions, one that cards afford us is the concept of having two sides.

A card on your desk would have a front and a back. You would be able to physically pick that card up and turn it over. It can have just as much information on the front as it does on the back. If you can’t flip it over, it’s not a card – it’s a sticker.

I took a look at what it takes to create a cards UI using my favorite open source UI library: Kendo UI Core. I came up with an app which displays albums for my favorite band. On the front is album information. Clicking or tapping the album flips it around to display a list of tracks on the back which can then be previewed (assuming your browser supports Web Audio). All of this data comes from the iTunes Search API.

View Full Page Demo

Introducing Kendo Flippable

I’m using the open source Kendo UI Core library for that app since it provides everything I need for binding, remote data, touch interactions, navbars, listviews and even the flip effect itself. I’m also using Bootstrap since I suck at CSS. Hard.

Kendo UI Core exposes an fx API that has a Flip method. The trouble with this effect is that it requires very specific markup with very specific CSS.

I might have mentioned that I suck at CSS, so I have a hard time getting this particular effect right. To prevent that from happening again, I created the Kendo Flippable Plugin. Its sole job is to be a leaky abstraction around the Flip effect that Kendo UI provides. To use it, you simply need a <div> with two inner <div>s which represent the front and back of the card.

<div id="card">
  <div id="front">
    <h1>Front</h1>
  </div>
  <div id="back">
    <h1>Back</h1>
  </div>
</div>

Then you select the element with jQuery and call the kendoFlippable method on it.

(function() {

  $('#card').kendoFlippable();

}());

It doesn’t look like much at the moment, but the Flippable actually applied some very important CSS settings for us:

  • Set position: relative on <div id="card">
  • Set position: absolute; height: 100%; width: 100% on <div id="front"> and <div id="back">

The net effect of these CSS settings is that the front and back of the card are stacked on top of each other. It’s imperative that the elements be structured this way for a flip effect to work.

Also, there are a few interesting quirks here…

  • Cards HAVE to have a static height. If you do not set a height, it defaults to the height of the content on the front of the card. You can set the height either via the API on initialization or using CSS – your choice.
  • Both the front and back of the card have a class of k-header set which gives them a background. If the card did not have a set background, the content on the other side would be visible and things would look like a jumbled mess.
  • Cards are responsive by default. The width will always be 100% of the container. You can change this by giving the card a width either via the API or via CSS.

Knowing all of this, lets give the card a set height and width so that it looks more like a card. Again, this can be done in CSS, I’m just doing it through the API.

(function() {

  $('#card').kendoFlippable({
    height: 250,
    width: 300
  });

}());

Now we’re looking more like a card. So how do we flip it to the back?

To flip a card, you need to get a reference to it and then call the method to flip it in the direction of your choice. The flipHorizontal method flips the card horizontally and the the flipVertical flips it vertically.

To get a reference to a Kendo UI widget, select the element on which the widget was initialized, and then call data("kendoFlippable"), in keeping with jQuery plugin best practices. For the sake of convenience, I have added a click method on the card which has a reference to the widget directly via this.

While the following example uses this to get the widget reference, it’s also available via the function argument e via e.sender.

(function() {

  $('#card').kendoFlippable({
    height: 250,
    width: 300,
    click: function(e) {
      this.flipHorizontal();
    }
  });

}());

And NOW we have a flipping card. The card will automatically flip from front to back and it flips in the reverse direction to simulate “flipping back”. It only flips between front and back as a card has two sides. Any more sides and it would be a dodecahedron or something.

How Does This Work?

Given the abstraction, it’s not necessary, but still interesting to know what Kendo UI is doing under the covers to pull off this flip in 3D space.

When the Flippable is initialized, it absolutely positions the front and back elements (as we already discussed) so that they are on top of each other. It then creates an underlying kendo.fx flipHorizontal (or vertical) effect specifying the front and back divs – like this:

// element = $("#card");
// front = $("#front");
// back = $("#back");

that.effect = kendo.fx(element).flipHorizontal(front, back);

Under the covers, kendo.fx translates this flipHorizontal or flipVertical to the turningPage effect which is another effect available off of the kendo.fx object. This is so we can get more effects with less code by reusing some of the same effects. A page flip and a turn are quite similar.

At this point, Kendo UI kicks into CSS3 mode.

Everything You Never Wanted To Know About CSS3 Animation

TL;DR – 3D animation is a hard concept to wrap your brain around and Kendo UI does everything for you.

Once the effect kicks in, Kendo UI will set a perspective: 1500px on the card element. CSS3 perspective is a bit difficult to understand because thinking in 3D on a 2D surface (a screen) is frustrating. Perspective is how far away you are from the Z plane as explained by Chris Coyer.

Let’s think about the Z plane like this: If the X plane goes from left to right, and the Y plane goes up and down, the Z plane goes from your eye straight back into the middle of the element indefinitely. Z is the third dimension. Kendo UI reserves a big block of 3D space by setting a large perspective so that the effect will be more crisp and impressive. If you were to reduce the perspective, the effect would become less and less pronounced.

Here is another way to think about the effect of a larger perspective: If you were in a phone booth, you might not be able to turn around. If you were in a closet, you would be able to turn around easily. If you were in a large room, you would be able to turn around with your arms out while screaming “I’M THE KING OF THE WORLD!”.

83438808_018df09d56_o

Try to focus up now Leo. This is serious business.

This 3D space is then preserved for the child elements which also get a perspective: 1500px set on them so that their children will transform in the 3D space as well.

Next, Kendo UI attaches transform: rotateY(180%) to the front of the card. This rotates the card on the Y axis in Z perspective. If you were to flip the card vertically, it would flip it on the X axis.

Once the front of the card gets to 180 degrees, it’s as if you are looking at a card by holding it flat it front of your eye. An actual card has thickness, but these do not so at this point, you cannot see the front of the card because it has been flattened. It is then given a display: none and the back is rotated from a flattened position to 0% achieving the desired flipping effect.

All of this is animated by giving the <div id="card"> and its children a transition: all 800ms easeout. The 800ms can be changed by setting the duration configuration property of the Flippable.

Some Notes On Styling Flippable Cards

In the spirit of Kendo UI the card doesn’t do a lot of styling for you when it comes to the contents. By default, the back and front sides get a class of k-header which gives them a background color. Feel free to override this with a background color of your choosing.

Since the cards have a relative positioning set, they will not respect your padding and margin. This can be rectified by setting box-sizing: border-box on the card AND the front and back. The reason why I didn’t do this in the plugin is that any styles the plugin sets get done inline and they become virtually impossible to override. If you are using a CSS framework like Bootstrap, it will automatically set box-sizing for you and you won’t even have to worry about this quirk.

Flip Some Stuff

Flipping cards are a really nice little UI trick to have at your disposal. I really enjoyed putting this project together. Also, since our cards are digital, we can do things like scroll content inside of them. These are things that a physical card cannot do, but it would be crazy Harry Potter cool if they could.

Cards combined with other Kendo UI elements like the NavBar and ListView make for a wonderful experience. Make sure to “view source” on the demo. All of the code is in the index page. There are some interesting items in there in terms of MVVM and styling.

Photo: “Titanic” by Nick O’Leary
Header image: “Playing Cards” by Rocco Lucia

Comments

  • kynao

    Hi,
    Thanks for sharing this. What i would see as even more wonderful is an “advanced listview”, ie portlets so e can drag each element in an organized layout, check this demo http://dev.sencha.com/ext/5.0.1/examples/portal/index.html, unhappily, i didn’t see any equivalent available out of extjs

  • kynao

    Hi,
    Thanks for sharing this. What i would see as even more wonderful is an “advanced listview”, ie portlets so e can drag each element in an organized layout, check this demo http://dev.sencha.com/ext/5.0.1/examples/portal/index.html, unhappily, i didn’t see any equivalent available out of extjs

    • burkeholland

      Oh! I like this a lot. It should be pretty easy with the Sortable. Did you check out the sortable panels demo?

      http://demos.telerik.com/kendo-ui/sortable/sortable-panels

      • kynao

        Apparently, contrary to the extjs demo :
        – you can’t change the number of colums here. In this example, you have 2 columns, the user can’t switch to 3, then back to 2 columns if he wants or switch to only one colunn.
        – you can’t, for example, have 3 columns and porlets in each, then having below a portlet having the width of all the 3 columns

        – you can’t resize the portlets, ie column width; and can’t resize the portlets height independently

        Would Kendo allow to achieve such things ?

        • burkeholland

          Yep – check out the panels which are resizable and have an API for adding and removing new ones…

          http://demos.telerik.com/kendo-ui/splitter/index

          • kynao

            Humm, i guess that would much deserve a part 2 of this article 🙂

            For remark 1 : the api would allow to change the number of columns live (runtime) ? so eventually the user could have the number of columns he wants ?

            For remark 2 : what is the idea ? a sortable in each splitted pane ? then we drag&drop a sortable from one splitted pane to another ?

            For remark 3 : i can’t see how the splitter allows to resize easily a portlet height independently

          • kynao

            The idea is also to have, like the provided extjs example show, “portlets”, ie draggable windows (http://www.jqwidgets.com/jquery-widgets-demo/demos/jqxdocking/index.htm#demos/jqxdocking/defaultfunctionality.htm), so that we have a title bar in which we can have title icon buttons (minimize, close, etc…)

          • kynao

            Do you have something in mind to achieve this and share it whatever with an article or a download ?

      • kynao

        From my point of view, it’s easier to use the extjs portal element and make the content flip, still for free

  • Pingback: Mobile Design that Scales -Telerik Developer Network()

  • Strkli

    I’m using AppBuilder in the browser, created a Kendo UI Blank project and uploaded the flappable-cards-master zip in the Plugin dialog. I’m just not getting it to work. The instructions I’ve been following asked for a plugin.xml manifest which isn’t in the zip file, and I have no idea if the plugin is Cordova compatible. This is the only thing I can imagine that might be causing the project to not work. Can you offer any advice?