FEM-1 Product Preview Card Component

Welcome to this step-by-step guide on creating a product preview card component for a website. In this tutorial, we'll cover HTML markup and CSS styling to build a responsive product card. If you're ready, let's dive in!
Overview
Ever felt overwhelmed starting a challenge? Don't worry; we've got you covered. This guide focuses on frontend mentor challenges, aiming to explain our decisions while building from scratch.
If you want to jump directly to the final code, click here. But hey, a star on GitHub would be appreciated! 😉
Writing The Html
Basic Layout
Let's begin with the HTML structure. For this project, simplicity reigns. We'll start with a basic structure:
<body>
<main>
<article class="product__card">
<!-- Product elements go here -->
</article>
</main>
</body>
This simplified structure is designed specifically for styling the product card. It utilizes the <article> HTML element, which is ideal for presenting content as an individual and self-contained unit.
Product Image Markup
We'll structure the product content with a desktop-first approach and utilize the <picture> element for responsive images:
<article class="product">
<!-- Product Image -->
<picture>
<source srcset="images/image-product-desktop.jpg" media="(min-width:600px)">
<img src="./images/image-product-mobile.jpg" alt="Product Image">
</picture>
<!-- Product Content -->
<div class="product__content">
<!-- Content elements: category, title, description, price, and button -->
<p class="product__category">Perfume</p>
<h1 class="product__title">Gabrielle Essence Eau De Parfum</h1>
<p class="product__description">A floral, solar and voluptuous interpretation composed by Olivier Polge,
Perfumer-Creator for the House of CHANEL.</p>
<!-- Product Price -->
<div class="product__price">
<p>$149.99</p>
<p><s>$169.99</s></p>
</div>
<!-- Button -->
<button aria-label="Add Gabrielle Essence Eau De Parfum to Cart">
<img src="images/icon-cart.svg" alt=""> Add to Cart
</button>
</div>
</article>
Writing the CSS
CSS Reset
CSS reset styles are used to standardize and neutralize default styles applied by different browsers to HTML elements. It ensures a consistent starting point for styling, helping you avoid inconsistencies and achieve more control over the appearance of elements across various browsers
Here's a reset by Andy Bell:
/* Box sizing rules */
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
/* Remove default margin */
body,
h1,
h2,
h3,
h4,
p,
figure,
blockquote,
dl,
dd {
margin-block-end: 0;
}
/* Remove list styles on ul, ol elements with a list role, which suggests default styling will be removed */
ul[role='list'],
ol[role='list'] {
list-style: none;
}
/* Set core root defaults */
html:focus-within {
scroll-behavior: smooth;
}
/* Set core body defaults */
body {
min-height: 100vh;
text-rendering: optimizeSpeed;
line-height: 1.5;
}
/* A elements that don't have a class get default styles */
a:not([class]) {
text-decoration-skip-ink: auto;
}
/* Make images easier to work with */
img,
picture {
max-width: 100%;
display: block;
}
/* Inherit fonts for inputs and buttons */
input,
button,
textarea,
select {
font: inherit;
}
/* Remove all animations, transitions and smooth scroll for people that prefer not to see them */
@media (prefers-reduced-motion: reduce) {
html:focus-within {
scroll-behavior: auto;
}
*,
*::before,
*::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
scroll-behavior: auto !important;
}
}
Reusable Variables
Utilizing CSS variables for colors, font families, and font weights ensures consistent styling:
:root {
--clr-primary-cyan: hsl(158, 36%, 40%);
--clr-primary-cyan-dark: hsl(158, 36%, 30%);
--clr-primary-cream: hsl(30, 38%, 92%);
--clr-neutral-dark-blue: hsl(212, 21%, 14%);
--clr-neutral-grayish-blue: hsl(228, 12%, 48%);
--clr-white: hsl(0, 0%, 100%);
--ff-body: 'Montserrat', sans-serif;
--ff-secondary: 'Fraunces', sans-serif;
--fw-regular: 500;
--fw-bold: 700;
}
Styling elements
We'll style the product container, images, content, category, title, description, price, and button using CSS rules.
/* Product */
.product {
background-color: var(--clr-white);
border-radius: .5rem;
overflow: hidden;
display: grid;
max-width: 38.125rem;
}
/* Product Content */
.product__content {
padding: 1.5rem 2rem;
display: grid;
gap: .5rem;
}
/* Product Category */
.product__category {
font-family: var(--ff-secondary);
letter-spacing: 6px;
text-transform: uppercase;
}
.product__title {
font-size: 2rem;
line-height: 1.1;
color: var(--clr-neutral-dark-blue);
font-weight: var(--fw-bold);
}
.product__desscription {
font-weight: var(--fw-regular);
}
.product__price{
display: flex;
align-items: center;
gap: 1rem;
}
.product__price p:first-child {
font-size: 2rem;
font-weight: var(--fw-bold);
color: var(--clr-primary-cyan);
}
button {
cursor: pointer;
font-family: inherit;
border: none;
border-radius: .5rem;
padding: 1rem 1.5rem;
background-color: var(--clr-primary-cyan);
color: var(--clr-white);
font-weight: var(--fw-bold);
/* flexing because of the icon */
display: inline-flex;
justify-content: center;
align-items: center;
gap: .5rem;
}
button:focus,
button:hover {
background-color: var(--clr-primary-cyan-dark);
}
/*
button:is(:hover, :focus) {
background-color: var(--clr-primary-cyan-dark);
} */
/* Clearly visible focus outline for accessibility on tab focus */
button:focus {
outline: 2px solid var(--clr-primary-cyan-dark);
outline-offset: 2px;
}
Responsiveness and Media Queries
Determining The Break Point
Our design shifts to a two-column layout at around 600 pixels. Let's set up a media query for screens larger than this width:
/* Media query for screens with a MINIMUM width of 600px */
@media screen and (min-width: 600px) {
/* Styles for screens larger than 600px width */
.product {
grid-template-columns: 1fr 1fr;
}
button {
padding: .5rem 1.5rem;
}
}
Conslusion
Building a product preview card involves structuring HTML, applying CSS styles, and ensuring responsiveness. We've covered the basics here, but remember, practice and experimentation are key to mastering frontend development!
And that's a wrap! Happy coding and creating awesome product cards!

