# Animated Card Tiles 2019-02-27 *The design trend of using "cards" or "tiles" to display interactive* sections/article headings in an app or website remains a popular choice among designers. So, let's build a set of animated cards with only HTML & CSS. ## What we will be building (live demo) This is the set of animated card tiles we will be creating: *(try hovering)* [Live CodePen](https://codepen.io/bradleytaunt/pen/rNjBpob) ## The HTML For the base skeleton of these cards we only need: - a `flexbox` main container to hold everything - a `.card-tile` parent element - the inner child element that will display on `:hover` - proper `h4` and `p` tags inside that child element

Card Title

Inner card content text

That's all that is needed - for now. We will be returning to this code shortly to add some extra classes to make our lives easier. ## The CSS First we set the main housing container to use `flex` so we save ourselves the headache of aligning all the cards in a nice row: .card-tiles-container { display: flex; font-size: 14px; margin: 20px 0; } Next we create the default styling for our tile cards and set the `transform` property to scale the card on `:hover`: /* Default card tile styles */ .card-tile { border: 1px solid; border-radius: 10px; cursor: pointer; height: 150px; margin: 0 10px; overflow: hidden; position: relative; width: 33.33%; } .card-tile:hover { transform: scale(1.1); } ### Where are my cards?! Don't panic if you can't *visually* see any card elements in your demo yet - that's to be expected. We will be styling these card elements momentarily. Our next step is to hide the default inner `text-content` and only show it on hover. We achieve this by setting it's position to `absolute`, placing it's opacity at 0 and pushing it's z-index back to -1. When the user hovers over a main card tile, we change the `text-content` values of both the opacity and z-index to 1. /* Card tile text content */ .card-tile .text-content { background: linear-gradient(rgba(0,0,0,0.4) 0%, rgba(0,0,0,0.6) 100%); bottom: 10px; border: 1px solid rgba(0,0,0,0.4); border-radius: 5px; box-shadow: inset 0 1px 1px rgba(255,255,255,0.8), 0 2px 4px rgba(0,0,0,0.5); height: 65px; left: 10px; opacity: 0; padding: 10px; position: absolute; width: calc(100% - 20px); z-index: -1; } .card-tile:hover .text-content { opacity: 1; z-index: 1; } Finally we add some minor styling for the inner header and paragraph tags: .card-tile .text-content h4, .card-tile .text-content p { color: #fff; margin: 0; text-shadow: 1px 1px 1px rgba(0,0,0,0.6); } ### Don't forget mobile We want out UI to stack the cards if users are viewing them on smaller devices: @media(max-width: 600px) { .card-tiles-container { flex-direction: column; } .card-tile { margin: 0 0 10px 0; width: 100%; } } ## Customizing each card Remember how I mentioned that we would be adding more classes to the original HTML? Now is the time. We will be including a simple class on each card tile to provide it's own custom coloring:

Card Title

Inner card content text

Card Title

Inner card content text

Card Title

Inner card content text

And these color classes correlate to some new CSS styling: /* Blue Card */ .card-tile.blue { background-color: #0093E9; background-image: linear-gradient(0deg, #0093E9 0%, #80D0C7 100%); border-color: #0093E9; box-shadow: 0 4px 12px rgba(128,208,199,0.7), inset 0 2px 1px rgba(255,255,255,0.6); } .card-tile.blue:hover { box-shadow: 0 8px 18px rgba(128,208,199,0.4), inset 0 2px 1px rgba(255,255,255,0.6); } /* Orange Card */ .card-tile.orange { background-color: #FAD961; background-image: linear-gradient(180deg, #FAD961 0%, #F76B1C 100%); border-color: #F76B1C; box-shadow: 0 4px 12px rgba(247,107,28,0.7), inset 0 2px 1px rgba(255,255,255,0.6); } .card-tile.orange:hover { box-shadow: 0 8px 18px rgba(247,107,28,0.4), inset 0 2px 1px rgba(255,255,255,0.6); } /* Green Card */ .card-tile.green { background-color: #096e40; background-image: linear-gradient(0deg, #096e40 0%, #2AF598 100%); border-color: #096e40; box-shadow: 0 4px 12px rgba(9,110,64,0.7), inset 0 2px 1px rgba(255,255,255,0.6); } .card-tile.green:hover { box-shadow: 0 8px 18px rgba(9,110,64,0.4), inset 0 2px 1px rgba(255,255,255,0.6); } ### Adding transitions We can now see the actual cards visually and have the ability to interact with them, but there is a problem - they don't animate. Lucky we can target all elements we wish to animate with the `transition` property, like so: /* Shared transitions */ .card-tile, .card-tile .text-content { transition: .3s ease all; } Done and done. ## The final code To make things easier for reference, I have included all the `html` and `css` below. Please feel free to use these cards anywhere you like and change them as you see fit! ### HTML

Card Title

Inner card content text

Card Title

Inner card content text

Card Title

Inner card content text

### CSS .card-tiles-container { display: flex; font-size: 14px; margin: 20px 0; } /* Shared transitions */ .card-tile, .card-tile .text-content { transition: .3s ease all; } /* Default card tile styles */ .card-tile { border: 1px solid; border-radius: 10px; cursor: pointer; height: 150px; margin: 0 10px; overflow: hidden; position: relative; width: 33.33%; } /* Blue Card */ .card-tile.blue { background-color: #0093E9; background-image: linear-gradient(0deg, #0093E9 0%, #80D0C7 100%); border-color: #0093E9; box-shadow: 0 4px 12px rgba(128,208,199,0.7), inset 0 2px 1px rgba(255,255,255,0.6); } .card-tile.blue:hover { box-shadow: 0 8px 18px rgba(128,208,199,0.4), inset 0 2px 1px rgba(255,255,255,0.6); } /* Orange Card */ .card-tile.orange { background-color: #FAD961; background-image: linear-gradient(180deg, #FAD961 0%, #F76B1C 100%); border-color: #F76B1C; box-shadow: 0 4px 12px rgba(247,107,28,0.7), inset 0 2px 1px rgba(255,255,255,0.6); } .card-tile.orange:hover { box-shadow: 0 8px 18px rgba(247,107,28,0.4), inset 0 2px 1px rgba(255,255,255,0.6); } /* Green Card */ .card-tile.green { background-color: #096e40; background-image: linear-gradient(0deg, #096e40 0%, #2AF598 100%); border-color: #096e40; box-shadow: 0 4px 12px rgba(9,110,64,0.7), inset 0 2px 1px rgba(255,255,255,0.6); } .card-tile.green:hover { box-shadow: 0 8px 18px rgba(9,110,64,0.4), inset 0 2px 1px rgba(255,255,255,0.6); } /* Card tile text content */ .card-tile .text-content { background: linear-gradient(rgba(0,0,0,0.4) 0%, rgba(0,0,0,0.6) 100%); bottom: 10px; border: 1px solid rgba(0,0,0,0.4); border-radius: 5px; box-shadow: inset 0 1px 1px rgba(255,255,255,0.8), 0 2px 4px rgba(0,0,0,0.5); height: 65px; left: 10px; opacity: 0; padding: 10px; position: absolute; width: calc(100% - 20px); z-index: -1; } .card-tile .text-content h4, .card-tile .text-content p { color: #fff; margin: 0; text-shadow: 1px 1px 1px rgba(0,0,0,0.6); } /* All animations on hover */ .card-tile:hover { transform: scale(1.1); } .card-tile:hover .text-content { opacity: 1; z-index: 1; } @media(max-width: 600px) { .card-tiles-container { flex-direction: column; } .card-tile { margin: 0 0 10px 0; width: 100%; } }