This testimonial card HTML CSS tutorial shows you how to build a clean and polished review card with star ratings, a large decorative quote icon, an italic quote in a serif font, and a client author section at the bottom. The card uses a thin colored top border along with a layered box-shadow for a premium feel.
Final output:
I’ve worked with a lot of consultants who talk a big game and disappear after the deck. This team stayed in the trenches with us. A year later, the framework they built is still how we run planning.
Steps for HTML CSS Testimonial Card #2:
1. Let’s start with a .testimonial-card div. Inside it, add a .ratings-wrapper div with five star SVG icons, a .quotes-icon div, and a .testimonial-card-body div.
<div class="testimonial-card">
<div class="ratings-wrapper">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M6.99935 1.16602L8.80185 4.81768L12.8327 5.40685L9.91602 8.24768L10.6043 12.261L6.99935 10.3652L3.39435 12.261L4.08268 8.24768L1.16602 5.40685L5.19685 4.81768L6.99935 1.16602Z"
fill="#A8722A" />
</svg>
<!-- add more stars -->
</div>
<div class="quotes-icon">"</div>
<div class="testimonial-card-body"></div>
</div>
Link the Figtree and Lora fonts from Google Fonts in the head.
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Figtree:ital,wght@0,300..900;1,300..900&family=Lora:ital,wght@0,400..700;1,400..700&display=swap"
rel="stylesheet">
Then reset margins and set Figtree as the font family on the body. Also define the Lora font as a CSS variable on the body so you can reuse it throughout without repeating yourself.
* {
margin: 0;
box-sizing: border-box;
}
body {
font-family: "Figtree", sans-serif;
--lora-font: "Lora", serif;
}
Style the card with a max-width, some padding, and rounded corners. Add a multi-layer box-shadow to give it depth. Set the position property to relative and the overflow property to hidden so the decorative top border stays clipped inside the card corners.
Then use a ::before pseudo-element to add that thin dark border at the very top of the card. Set the position property to absolute on it and the top and left properties to 0 so it sits flush against the top edge.
.testimonial-card {
max-width: 33.75rem;
padding: 2.5rem;
border-radius: 0.625rem;
box-shadow: 0px 0px 0px 1px hsla(0, 0%, 0%, 0.04),
0px 4px 24px 0px hsla(0, 0%, 0%, 0.07),
0px 1px 3px 0px hsla(0, 0%, 0%, 0.06);
position: relative;
overflow: hidden;
}
.testimonial-card::before {
position: absolute;
top: 0;
left: 0;
content: "";
width: 100%;
height: 3px;
background-color: hsl(180, 36%, 17%);
}
Output:
2. Use flexbox with a small gap on .ratings-wrapper to space the stars evenly. Fix the width and height on each SVG so they stay consistent regardless of context.
.testimonial-card .ratings-wrapper {
display: flex;
gap: .25rem;
}
.testimonial-card .ratings-wrapper svg {
width: 1rem;
height: 1rem;
}
Style the .quotes-icon. Use the Lora font at a very large font size so it reads as a decorative element rather than actual content. Set the color property to a very faint teal so it sits in the background without distracting from the quote text below it.
.testimonial-card .quotes-icon {
margin-top: 1.75rem;
font-family: var(--lora-font);
font-size: 5rem;
line-height: 1;
color: hsla(180, 36%, 17%, 0.11);
}
Output:
3. Fill in .testimonial-card-body with the quote paragraph and a .testimonial-author-details div containing the client image and their name and title.
<div class="testimonial-card-body">
<p>I've worked with a lot of consultants who talk a big game and disappear after the deck. This team stayed in the trenches with us. A year later, the framework they built is still how we run planning.</p>
<div class="testimonial-author-details">
<img src="elena-voss.png" alt="">
<div>
<span>Elena Voss</span>
<span>Chief Operating Officer - Aster & Hale</span>
</div>
</div>
</div>
Set a negative top margin on .testimonial-card-body so it pulls up slightly and overlaps with the large quote icon above it, since the icon’s size would otherwise create too much space between the ratings and the quote text.
.testimonial-card .testimonial-card-body {
margin-top: -1rem;
}
Style the quote paragraph with the Lora font in italic and a generous line height so it feels open and readable. Add a bottom margin to space it away from the author details below.
.testimonial-card .testimonial-card-body p {
font-family: var(--lora-font);
font-style: italic;
font-size: 1.125rem;
line-height: 2;
margin-bottom: 1.75rem;
}
Output:
I’ve worked with a lot of consultants who talk a big game and disappear after the deck. This team stayed in the trenches with us. A year later, the framework they built is still how we run planning.
4. Style .testimonial-author-details. Use flexbox to lay the image and text side by side. Add a top border and some top padding to visually separate the author from the quote above.
Make the image circular by setting the border radius property to 50% and fixing its width and height so it stays consistent.
Then use flexbox with the flex direction property set to column on the inner div to stack the name and title, and use the first-child and last-child selectors to differentiate their styles.
.testimonial-card .testimonial-author-details {
display: flex;
gap: .875rem;
padding-top: 2rem;
border-top: 1px solid hsla(0, 0%, 0%, 0.09);
}
.testimonial-card .testimonial-author-details img {
width: 2.875rem;
height: 2.875rem;
border-radius: 50%;
}
.testimonial-card .testimonial-author-details div {
display: flex;
flex-direction: column;
justify-content: center;
gap: .25rem;
}
.testimonial-card .testimonial-author-details span:first-child {
font-weight: 600;
font-size: 1rem;
line-height: 1.4;
letter-spacing: -0.15px;
}
.testimonial-card .testimonial-author-details span:last-child {
font-size: .875rem;
line-height: 1.4;
letter-spacing: 0.13px;
color: hsl(240, 4%, 48%);
}
Output:
I’ve worked with a lot of consultants who talk a big game and disappear after the deck. This team stayed in the trenches with us. A year later, the framework they built is still how we run planning.
Final Output Code for HTML CSS Testimonial Card #2:
HTML
<div class="testimonial-card">
<div class="ratings-wrapper">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M6.99935 1.16602L8.80185 4.81768L12.8327 5.40685L9.91602 8.24768L10.6043 12.261L6.99935 10.3652L3.39435 12.261L4.08268 8.24768L1.16602 5.40685L5.19685 4.81768L6.99935 1.16602Z"
fill="#A8722A" />
</svg>
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M6.99935 1.16602L8.80185 4.81768L12.8327 5.40685L9.91602 8.24768L10.6043 12.261L6.99935 10.3652L3.39435 12.261L4.08268 8.24768L1.16602 5.40685L5.19685 4.81768L6.99935 1.16602Z"
fill="#A8722A" />
</svg>
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M6.99935 1.16602L8.80185 4.81768L12.8327 5.40685L9.91602 8.24768L10.6043 12.261L6.99935 10.3652L3.39435 12.261L4.08268 8.24768L1.16602 5.40685L5.19685 4.81768L6.99935 1.16602Z"
fill="#A8722A" />
</svg>
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M6.99935 1.16602L8.80185 4.81768L12.8327 5.40685L9.91602 8.24768L10.6043 12.261L6.99935 10.3652L3.39435 12.261L4.08268 8.24768L1.16602 5.40685L5.19685 4.81768L6.99935 1.16602Z"
fill="#A8722A" />
</svg>
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M6.99935 1.16602L8.80185 4.81768L12.8327 5.40685L9.91602 8.24768L10.6043 12.261L6.99935 10.3652L3.39435 12.261L4.08268 8.24768L1.16602 5.40685L5.19685 4.81768L6.99935 1.16602Z"
fill="#A8722A" />
</svg>
</div>
<div class="quotes-icon">"</div>
<div class="testimonial-card-body">
<p>I've worked with a lot of consultants who talk a big game and disappear after the deck. This team stayed in
the trenches with us. A year later, the framework they built is still how we run planning.</p>
<div class="testimonial-author-details">
<img src="elena-voss.png" alt="">
<div>
<span>Elena Voss</span>
<span>Chief Operating Officer - Aster & Hale</span>
</div>
</div>
</div>
</div>
CSS
* {
margin: 0;
box-sizing: border-box;
}
body {
font-family: "Figtree", sans-serif;
--lora-font: "Lora", serif;
}
.testimonial-card {
max-width: 33.75rem;
padding: 2.5rem;
border-radius: 0.625rem;
box-shadow: 0px 0px 0px 1px hsla(0, 0%, 0%, 0.04),
0px 4px 24px 0px hsla(0, 0%, 0%, 0.07),
0px 1px 3px 0px hsla(0, 0%, 0%, 0.06);
position: relative;
overflow: hidden;
}
.testimonial-card::before {
position: absolute;
top: 0;
left: 0;
content: "";
width: 100%;
height: 3px;
background-color: hsl(180, 36%, 17%);
}
.testimonial-card .ratings-wrapper {
display: flex;
gap: .25rem;
}
.testimonial-card .ratings-wrapper svg {
width: 1rem;
height: 1rem;
}
.testimonial-card .quotes-icon {
margin-top: 1.75rem;
font-family: var(--lora-font);
font-size: 5rem;
line-height: 1;
color: hsla(180, 36%, 17%, 0.11);
}
.testimonial-card .testimonial-card-body {
margin-top: -1rem;
}
.testimonial-card .testimonial-card-body p {
font-family: var(--lora-font);
font-style: italic;
font-size: 1.125rem;
line-height: 2;
margin-bottom: 1.75rem;
}
.testimonial-card .testimonial-author-details {
display: flex;
gap: .875rem;
padding-top: 2rem;
border-top: 1px solid hsla(0, 0%, 0%, 0.09);
}
.testimonial-card .testimonial-author-details img {
width: 2.875rem;
height: 2.875rem;
border-radius: 50%;
}
.testimonial-card .testimonial-author-details div {
display: flex;
flex-direction: column;
justify-content: center;
gap: .25rem;
}
.testimonial-card .testimonial-author-details span:first-child {
font-weight: 600;
font-size: 1rem;
line-height: 1.4;
letter-spacing: -0.15px;
}
.testimonial-card .testimonial-author-details span:last-child {
font-size: .875rem;
line-height: 1.4;
letter-spacing: 0.13px;
color: hsl(240, 4%, 48%);
}
If you have any doubts or stuck somewhere, you can reach out through Coding Yaar's Discord server.