This feature card HTML CSS tutorial shows you how to build a modern SaaS feature card with a gradient border, icon, badge, and custom checkmark list. The card includes a gradient CTA button, a secondary link with an animated arrow, and a subtle box shadow for depth.
Final output:
Instant Sync
Keep every device up to date in real time. Changes you make on one device show up everywhere within seconds.
- Real-time updates across devices
- Works offline, syncs when back
- End-to-end encrypted
Steps for Feature Card Design With Gradient Border:
1. Start with the feature card structure
Link the Inter font 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=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap"
rel="stylesheet">
Let’s start by creating a .feature-card div and placing a .feature-card-body inside it. The outer card will act as the gradient border, while the inner body will hold the actual content.
<div class="feature-card">
<div class="feature-card-body">
<div class="feature-card-top">
<svg width="38" height="38" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="38" height="38" rx="10" fill="#F0EFFF" />
<path
d="M19.9521 11.6758L14.0938 19.7904H18.1312L17.9729 26.3216L23.9104 18.207H19.8729L19.9521 11.6758Z"
stroke-width="1.425" stroke-linecap="round" stroke-linejoin="round" stroke="#5544EE" />
</svg>
<span class="badge">New</span>
</div>
<h2 class="feature-card-heading">Instant Sync</h2>
<p class="feature-card-description">Keep every device up to date in real time. Changes you make on one
device show up everywhere
within
seconds.</p>
<ul>
<li>Real-time updates across devices</li>
<li>Works offline, syncs when back</li>
<li>End-to-end encrypted</li>
</ul>
<div class="feature-card-bottom">
<button class="btn" type="button">Try it free</button>
<a class="link" href="#learn-more">Learn more <svg width="10" height="10" viewBox="0 0 10 10"
fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M4.93501 9.13246L3.92401 8.13068L6.75391 5.30078H0V3.83274H6.75391L3.92401 1.00746L4.93501 0.00106478L9.50071 4.56676L4.93501 9.13246Z"
fill="#606374" />
</svg>
</a>
</div>
</div>
</div>
Then reset margins and set box-sizing: border-box so padding and borders are included in the element’s dimensions.
Style .feature-card with a maximum width, rounded corners, and a linear gradient background. Use padding: 2px to create a thin gradient border around the card. Add a subtle box shadow for depth.
* {
margin: 0;
box-sizing: border-box;
}
body {
font-family: "Inter", sans-serif;
}
.feature-card {
max-width: 26.25rem;
padding: 2px;
border-radius: 1.25rem;
background: linear-gradient(
134.38deg,
#7078FF 0%,
#8D66FF 45%,
#C260FF 74%,
#FF75DC 100%
);
color: hsla(240, 8%, 10%, 1);
box-shadow: 0 12px 32px 0 hsla(248, 38%, 28%, 0.12);
}
Output:
Instant Sync
Keep every device up to date in real time. Changes you make on one device show up everywhere within seconds.
- Real-time updates across devices
- Works offline, syncs when back
- End-to-end encrypted
2. Style the card body and top section
Give .feature-card-body a white background, matching border radius, and padding. This creates the inner surface while allowing the gradient background of the parent to remain visible around the edges.
Use flexbox on .feature-card-top to position the icon and badge on opposite sides of the card.
.feature-card .feature-card-body {
padding: 1.75rem;
border-radius: 1.25rem;
background: hsla(0, 0%, 100%, 1);
}
.feature-card .feature-card-top {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
}
Style the badge with a small font, rounded pill shape, and light purple background. Use a stronger purple for the text to maintain contrast.
.feature-card .badge {
font-size: 0.75rem;
font-weight: 600;
padding: 0.25rem 0.625rem;
border-radius: 10rem;
background: hsla(248, 100%, 97%, 1);
color: hsla(246, 83%, 60%, 1);
}
Output:
Instant Sync
Keep every device up to date in real time. Changes you make on one device show up everywhere within seconds.
- Real-time updates across devices
- Works offline, syncs when back
- End-to-end encrypted
3. Style the heading and description
Add spacing above the heading and use a slightly larger font size with tight line height. Keep the description smaller and muted so it doesn’t compete with the heading.
.feature-card .feature-card-heading {
margin-top: 1.5rem;
font-size: 1.375rem;
line-height: 1.19;
letter-spacing: -0.01em;
}
.feature-card .feature-card-description {
margin-top: 0.5rem;
font-size: 0.875rem;
line-height: 1.5;
color: hsla(229, 11%, 39%, 1);
}
Output:
Instant Sync
Keep every device up to date in real time. Changes you make on one device show up everywhere within seconds.
- Real-time updates across devices
- Works offline, syncs when back
- End-to-end encrypted
4. Style the feature list
Remove the default list bullets and padding. Add a subtle top border to separate the list from the description, then use a custom SVG checkmark as the background image for each list item.
The checkmark is embedded directly in the CSS as a data URI, so you don’t need a separate image file.
.feature-card ul {
list-style: none;
padding: 0;
border-top: 1px solid hsla(231, 15%, 91%, 1);
padding-top: 1.375rem;
margin-top: 1.375rem;
font-size: 0.813rem;
line-height: 1.5;
}
.feature-card ul li {
padding-left: 1.75rem;
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='17' height='17' fill='none' stroke='%236048F2' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12 5 5 9-10' /%3E%3C/svg%3E") left no-repeat;
}
Output:
Instant Sync
Keep every device up to date in real time. Changes you make on one device show up everywhere within seconds.
- Real-time updates across devices
- Works offline, syncs when back
- End-to-end encrypted
5. Style the bottom section
Use flexbox to position the button and link on opposite sides. Add spacing above the bottom section to separate it from the feature list.
Style the button with a purple gradient, rounded corners, white text, and a subtle shadow. Set cursor: pointer to indicate that it’s interactive.
.feature-card .feature-card-bottom {
margin-top: 1.875rem;
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
}
.feature-card .btn {
border: 0;
border-radius: 0.625rem;
padding: 0.625rem 1rem;
font-weight: 700;
font-size: 0.875rem;
line-height: 1.5rem;
background: linear-gradient(
112.95deg,
#6048F2 0%,
#4B35E6 100%
);
color: hsla(0, 0%, 100%, 1);
box-shadow: 0 5px 14px 0 hsla(246, 83%, 60%, 0.2);
cursor: pointer;
}
Style the secondary link with muted text and a small SVG arrow. Add a transition to the arrow so it moves slightly to the right when the link is hovered.
.feature-card .link {
color: hsla(231, 9%, 42%, 1);
font-size: 0.875rem;
text-decoration: none;
font-weight: 600;
}
.feature-card .link svg {
margin-left: 0.25rem;
transition: transform 0.3s;
}
.feature-card .link:hover svg {
transform: translateX(25%);
}
Output:
Instant Sync
Keep every device up to date in real time. Changes you make on one device show up everywhere within seconds.
- Real-time updates across devices
- Works offline, syncs when back
- End-to-end encrypted
Final Output Code for Feature Card Design With Gradient Border HTML CSS:
HTML
<div class="feature-card">
<div class="feature-card-body">
<div class="feature-card-top">
<svg width="38" height="38" viewBox="0 0 38 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="38" height="38" rx="10" fill="#F0EFFF" />
<path
d="M19.9521 11.6758L14.0938 19.7904H18.1312L17.9729 26.3216L23.9104 18.207H19.8729L19.9521 11.6758Z"
stroke-width="1.425" stroke-linecap="round" stroke-linejoin="round" stroke="#5544EE" />
</svg>
<span class="badge">New</span>
</div>
<h2 class="feature-card-heading">Instant Sync</h2>
<p class="feature-card-description">Keep every device up to date in real time. Changes you make on one
device show up everywhere
within
seconds.</p>
<ul>
<li>Real-time updates across devices</li>
<li>Works offline, syncs when back</li>
<li>End-to-end encrypted</li>
</ul>
<div class="feature-card-bottom">
<button class="btn" type="button">Try it free</button>
<a class="link" href="#learn-more">Learn more <svg width="10" height="10" viewBox="0 0 10 10" fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M4.93501 9.13246L3.92401 8.13068L6.75391 5.30078H0V3.83274H6.75391L3.92401 1.00746L4.93501 0.00106478L9.50071 4.56676L4.93501 9.13246Z"
fill="#606374" />
</svg>
</a>
</div>
</div>
</div>
CSS
* {
margin: 0;
box-sizing: border-box;
}
body {
font-family: "Inter", sans-serif;
}
.feature-card {
max-width: 26.25rem;
padding: 2px;
border-radius: 1.25rem;
background: linear-gradient(
134.38deg,
#7078FF 0%,
#8D66FF 45%,
#C260FF 74%,
#FF75DC 100%
);
color: hsla(240, 8%, 10%, 1);
box-shadow: 0 12px 32px 0 hsla(248, 38%, 28%, 0.12);
}
.feature-card .feature-card-body {
padding: 1.75rem;
border-radius: 1.25rem;
background: hsla(0, 0%, 100%, 1);
}
.feature-card .feature-card-top {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
}
.feature-card .badge {
font-size: 0.75rem;
font-weight: 600;
padding: 0.25rem 0.625rem;
border-radius: 10rem;
background: hsla(248, 100%, 97%, 1);
color: hsla(246, 83%, 60%, 1);
}
.feature-card .feature-card-heading {
margin-top: 1.5rem;
font-size: 1.375rem;
line-height: 1.19;
letter-spacing: -0.01em;
}
.feature-card .feature-card-description {
margin-top: 0.5rem;
font-size: 0.875rem;
line-height: 1.5;
color: hsla(229, 11%, 39%, 1);
}
.feature-card ul {
list-style: none;
padding: 0;
border-top: 1px solid hsla(231, 15%, 91%, 1);
padding-top: 1.375rem;
margin-top: 1.375rem;
font-size: 0.813rem;
line-height: 1.5;
}
.feature-card ul li {
padding-left: 1.75rem;
background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' width='17' height='17' fill='none' stroke='%236048F2' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12 5 5 9-10' /%3E%3C/svg%3E") left no-repeat;
}
.feature-card .feature-card-bottom {
margin-top: 1.875rem;
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
}
.feature-card .btn {
border: 0;
border-radius: 0.625rem;
padding: 0.625rem 1rem;
font-weight: 700;
font-size: 0.875rem;
line-height: 1.5rem;
background: linear-gradient(
112.95deg,
#6048F2 0%,
#4B35E6 100%
);
color: hsla(0, 0%, 100%, 1);
box-shadow: 0 5px 14px 0 hsla(246, 83%, 60%, 0.2);
cursor: pointer;
}
.feature-card .link {
color: hsla(231, 9%, 42%, 1);
font-size: 0.875rem;
text-decoration: none;
font-weight: 600;
}
.feature-card .link svg {
margin-left: 0.25rem;
transition: transform 0.3s;
}
.feature-card .link:hover svg {
transform: translateX(25%);
}
If you have any doubts or stuck somewhere, you can reach out through Coding Yaar's Discord server.