Cards

Cards, along with List View, is a great way to contain and organize your information. Cards contain unique related data, for example, a photo, text, and link all about a single subject. Cards are typically an entry point to more complex and detailed information.

Card Layout

Lets look at a basic card HTML layout

<div class="card">
  <div class="card-header">Header</div>
  <div class="card-content">
    <!-- Card content -->
  </div>
  <div class="card-footer">Footer</div>
</div>

<div class="card">
  <div class="card-header">Header</div>
  <div class="card-content card-content-padding">
    <!-- Card content -->
  </div>
  <div class="card-footer">Footer</div>
</div>

<div class="card card-outline">
  <div class="card-header">Header</div>
  <div class="card-content">
    <!-- Card content -->
  </div>
  <div class="card-footer">Footer</div>
</div>

Where:

  • <div class="card"> - Card container

    • <div class="card-header"> - Card header. Mostly used to display card title. Optional

    • <div class="card-footer"> - Card footer is used for some additional information or for custom actions/links. Optional

    • <div class="card-content"> - Main container for card content. Required

    • <div class="card-content card-content-padding"> - Additional card-content-padding used to add extra padding to card-content

    • card-outline - additional class that can be added to card element to make it outline

    • no-shadow - additional class that can be added to card element to remove its shadow

    • no-border - additional class that can be added to card element to remove its border (for outline card)

Note that "card-header" and "card-footer" have a flexbox layout (display:flex) where as items have a center vertical alignment. If you need to align items to top or to bottom of header/footer, then you may use additional typography classes, for example:

<div class="card-header align-items-flex-start"> - align header items by header top line

<div class="card-footer align-items-flex-end"> - align footer items by footer bottom line

Expandable Cards

Expandable Cards (aka AppStore cards) is a subset of usual Cards which expand on click to full screen size on mobile and to larger size on tablet.

Expandable Cards Layout

It has a bit different and simplified layout:

<!-- addition "card-expandable" class on card to make it expandable -->
<div class="card card-expandable">
  <!-- card content -->
  <div class="card-content">
    <!-- put all content here -->
  </div>
</div>

Where

  • card-expandable - addition class on card element to make it expandable
  • card-content - only place here to put any card content

So all the extra elements like card-content-padding, card-header, card-footer must be placed inside of card-content when card is expandable.

Expandable Card Size

By default expandable card opens to fixed size on tablet/desktops. To make expandable card to open to full screen size on tablet/desktop screen additional card-tablet-fullscreen class required on card element. Otherwise you can configure this size using --f7-card-expandable-tablet-width and --f7-card-expandable-tablet-height CSS variables.

Expandable card content (card-content) is set to 100vw width when collapsed (closed). It is done to improve card open/close transition performance, so you need to take care about its content positioning. You can make its content width also animatable and responsive by adding additional card-expandable-animate-width class to card element, but performance can be worse in this case.

Hide Elements On Open/Close

Expandable card has 2 states: closed and opened. And it is possible to hide/show card's elements by using these two classes:

  • card-opened-fade-in - element with such class inside of card-content will have 0 opacity when card closed, and it will fade to 1 opacity on card open.
  • card-opened-fade-out - element with such class inside of card-content will have 1 opacity when card closed, and it will fade to 0 opacity on card open.

Prevent Card From Opening

In some layouts you may have a button or link in visible area or expandable card when it is collapsed. To allow click on such button or link and to prevent expandable card from opening, we need to add card-prevent-open class to this button:

<div class="card card-expandable">
  <div class="card-content">
    ...
    <!-- Add "card-prevent-open" to element and click on it won't open expandable card -->
    <a href="#" class="button card-prevent-open">Button</a>
  </div>
</div>

Expandable Card Backdrop

If you have enabled expandable card backdrop (enabled by default, see parameters below), then it will automatically add backdrop element (darken overlay behind the card) on card open to card parent page.

In some layouts you may need to place such backdrop element in custom place. In this case we need to manually add this element and specify it in card's data-backdrop-el attribute:

<div class="block">
  <!-- custom backdrop element -->
  <div class="card-backdrop custom-backdrop"></div>
  <!-- pass its CSS selector in data-backdrop-el attribute -->
  <div class="card card-expandable" data-backdrop-el=".custom-backdrop">
    ...
  </div>
</div>

Card App Methods

Let's look at related App methods to work with expandable cards:

app.card.open(el, animate)- open expandable card

  • el - HTMLElement or string (with CSS Selector). Expandable card to open.
  • animate - boolean. Opens expandable card with animation. By default is true

