Responsive Cards on Foundation + AngularJs


Foundation Cards Example

Cards are a clean, consise means of displaying content composed of different types of objects. They’re also well-suited for presenting similar objects whose size or supported actions can vary considerably, like headings and photos with captions.

I will use Zurb's Foundation for the responsive grid, but the could easily swapped out with Bootstrap, PureCSS or the frontend framework of your choice.

The Angular Controller

Here's the simple controller that's used to fetch the user data from the RandomUser.me API. In a real AngularJs app you'd most likely move the $http get out to a user service, and then simply do something like userService.get() in the controller. This populates the $scope.users var that will be used to construct the panels using ng-repeat...

var myApp = angular.module('myApp', []);  
myApp.controller('mainCtrl', function Main($scope, $http){  
  $http.get('http://api.randomuser.me/?results=24').success(function(data) {
    $scope.users = data.results;
  }).error(function(data, status) {
    console.log('data error..');
  });
});

The HTML Structure

Each card is simply a Foundation panel wrapped in a 3 column grid. I'm using the Foundation medium grid so the cards will vertically stack on smaller screen widths.

<div class="row" ng-controller="mainCtrl">  
    ...
    <div class="column medium-4 animated" ng-repeat="u in users">
        <div class="panel text-center">
            <img class="circle" src="{{u.user.picture.medium}}">
            <h3 class="ellipsis">{{u.user.username}}</h3>
            <p class="ellipsis-2">{{u.user.slogan}}</p>
            <hr>
            <div class="medium-12 sm-centered lg-centered column">
                <ul class="small-block-grid-4 text-center">
                    <li><a href=""><i class="fa fa-pinterest fa-2x"></i></a></li>
                     ...
                </ul>
            </div>
            <hr>
            <a href="#" class="ellipsis">{{u.user.location.city}}, {{u.user.location.state}}</a>
        </div>
    </div>
</div>  

A Few CSS Changes

A little CSS is added to handle the text overflow, and to create the circle user images in each card. The ellipsis CSS class handle single line overflow since headings may vary in length. Also, the ellipsis-2 CSS class handles two-line overflow, so that descriptions inside the card show "..." instead of wrapping to another line. This enables each panel to be the same height.

body {  
    background-color:#5682B4;
}

.circle {
  border-radius: 50%;
}

/* css3 2 line ellipsis for text overflow */
.ellipsis-2 {
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.panel h3, .ellipsis {
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}

A Few More Tweaks

For CSS animation, I'm using Dan Eden's animate.css. You'll see in the markup that AngularJS' ng-class-odd and ng-class-even can be used to switch styles on each panel rendered by the ng-repeat. The effect is that each panel alternates slide in from the left and right.

<div class="column medium-4 animated" ng-class-odd="'slideInLeft'" ng-class-even="'slideInRight'" ng-repeat="u in users">

Demo the alternating version

Alternately, you can create a staggered / cascading effect by adding a style delay to the -animation-duration used by the animate.css animated class. You don't need angular-animate for this since it's using the animate.css classes.

<div class="column medium-4 animated fadeInUp" style="-webkit-animation-duration:{{$index * 200}}ms" ng-repeat="u in users">

Demo the staggered version


Here's the Full Code & Demo

So there's another Foundation nugget for you. Find more at responsive examples and snippets at Codeply