Making an NFT Preview Card

Frontend Mentor Project

You learn most by doing. This rule applies to nearly everything. This is why as a Frontend Developer you must try out new ways of doing things and test the skills you have every day (learning never stops).

I recently joined Fronted Mentor to expand my skillset in HTML, CSS and JavaScript. The latest project I made on the platform was a responsive NFT Preview Card.

The beauty of Frontend Mentor is that much like a real developer job you are given a mockup design to implement using whatever tech stack you're comfortable with, be it React, Vue, Angular, jQuery etc..

Since the design was simple i chose to keep things simple with this stack :

  • HTML

  • CSS (Sass using scss-syntax)

  • Flexbox (one-dimensional positioning)

NFT Card Preview

Screenshot

The HTML structure is fairly simple to implement, you structure your code :

  • main element (serves as preview background)

  • div (serves as nft card body)

  • figure (holds images and images after-effects)

  • section element (contains the full body of the nft-preview card)

The above list is but a short preview of the code I used to build the NFT-Preview Card.

View full HTML Code here: Github Link

NFT-HTML

Styling the card is where the fun starts as the design though it looks simple is easy to miss or get wrong.

We start with -

Main Element -

The main element is the container that houses the body of the NFT-Preview Card.

After setting my usual default styles(padding/margin: 0, box-sizing: borderbox), I set the main element as a flex parent and set flex-direction of the child elements as a column, and then finally center it.

main { 
display: flex; 
flex-direction: column; 
align-items: center; 
justify-content: center; 
min-height: 100vh; 
background-color: hsl(217deg, 54%, 11%); 
}

With the above styling for the main element we've specified a min-height of 100vh to allow content scale beyond the viewport height if we need it to. We've also specified the background color we need.

DIV (Card Body) -

For our div.nft-card-body nested in the main element, we have the following styles.

main div.nft-card-body { 
display: flex; 
flex-direction: column; 
align-items: center; 
justify-content: center; 
width: 351px; 
height: 597px; 
border: 1px solid hsl(217deg, 54%, 11%); 
box-shadow: -25px 10px 5px 5px; 
border-radius: 12px; 
background-color: hsl(216deg, 50%, 16%); 
}

Aside the other properties which have been gone through with the main element, we've specified the width and height of our NFT-Card Preview and given borders to give it a proper definition. We've also set a box shadow to cast a shadow effect giving depth to our card.

Read more about box-shadows here: MDN Documentation

The div body also contains other nested elements like the figure element that serves as a container for our images and image hover styling.

main div.nft-card-body header figure.nft-image-container { 
display: flex; 
flex-direction: column; 
align-items: center; 
justify-content: center; 
margin: auto; 
border-radius: 12px; 
height: 306px; 
width: 301px; 
transition: 0.4s; 
position: relative; 
}

For the above code, this acts a container for the image elements, pseudoelements and pseudoclasses.

In the code, we use margin -> auto to center the element itself while we use flexbox to position child elements into the center of the div.

In preparation for our hover effect, we set this container to relative positioning.

Hover effects -

To style our image element to only appear when we hover over it, we give it opacity 0 in its default state and then center it to the middle of the div.

img.hover-icon { 
object-fit: contain; 
border-radius: 12px; 
width: 56.52px; 
height: 45.5px; 
left: 0; 
right: 0; 
margin-left: auto; 
margin-right: auto; 
opacity: 0; 
}

We make sure the images fit and retain a good aspect ratio so we use the property object-fit -> contain, then using absolute positioning, lift the image from the normal document flow and center the image to the div in front of the previous image(remember that the image would be hidden because the opacity is set to 0).

To display the image on hover we use.

header figure.nft-image-container:hover img.hover-icon { 
opacity: 1; 
z-index: 1; 
}

This lets the image only be displayed when the header element is hovered.

To create the green translucent area on hover.

header figure.nft-image-container:hover div.hover-layer-style { background-color: hsl(178deg, 100%, 50%); 
border-radius: 12px; 
width: 301px; 
height: 306px; 
opacity: 0.5; 
cursor: pointer; 
}

When the header hovers, the div layer is given the following properties above.

The opacity is set to half which allows it to be translucent and we can see the image beneath it.

Checkout full style here: GitHub Link

Section Element -

The section element holds the main body of our NFT Card, it carries the following document flow.

section -> h1.card-title -> p.nft-card-description -> aside.nft-card-data -> div.nft-card-duration -> div.nft-footer-profile

HTML Code here: GitHub Link

Wrapping up here.

section.nft-card-details { 
display: flex; 
flex-direction: column; 
align-content: flex-start; 
margin-top: 28px; 
width: 306px; 
height: 212px; 
}
aside.nft-card-data { 
display: flex; 
flex-direction: row; 
align-items: center; 
justify-content: space-between; 
margin-top: 27px; 
cursor: default; 
margin-bottom: 18px; 
}

Since our Frontend Mentors mockup design shows us an nft price and duration spaced apart in the same row, we use display -> flex and set a flex-direction -> row to our child elements into a row, we then set them apart from each other with justify-content -> space-between.

We do roughly the same for our floor profile picture, also adding a margin-left to-space icon from the text.

Finishing touches -

I had recently learned from an earlier Frontend Mentor project about using appropriate font sizes for deploying live sites.

You see, the problem I had before was assumed (like every developer) that just because it looked good on my machine means it will look just fine on others, boy was I wrong, I neatly set a lower end of 11px for font sizes.

Footers are my arch-enemy, In this case, I chose to take it easy and position them at the bottom of the page with both flexbox and absolute positioning.

footer.nft-card-footer { 
display: flex; 
flex-direction: column; 
position: relative; 
}

footer.nft-card-footer div.attribution { 
font-size: 11px; 
width: 100%; 
color: hsl(228deg, 45%, 44%); 
text-align: center; 
background-color: #fff; 
position: absolute; 
bottom: 0; 
}

And we're done with the NFT-Card Preview!! :)