app.card.close(el, animate)- close expandable card

  • el - HTMLElement or string (with CSS Selector). Expandable card to close.
  • animate - boolean. Closes expandable card with animation. By default is true

app.card.toggle(el, animate)- toggle expandable card

  • el - HTMLElement or string (with CSS Selector). Expandable card to toggle.
  • animate - boolean. Toggle expandable card with animation. By default is true

Card App Parameters

It is possible to control some default Cards behavior using global app parameters by passing Cards related parameters under card parameter:

ParameterTypeDefaultDescription
hideNavbarOnOpenbooleantrueWill hide Navbar on expandable card open.
hideToolbarOnOpenbooleantrueWill hide Toolbar on expandable card open.
hideStatusbarOnOpenbooleantrueWill hide "Statusbar" (or fully hide Navbar) on expandable card open.
swipeToClosebooleantrueAllows to close expandable card with swipe.
backdropbooleantrueEnables expandable card backdrop layer.
closeByBackdropClickbooleantrueWhen enabled, expandable card will be closed on its backdrop click.

For example:

var app = new Framework7({
  card: {
    hideNavbarOnOpen: false,
    closeByBackdropClick: false,
  },
});

In addition, all these paramteres can be set on each expandable card individually with same data- attributes, including additional data-animate attribute:

<!-- this card will opened without animation -->
<div class="card card-expandable" data-animate="false">
  ...
</div>

<!-- this card will opened without backdrop -->
<div class="card card-expandable" data-backdrop="false">
  ...
</div>

It is possible to open and close required expandable cards using special classes and data attributes on links:

  • To open expandable card we need to add "card-open" class to any HTML element (prefered to link)

  • To close expandable we need to add "card-close" class to any HTML element (prefered to link)

  • If you have more than one expandable cards in DOM, you need to specify appropriate card via additional data-card=".my-card" attribute on this HTML element

Card Events

Expandable card will fire the following DOM events on card element and events on app instance:

DOM Events

EventTargetDescription
card:beforeopenCard Element<div class="card">Event will be triggered right before expandable card starts its opening animation. event.detail.prevent contains function that will prevent card from opening when called
card:openCard Element<div class="card">Event will be triggered when expandable card starts its opening animation
card:openedCard Element<div class="card">Event will be triggered after expandable card completes its opening animation
card:closeCard Element<div class="card">Event will be triggered when expandable card starts its closing animation
card:closedCard Element<div class="card">Event will be triggered after expandable card completes its closing animation

App Instance Events

EventArgumentsDescription
cardBeforeOpen(el, prevent)Event will be triggered right before expandable card starts its opening animation. prevent contains function that will prevent expandable card from opening when called
cardOpen(el)Event will be triggered when expandable card starts its opening animation. As an argument event handler received card HTML element
cardOpened(el)Event will be triggered after expandable card completes its opening animation. As an argument event handler received card HTML element
cardClose(el)Event will be triggered when expandable card starts its closing animation. As an argument event handler received card HTML element
cardClosed(el)Event will be triggered after expandable card completes its closing animation. As an argument event handler received card HTML element

CSS Variables

Below is the list of related CSS variables (CSS custom properties).

