Skip to main content

The product tile

The markup

caution

This file is already added in the chapter's snapshot!

/views/snippets/product-tile.twig
{% set _product = product | default(null) %}

{% set _classes = classes | default(null) %}
{% set _modifiers = modifiers | default(null) %}
{% set _attr = attr | default(null) %}

{% if _classes != null %}
{% set _classes = ' ' ~ _classes %}
{% endif %}

{% if _modifiers != null %}
{% set _classes = ' ' ~ _modifiers ~ ' ' ~ _classes %}
{% endif %}

<article class="c-product-tile {{ _classes }}" {{ _attr }}>
{% include "@snippets/image.twig" with {
classes: 'c-product-tile_image',
src: _product.img.src,
width: _product.img.width,
height: _product.img.height
} only %}

<div class="c-product-tile_content">
<h3 class="c-product-tile_title">{{ _product.title }}</h3>
{% for tag in _product.tags %}
<span class="c-product-tile_tag">{{ tag }}</span>&nbsp;
{% endfor %}

<span class="c-product-tile_price">{{ _product.price }}</span>

<span class="c-product-tile_cta" aria-hidden="true"></span>
</div>

<a href="#" class="c-product-tile_link">
<span class="u-screen-reader-text">Details</span>
</a>
</article>
info

Notice that we position the <a> tag at the end of the component, not only to maintain good semantics but also to ensure accessibility through keyboard navigation and screen readers. The <a> tag will be placed in an absolute position within our tile, styled with the following CSS properties.

The styles

caution

This file is already added in the chapter's snapshot!

/assets/styles/components/_product-tile.scss
.c-product-tile {
position: relative;
}

.c-product-tile_image {
@media (max-width: $to-small) {
.c-products_highlight & {
margin-left: calc(var(--container-margin) * -1);
width: calc(100% + var(--container-margin) * 2);
}
}

.c-product-tile:hover &,
.c-product-tile:focus-within & {
transform: scaleX(-1);
}
}

.c-product-tile_content {
position: relative;
padding-top: .5em;
}

.c-product-tile_title {
margin-bottom: 0;
}

.c-product-tile_tag {
display: inline-block;
margin-right: .5em;
opacity: .5;

.c-product-tile:hover &,
.c-product-tile:focus-within & {
opacity: 1;
}
}

.c-product-tile_price {
display: block;
margin-top: 1em;
}

.c-product-tile_cta {
position: absolute;
top: .5em;right: 0;

&:before {
content: '(+)';
}

.c-product-tile:hover &,
.c-product-tile:focus-within & {
&:before {
content: 'Details';
text-decoration: underline;
}
}
}

.c-product-tile_link {
position: absolute;
top: 0;left: 0;
width: 100%;
height: 100%;
z-index: 10;
}

Now we're ready to start the products listing.