<div id="app">
<custom-card type="hero" background="https://picsum.photos/id/237/800/200">
<template v-slot:header>Article Title</template>
<template v-slot:content>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla ac pharetra urna. Maecenas bibendum felis venenatis, eleifend nunc nec, eleifend est. Suspendisse consectetur laoreet urna sed varius. Nunc in risus pulvinar odio ornare pharetra nec mollis leo.</template>
<template v-slot:footer>January 1, 2011</template>
</custom-card>
<nav class="custom-card__cta-nav">
<custom-card type="cta">
<template v-slot:header>CTA Title One</template>
<template v-slot:content>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</template>
<template v-slot:footer>footer</template>
</custom-card>
<custom-card type="cta">
<template v-slot:header>CTA Title Three</template>
<template v-slot:content>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas bibendum felis venenatis, eleifend nunc nec, eleifend est.</template>
<template v-slot:footer>footer</template>
</custom-card>
<custom-card type="cta">
<template v-slot:header>CTA Title Two</template>
<template v-slot:content>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla ac pharetra urna.</template>
<template v-slot:footer>footer</template>
</custom-card>
<custom-card type="cta">
<template v-slot:header>CTA Title Four</template>
<template v-slot:content>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc in risus pulvinar odio ornare pharetra nec mollis leo.</template>
<template v-slot:footer>footer</template>
</custom-card>
</nav>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla ac pharetra urna. Maecenas bibendum felis venenatis, eleifend nunc nec, eleifend est. Suspendisse consectetur laoreet urna sed varius. Nunc in risus pulvinar odio ornare pharetra nec mollis leo. Duis malesuada leo at leo facilisis, non scelerisque ex efficitur. Proin ut elit a nisi faucibus vehicula.</p>
<p>Sed accumsan mi lectus, et lobortis orci placerat id. Ut efficitur luctus magna, nec luctus felis facilisis at. Vestibulum mi urna, vulputate nec lectus tincidunt, gravida commodo mauris. Cras sed molestie ipsum, nec rutrum libero. Ut vitae sapien quam. Nulla a lorem orci. Curabitur a dui accumsan, malesuada velit ut, tincidunt erat. Aliquam egestas mi vitae sodales condimentum. Donec laoreet pharetra pulvinar.</p>
<custom-card type="info">
<template v-slot:header>Here's a Quote</template>
<template v-slot:content>“Maecenas nec leo a lectus pretium laoreet at quis mauris. Aenean vulputate magna ultricies, semper nisl vitae, tristique nunc. Proin luctus fermentum lorem, congue condimentum lorem tempor quis.”</template>
<template v-slot:footer>who said it</template>
</custom-card>
<p>Suspendisse in condimentum erat. Nulla facilisi. Integer molestie tempor turpis, dictum maximus dui laoreet et. Sed non fermentum mauris, vel accumsan justo. Vivamus sit amet molestie orci. Quisque ut lorem velit. Donec mollis urna vel fringilla porta. Phasellus iaculis odio mauris, id vehicula tortor fringilla eleifend. Praesent fermentum luctus dui, sed lobortis orci vestibulum a.</p>
<p>Mauris vestibulum diam sed leo ultricies dictum. Sed mattis tempus eleifend. Suspendisse rhoncus elementum elit, id sollicitudin ex maximus quis. Sed luctus mauris nec purus finibus, vitae cursus elit cursus. Nunc convallis lectus diam, eget condimentum magna luctus nec. Cras varius eleifend pretium. Pellentesque tempor auctor purus, id dapibus orci lacinia eu.</p>
<p>Maecenas nec leo a lectus pretium laoreet at quis mauris. Aenean vulputate magna ultricies, semper nisl vitae, tristique nunc. Proin luctus fermentum lorem, congue condimentum lorem tempor quis. In volutpat id sapien ac iaculis. Vestibulum in placerat leo, dignissim congue arcu. Duis hendrerit tortor sit amet egestas dapibus. Aliquam erat volutpat.</p>
<p>Sed sit amet diam augue. Vivamus accumsan, tellus quis rhoncus molestie, orci diam porttitor risus, in volutpat tellus odio ac nisl. Pellentesque id erat ac purus auctor venenatis. Proin sed condimentum magna, in blandit nibh. Duis aliquam erat in orci eleifend, at malesuada ex bibendum. Cras id pulvinar felis. Phasellus tristique, ligula sit amet vehicula tincidunt, dui nisl sagittis ex, sollicitudin eleifend massa neque eu diam.</p>
</div>
@import url('https://fonts.googleapis.com/css2?family=Alfa+Slab+One&family=Open+Sans&display=swap');
body {
font-family: 'Open Sans', sans-serif;
margin: 16px;
}
.custom-card {
display: flex;
flex-direction: column;
}
.custom-card__hero {
border-bottom: 3px solid gainsboro;
padding-bottom: 16px;
}
.custom-card__hero .custom-card__header {
background-position: center;
background-repeat: no-repeat;
background-size: cover;
font-family: 'Alfa Slab One', sans-serif;
height: 200px;
position: relative;
}
.custom-card__hero .custom-card__header-content {
bottom: 16px;
color: white;
font-size: 48px;
left: 16px;
margin: 0;
position: absolute;
text-shadow: 1px 1px 2px black;
}
.custom-card__hero .custom-card__content {
font-weight: bold;
margin: 16px 0;
}
.custom-card__hero .custom-card__footer-content {
display: block;
font-size: 16px;
font-style: italic;
margin: 8px 0;
text-align: right;
}
.custom-card__cta-nav {
display: flex;
}
.custom-card__cta {
border: 2px solid gainsboro;
cursor: pointer;
flex-basis: 25%;
flex-grow: 1;
margin: 16px 8px;
}
.custom-card__cta:first-child {
margin-left: 0;
}
.custom-card__cta:last-child {
margin-right: 0;
}
.custom-card__cta:hover {
border-color: gray;
}
.custom-card__cta:hover .custom-card__footer-content {
background-color: gray;
color: gainsboro;
}
.custom-card__cta .custom-card__header-content {
border-bottom: 1px solid gainsboro;
font-size: 16px;
margin: 8px;
text-align: center;
}
.custom-card__cta .custom-card__content {
flex-grow: 1;
font-size: 14px;
margin: 0 8px;
}
.custom-card__cta .custom-card__footer-content {
background-color: gainsboro;
border-radius: 999px;
color: gray;
margin: 16px 4px 4px;
padding: 8px;
text-align: center;
}
.custom-card__info {
border-left: 3px solid gray;
float: right;
margin: 16px 0 16px 16px;
padding-left: 8px;
width: 25%;
}
.custom-card__info .custom-card__header-content {
font-size: 16px;
line-height: 1;
margin: 0;
}
.custom-card__info .custom-card__content {
margin: 8px 0;
}
.custom-card__info .custom-card__footer-content {
display: block;
font-style: italic;
margin: 8px 0;
text-align: right;
}
Vue.component('custom-card', {
props: ['type', 'background'],
methods: {
rootClickHandler() {
if (this.type === 'cta') {
console.log('cta clicked!');
}
},
footerClickHandler() {
if (this.type === 'info') {
console.log('info footer clicked!');
}
},
elements(which) {
const tags = {
hero: { root: 'section', header: 'h1', footer: 'date' },
cta: { root: 'section', header: 'h2', footer: 'div' },
info: { root: 'aside', header: 'h3', footer: 'small' }
}
return tags[this.type][which];
},
},
computed: {
bg() {
return this.background ? `background-image: url(${this.background})` : null;
}
},
template: `
<component :is="elements('root')" :class="'custom-card custom-card__' + type" @click="rootClickHandler">
<header class="custom-card__header" :style="bg">
<component :is="elements('header')" class="custom-card__header-content">
<slot name="header"></slot>
</component>
</header>
<div class="custom-card__content">
<slot name="content"></slot>
</div>
<footer class="custom-card__footer">
<component :is="elements('footer')" class="custom-card__footer-content" @click="footerClickHandler">
<slot name="footer"></slot>
</component>
</footer>
</component>`
});
const app = new Vue({
el: '#app'
});
This Pen doesn't use any external CSS resources.