:root {
  --f7-card-margin-horizontal: 16px;
  --f7-card-margin-vertical: 16px;
  --f7-card-content-padding-horizontal: 16px;
  --f7-card-content-padding-vertical: 16px;
  --f7-card-border-radius: 4px;
  --f7-card-font-size: inherit;
  --f7-card-header-text-color: inherit;
  --f7-card-header-font-weight: 400;
  --f7-card-header-padding-horizontal: 16px;
  --f7-card-footer-font-weight: 400;
  --f7-card-footer-font-size: inherit;
  --f7-card-footer-padding-horizontal: 16px;
  --f7-card-expandable-font-size: 16px;
  --f7-card-expandable-tablet-width: 670px;
  --f7-card-expandable-tablet-height: 670px;
  --f7-card-bg-color: #fff;
  --f7-card-outline-border-color: rgba(0, 0, 0, 0.12);
  --f7-card-header-border-color: rgba(0, 0, 0, 0.1);
  --f7-card-footer-border-color: rgba(0, 0, 0, 0.1);
  --f7-card-expandable-bg-color: #fff;
}
:root .dark,
:root.dark {
  --f7-card-bg-color: #1c1c1d;
  --f7-card-expandable-bg-color: #1c1c1d;
  --f7-card-outline-border-color: rgba(255, 255, 255, 0.15);
  --f7-card-header-border-color: rgba(255, 255, 255, 0.15);
  --f7-card-footer-border-color: rgba(255, 255, 255, 0.15);
  --f7-card-footer-text-color: rgba(255, 255, 255, 0.55);
}
.ios {
  --f7-card-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.2);
  --f7-card-header-font-size: 17px;
  --f7-card-header-padding-vertical: 10px;
  --f7-card-header-min-height: 44px;
  --f7-card-footer-text-color: rgba(0, 0, 0, 0.45);
  --f7-card-footer-padding-vertical: 10px;
  --f7-card-footer-min-height: 44px;
  --f7-card-expandable-margin-horizontal: 20px;
  --f7-card-expandable-margin-vertical: 30px;
  --f7-card-expandable-box-shadow: 0px 20px 40px rgba(0, 0, 0, 0.3);
  --f7-card-expandable-border-radius: 15px;
  --f7-card-expandable-tablet-border-radius: 5px;
  --f7-card-expandable-header-font-size: 27px;
  --f7-card-expandable-header-font-weight: bold;
}
.md {
  --f7-card-box-shadow: var(--f7-elevation-1);
  --f7-card-header-font-size: 16px;
  --f7-card-header-padding-vertical: 4px;
  --f7-card-header-min-height: 48px;
  --f7-card-footer-text-color: rgba(0, 0, 0, 0.54);
  --f7-card-footer-padding-vertical: 4px;
  --f7-card-footer-min-height: 48px;
  --f7-card-expandable-margin-horizontal: 12px;
  --f7-card-expandable-margin-vertical: 24px;
  --f7-card-expandable-box-shadow: var(--f7-elevation-10);
  --f7-card-expandable-border-radius: 8px;
  --f7-card-expandable-tablet-border-radius: 4px;
  --f7-card-expandable-header-font-size: 24px;
  --f7-card-expandable-header-font-weight: 500;
}
.aurora {
  --f7-card-border-radius: 8px;
  --f7-card-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.15);
  --f7-card-header-font-size: 16px;
  --f7-card-header-font-weight: bold;
  --f7-card-header-padding-vertical: 8px;
  --f7-card-header-min-height: 48px;
  --f7-card-footer-text-color: rgba(0, 0, 0, 0.6);
  --f7-card-footer-padding-vertical: 8px;
  --f7-card-footer-min-height: 48px;
  --f7-card-expandable-margin-horizontal: 10px;
  --f7-card-expandable-margin-vertical: 20px;
  --f7-card-expandable-box-shadow: 0px 10px 20px rgba(0, 0, 0, 0.2);
  --f7-card-expandable-border-radius: 8px;
  --f7-card-expandable-tablet-border-radius: 4px;
  --f7-card-expandable-header-font-size: 24px;
  --f7-card-expandable-header-font-weight: bold;
}

Examples

