Creating a Fancy Stacked Card
March 09, 2021
Intro
The other day I noticed that the tailwindcss playground had a pretty nifty “stacked” card as the default element loaded in the playground. I thought it looked great and would be fun to reproduce using just plain css (as usual). Below is a screenshot of the card from the tailwindcss playground.
My version of it won’t be quite as fancy as this one, but it will still look really nice!
Getting Started
The card is basically going to be two divs
stacked on top of each other. The trick will be to use position: absolute
on the bottom div and position: relative
on the top div so that the two divs appear to be stacked, but really they will just be siblings. The MDN docs have a really good breakdown of what absolute vs relative position means.
For our purposes today we’ll have 3 divs. A container div, the bottom div, and the top div. I changed the background-color
of the container to be a light gray color so that card pops a little bit more. I also added a box-shadow
property (from tailwindcss), which is something I think most cards you see will have. Lastly, the border-radius
rounds the corners.
The .bottom
css class will have a transform: rotate(-5deg)
property which does what it describes, and rotates the bottom div by -5 degrees. The tailwind version of this card pictured above adds a skewY(-6deg)
to the transform
property, but I am not in love with the look of that so I left it out here.
Below is our html and css, as well as an example of what our stacked card looks like so far.
.container {
padding: 3rem;
display: flex;
justify-content: center;
align-items: center;
background-color: #f3f4f6;
}
.bottom {
position: absolute;
width: 350px;
height: 350px;
background-color: cornflowerblue;
border-radius: 1.5rem;
transform: rotate(-5deg);
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
}
.top {
position: relative;
width: 350px;
height: 350px;
background-color: white;
border-radius: 1.5rem;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
}
<div class="container">
<div class="bottom"></div>
<div class="top"></div>
</div>
Adding Some Content and Final Code
So, that is pretty much it for the cards really. At this point you could add some content to card or do whatever you’d like with it. If you look at the actual tailwind playground version I linked above you’ll see that it changes orientation on small devices. This is done via tailwind’s utility breakpoint class, but really it is just media queries (which I won’t be covering here).
Below is an example of how some content could look inside the card. Matching the bottom card color with at least some of the content color is a really nice touch I think. Just something to consider. Our final css, html, and example are below.
.container {
padding: 3rem;
display: flex;
justify-content: center;
align-items: center;
background-color: #f3f4f6;
}
.bottom {
position: absolute;
width: 350px;
height: 350px;
background-color: cornflowerblue;
border-radius: 1.5rem;
transform: rotate(-5deg);
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
}
.top {
position: relative;
width: 350px;
height: 350px;
background-color: white;
border-radius: 1.5rem;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
}
.content {
padding: 2rem;
}
.content__header {
display: flex;
align-items: center;
padding-bottom: 1.5rem;
}
.content__header_icon {
color: cornflowerblue;
height: 3rem;
width: 3rem;
}
.content__header_text {
font-size: x-large;
font-weight: 900;
padding-left: 1rem;
color: cornflowerblue;
}
.content__body {
color: cornflowerblue;
font-weight: 700;
}
<div class="container">
<div class="bottom"></div>
<div class="top">
<div class="content">
<div class="content__header">
<svg class="content__header_icon" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 8h10M7 12h4m1 8l-4-4H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-3l-4 4z" />
</svg>
<div class="content__header_text">Info</div>
</div>
<div class="content__body">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
</div>
</div>
</div>
</div>