Cards
- Card Layout
- Expandable Cards
- Card App Methods
- Card App Parameters
- Control Cards With Links
- Card Events
- CSS Variables
- Examples
Cards, along with List View, is a great way to contain and orginize 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-contentcard-outline
- additional class that can be added to card element to make it outlineno-shadow
- additional class that can be added to card element to remove its shadowno-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 expandablecard-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 have0
opacity when card closed, and it will fade to1
opacity on card open.card-opened-fade-out
- element with such class inside of card-content will have1
opacity when card closed, and it will fade to0
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:
Parameter | Type | Default | Description |
---|---|---|---|
hideNavbarOnOpen | boolean | true | Will hide Navbar on expandable card open. |
hideToolbarOnOpen | boolean | true | Will hide Toolbar on expandable card open. |
swipeToClose | boolean | true | Allows to close expandable card with swipe. |
backdrop | boolean | true | Enables expandable card backdrop layer. |
closeByBackdropClick | boolean | true | When 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>
Control Cards With Links
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
Event | Target | Description |
---|---|---|
card:beforeopen | Card 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:open | Card Element<div class="card"> | Event will be triggered when expandable card starts its opening animation |
card:opened | Card Element<div class="card"> | Event will be triggered after expandable card completes its opening animation |
card:close | Card Element<div class="card"> | Event will be triggered when expandable card starts its closing animation |
card:closed | Card Element<div class="card"> | Event will be triggered after expandable card completes its closing animation |
App Instance Events
Event | Arguments | Description |
---|---|---|
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-bg-color: #fff;
--f7-card-outline-border-color: rgba(0, 0, 0, 0.12);
--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-border-color: #e1e1e1;
--f7-card-footer-border-color: #e1e1e1;
--f7-card-footer-font-weight: 400;
--f7-card-footer-font-size: inherit;
--f7-card-expandable-bg-color: #fff;
--f7-card-expandable-font-size: 16px;
--f7-card-expandable-tablet-width: 670px;
--f7-card-expandable-tablet-height: 670px;
}
:root .theme-dark,
:root.theme-dark {
--f7-card-bg-color: #1c1c1d;
--f7-card-expandable-bg-color: #1c1c1d;
--f7-card-outline-border-color: #282829;
--f7-card-header-border-color: #282829;
--f7-card-footer-border-color: #282829;
--f7-card-footer-text-color: #8E8E93;
}
.ios {
--f7-card-margin-horizontal: 10px;
--f7-card-margin-vertical: 10px;
--f7-card-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.2);
--f7-card-content-padding-horizontal: 15px;
--f7-card-content-padding-vertical: 15px;
--f7-card-header-font-size: 17px;
--f7-card-header-padding-vertical: 10px;
--f7-card-header-padding-horizontal: 15px;
--f7-card-header-min-height: 44px;
--f7-card-footer-text-color: #6d6d72;
--f7-card-footer-padding-vertical: 10px;
--f7-card-footer-padding-horizontal: 15px;
--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-margin-horizontal: 8px;
--f7-card-margin-vertical: 8px;
--f7-card-box-shadow: var(--f7-elevation-1);
--f7-card-content-padding-horizontal: 16px;
--f7-card-content-padding-vertical: 16px;
--f7-card-header-font-size: 16px;
--f7-card-header-padding-vertical: 4px;
--f7-card-header-padding-horizontal: 16px;
--f7-card-header-min-height: 48px;
--f7-card-footer-text-color: #757575;
--f7-card-footer-padding-vertical: 4px;
--f7-card-footer-padding-horizontal: 16px;
--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-margin-horizontal: 10px;
--f7-card-margin-vertical: 10px;
--f7-card-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.15);
--f7-card-content-padding-horizontal: 15px;
--f7-card-content-padding-vertical: 15px;
--f7-card-header-font-size: 14px;
--f7-card-header-font-weight: bold;
--f7-card-header-padding-vertical: 10px;
--f7-card-header-padding-horizontal: 15px;
--f7-card-header-min-height: 38px;
--f7-card-footer-text-color: rgba(0, 0, 0, 0.6);
--f7-card-footer-padding-vertical: 10px;
--f7-card-footer-padding-horizontal: 15px;
--f7-card-footer-min-height: 38px;
--f7-card-expandable-margin-horizontal: 10px;
--f7-card-expandable-margin-vertical: 20px;
--f7-card-expandable-box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.15);
--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;
}
Examples
Simple Cards
<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>
Outline Cards
<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>
Styled Cards
.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;
}
<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>
Facebook Cards
.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;
}
<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 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>
Cards With List View
<div class="card">
<div class="card-content">
<div class="list links-list">
<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">
<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>
Expandable Cards
<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">close_round_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>
...
</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">close_round_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>
...
</div>
</div>
</div>