<template>
  <div class="page">
    <div class="navbar">
      <div class="navbar-bg"></div>
      <div class="navbar-inner">
        <div class="title">Cards</div>
      </div>
    </div>
    <div class="page-content">
      <div class="block-title">Simple Cards</div>
      <div class="card">
        <div class="card-content card-content-padding">This is a simple card with plain text, but cards can also
          contain their own header, footer, list view, image, or any other element.</div>
      </div>
      <div class="card">
        <div class="card-header">Card header</div>
        <div class="card-content card-content-padding">Card with header and footer. Card headers are used to display
          card titles and footers for additional information or just for custom actions.</div>
        <div class="card-footer">Card Footer</div>
      </div>
      <div class="card">
        <div class="card-content card-content-padding">Another card. Lorem ipsum dolor sit amet, consectetur
          adipiscing elit. Suspendisse feugiat sem est, non tincidunt ligula volutpat sit amet. Mauris aliquet magna
          justo. </div>
      </div>
      <div class="block-title">Outline Cards</div>
      <div class="card card-outline">
        <div class="card-content card-content-padding">This is a simple card with plain text, but cards can also
          contain their own header, footer, list view, image, or any other element.</div>
      </div>
      <div class="card card-outline">
        <div class="card-header">Card header</div>
        <div class="card-content card-content-padding">Card with header and footer. Card headers are used to display
          card titles and footers for additional information or just for custom actions.</div>
        <div class="card-footer">Card Footer</div>
      </div>
      <div class="card card-outline">
        <div class="card-content card-content-padding">Another card. Lorem ipsum dolor sit amet, consectetur
          adipiscing elit. Suspendisse feugiat sem est, non tincidunt ligula volutpat sit amet. Mauris aliquet magna
          justo. </div>
      </div>
      <div class="block-title">Styled Cards</div>
      <div class="card demo-card-header-pic">
        <div style="background-image:url(https://cdn.framework7.io/placeholder/nature-1000x600-3.jpg)"
          class="card-header align-items-flex-end">Journey To Mountains</div>
        <div class="card-content card-content-padding">
          <p class="date">Posted on January 21, 2015</p>
          <p>Quisque eget vestibulum nulla. Quisque quis dui quis ex ultricies efficitur vitae non felis. Phasellus
            quis nibh hendrerit...</p>
        </div>
        <div class="card-footer"><a href="#" class="link">Like</a><a href="#" class="link">Read more</a></div>
      </div>
      <div class="card demo-card-header-pic">
        <div style="background-image:url(https://cdn.framework7.io/placeholder/people-1000x600-6.jpg)"
          class="card-header align-items-flex-end">Lorem Ipsum</div>
        <div class="card-content card-content-padding">
          <p class="date">Posted on January 21, 2015</p>
          <p>Quisque eget vestibulum nulla. Quisque quis dui quis ex ultricies efficitur vitae non felis. Phasellus
            quis nibh hendrerit...</p>
        </div>
        <div class="card-footer"><a href="#" class="link">Like</a><a href="#" class="link">Read more</a></div>
      </div>
      <div class="block-title">Facebook Cards</div>
      <div class="card demo-facebook-card">
        <div class="card-header">
          <div class="demo-facebook-avatar"><img src="https://cdn.framework7.io/placeholder/people-68x68-1.jpg"
              width="34" height="34" /></div>
          <div class="demo-facebook-name">John Doe</div>
          <div class="demo-facebook-date">Monday at 3:47 PM</div>
        </div>
        <div class="card-content"> <img src="https://cdn.framework7.io/placeholder/nature-1000x700-8.jpg"
            width="100%" /></div>
        <div class="card-footer"><a href="#" class="link">Like</a><a href="#" class="link">Comment</a><a href="#"
            class="link">Share</a></div>
      </div>
      <div class="card demo-facebook-card">
        <div class="card-header">
          <div class="demo-facebook-avatar"><img src="https://cdn.framework7.io/placeholder/people-68x68-1.jpg"
              width="34" height="34" /></div>
          <div class="demo-facebook-name">John Doe</div>
          <div class="demo-facebook-date">Monday at 2:15 PM</div>
        </div>
        <div class="card-content card-content-padding">
          <p>What a nice photo i took yesterday!</p><img
            src="https://cdn.framework7.io/placeholder/nature-1000x700-8.jpg" width="100%" />
          <p class="likes">Likes: 112 &nbsp;&nbsp; Comments: 43</p>
        </div>
        <div class="card-footer"><a href="#" class="link">Like</a><a href="#" class="link">Comment</a><a href="#"
            class="link">Share</a></div>
      </div>
      <div class="block-title">Cards With List View</div>
      <div class="card">
        <div class="card-content">
          <div class="list links-list no-ios-edges">
            <ul>
              <li><a href="#">Link 1</a></li>
              <li><a href="#">Link 2</a></li>
              <li><a href="#">Link 3</a></li>
              <li><a href="#">Link 4</a></li>
              <li><a href="#">Link 5</a></li>
            </ul>
          </div>
        </div>
      </div>
      <div class="card">
        <div class="card-header">New Releases:</div>
        <div class="card-content">
          <div class="list media-list no-ios-edges">
            <ul>
              <li class="item-content">
                <div class="item-media">
                  <img src="https://cdn.framework7.io/placeholder/fashion-88x88-4.jpg" width="44" />
                </div>
                <div class="item-inner">
                  <div class="item-title-row">
                    <div class="item-title">Yellow Submarine</div>
                  </div>
                  <div class="item-subtitle">Beatles</div>
                </div>
              </li>
              <li class="item-content">
                <div class="item-media">
                  <img src="https://cdn.framework7.io/placeholder/fashion-88x88-5.jpg" width="44" />
                </div>
                <div class="item-inner">
                  <div class="item-title-row">
                    <div class="item-title">Don't Stop Me Now</div>
                  </div>
                  <div class="item-subtitle">Queen</div>
                </div>
              </li>
              <li class="item-content">
                <div class="item-media">
                  <img src="https://cdn.framework7.io/placeholder/fashion-88x88-6.jpg" width="44" />
                </div>
                <div class="item-inner">
                  <div class="item-title-row">
                    <div class="item-title">Billie Jean</div>
                  </div>
                  <div class="item-subtitle">Michael Jackson</div>
                </div>
              </li>
            </ul>
          </div>
        </div>
        <div class="card-footer"> <span>January 20, 2015</span><span>5 comments</span></div>
      </div>
      <div class="block-title">Expandable Cards</div>
      <div class="card card-expandable">
        <div class="card-content">
          <div class="bg-color-red" style="height: 300px">
            <div class="card-header text-color-white display-block">Framework7<br />
              <small style="opacity: 0.7">Build Mobile Apps</small>
            </div>
            <a href="#" class="link card-close card-opened-fade-in color-white"
              style="position: absolute; right: 15px; top: 15px">
              <i class="icon f7-icons">xmark_circle_fill</i>
            </a>
          </div>
          <div class="card-content-padding">
            <p>Framework7 - is a free and open source HTML mobile framework to develop hybrid mobile apps or web
              apps with iOS or Android (Material) native look and feel. It is also an indispensable prototyping apps
              tool to show working app prototype as soon as possible in case you need to.</p>
            <p>The main approach of the Framework7 is to give you an opportunity to create iOS and Android
              (Material) apps with HTML, CSS and JavaScript easily and clear. Framework7 is full of freedom. It
              doesn't limit your imagination or offer ways of any solutions somehow. Framework7 gives you freedom!
            </p>
            <p>Framework7 is not compatible with all platforms. It is focused only on iOS and Android (Material) to
              bring the best experience and simplicity.</p>
            <p>Framework7 is definitely for you if you decide to build iOS and Android hybrid app (Cordova or
              Capacitor) or web app that looks like and feels as great native iOS or Android (Material) apps.</p>
          </div>
        </div>
      </div>
      <div class="card card-expandable">
        <div class="card-content">
          <div class="bg-color-yellow" style="height: 300px">
            <div class="card-header text-color-black display-block">Framework7<br />
              <small style="opacity: 0.7">Build Mobile Apps</small>
            </div>
            <a href="#" class="link card-close card-opened-fade-in color-black"
              style="position: absolute; right: 15px; top: 15px">
              <i class="icon f7-icons">xmark_circle_fill</i>
            </a>
          </div>
          <div class="card-content-padding">
            <p>Framework7 - is a free and open source HTML mobile framework to develop hybrid mobile apps or web
              apps with iOS or Android (Material) native look and feel. It is also an indispensable prototyping apps
              tool to show working app prototype as soon as possible in case you need to.</p>
            <p>The main approach of the Framework7 is to give you an opportunity to create iOS and Android
              (Material) apps with HTML, CSS and JavaScript easily and clear. Framework7 is full of freedom. It
              doesn't limit your imagination or offer ways of any solutions somehow. Framework7 gives you freedom!
            </p>
            <p>Framework7 is not compatible with all platforms. It is focused only on iOS and Android (Material) to
              bring the best experience and simplicity.</p>
            <p>Framework7 is definitely for you if you decide to build iOS and Android hybrid app (Cordova or
              Capacitor) or web app that looks like and feels as great native iOS or Android (Material) apps.</p>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<style>
  .demo-card-header-pic .card-header {
    height: 40vw;
    background-size: cover;
    background-position: center;
    color: #fff;
  }

  .demo-card-header-pic .card-content-padding .date {
    color: #8e8e93;
  }

  .demo-facebook-card .card-header {
    display: block;
    padding: 10px;
  }

  .demo-facebook-card .demo-facebook-avatar {
    float: left;
  }

  .demo-facebook-card .demo-facebook-name {
    margin-left: 44px;
    font-size: 14px;
    font-weight: 500;
  }

  .demo-facebook-card .demo-facebook-date {
    margin-left: 44px;
    font-size: 13px;
    color: #8e8e93;
  }

  .demo-facebook-card .card-footer {
    background: #fafafa;
  }

  .demo-facebook-card .card-footer a {
    color: #81848b;
    font-weight: 500;
  }

  .demo-facebook-card .card-content img {
    display: block;
  }

  .demo-facebook-card .card-content-padding {
    padding: 15px 10px;
  }

  .demo-facebook-card .card-content-padding .likes {
    color: #8e8e93;
  }
</style>