Product Layout With The CSS Grid
CSS Grid introduction
The CSS Grid module is used to create grid-based layouts, just as we have with our products area:
Since we can control both the rows and columns it is described as a two dimensional layout system. This is in contrast to the CSS flexbox that deals with only one direction at a time.
Styling products
The index.html
page has products inside of a div
container, this will be the parent element to set the grid properties. Inside, each product (currently only 1 example) is an article
element, these will be the child items. Update the elements below to include class
names:
<!-- index.html -->
<div class="product-grid">
<article class="product-card">
<section class="product-image">
<img
src="images/t-shirt-blue.png"
alt="blue t-shirt with short sleeves"
class="product-image"
/>
</section>
<section class="product-details">
<h3>Stylish long-sleeve t-shirt in blue / medium</h3>
<p>A stylish long sleeve blue t-shirt, in size medium.</p>
<p class="price">$20.95</p>
</section>
</article>
</div>
You may also want to create more products for testing (within the above container). This is optional as we will generate more products later using JavaScript.
Begin by adding some styling to the product card:
/* add to existing styles.css file */
.product-card {
cursor: pointer;
border: 1px solid #dde;
border-radius: 3px;
display: flex;
flex-direction: column;
}
/* Hover effect for product cards */
.product-card:hover {
transform: scale(1.02);
box-shadow: 0px 5px 10px rgba(0, 0, 0, 0.1);
}
cursor: pointer
: Setting thecursor
can give the user a visual clue as to what action can be taken. Thepointer
changes the mouse cursor to be a pointing hand when moving over this area, often indicating a link.- A 1px wide, solid
border
is added around the product, with a 3px rounded corner (border-radius
). - We use the flexbox to set the content direction to be vertical using
flex-direction: column
.
CSS transforms
There is also a property used called transform
which is used to apply transformations to elements. The scale
function is added to scale/resize an element using one or two values:
scale(1.1)
: One value will scale the element's width and height. A value of1
is the original size.scale(0.5, 1)
: Width and height can be specified individually. If both are equal, scaling will be uniform. This will reduce the width by half, and retain the original height.
Value | Visual |
---|---|
transform: scale(1.1); | |
transform: scale(0.5, 1); |
The above example is applied directly to the element to scale, the difference is we apply when the mouse hovers over the product (.product-card:hover
). This can appear to look 'jumpy' and it can often help to make the transform smoother. We can do this by using the transition
property:
.product-card {
cursor: pointer;
border: 1px solid #dde;
border-radius: 3px;
display: flex;
flex-direction: column;
/* add the transition */
transition: transform 0.3s ease-in-out;
}
The transition
property can transition between two states of an element. Such as a width
transitioning from 100px to 200px. We apply to the transform
property to control the scaling. This transition also has a duration in seconds, which we set to 0.3s
. Ths final value we use is ease-in-out
to slowly ease in the transition, speed it up, and slow down to complete. Values of ease-in
and ease-out
are also available to control individually.
The grid container
Create a grid container by setting the display
property on the parent element, and style the product images:
.product-grid {
display: grid;
}
/* Style for the product image */
.product-image {
width: 100%;
height: 200px;
background-size: cover;
}
Setting the image width to be 100% of the container will allow the image to resize with the product.
Columns and rows
This will not yet change the layout as we need to declare the number of columns or rows. Columns are set using grid-template-columns
:
/* creates 3 columns at 20% width */
grid-template-columns: 20% 20% 20%;
/* creates 2 columns at 1fr */
grid-template-columns: 1fr 1fr;
/* creates 4 columns at 300px wide */
grid-template-columns: 300px 300px 300px 300px;
The fr
unit used above is a fractional unit. A value of 1fr 1fr
will create two columns and calculate an equal width, 1fr 2fr
will also create two columns but the second will try to take up twice the available width.
The repeat()
function can also be used to repeat columns, add this to the product-grid
:
.product-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
This will create three columns at 1fr
wide.
To set the height of the rows there is the grid-template-rows
property. Row heights can be specified individually, or by using the repeat()
function. This will not be added to our project to allow rows to be determined by the product height.
Grid gaps
The gap
property sets the gap size between rows and columns:
.product-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 1rem;
}
The gap
property is a shorthand for row-gap
and column-gap
, and row and column can also be set individually using two values, such as gap: 1rem 40px
.
Final product styling
Complete the product styling with the following:
/* styles.css */
.product-details {
padding: 1rem;
display: flex;
flex-direction: column;
justify-content: space-evenly;
}
.product-details h3 {
margin: 0 0 0.5rem;
font-size: 1.25rem;
color: #2d877d;
}
.product-details p {
font-size: 0.875rem;
color: #666;
}
.product-details .price {
font-size: 1.25rem;
font-weight: bold;
color: #3d5944;
}