DEV Community

Thaísa Vieira
Thaísa Vieira

Posted on

NFT Preview Card Component Challenge from Frontend Mentor

Have you ever heard about Frontend Mentor? It's a website where you can improve your coding skills by building real-world projects professionally designed to help students of all levels practice HTML, CSS, and JavaScript. Also, since you made the challenge as close as the desired design you can use all the tools you like. Learning a new library? Testing your knowledge in fundamentals? Frontend Mentor is the right place to challenge yourself.
While in my studies I always keep something in mind:

"You can't cross the sea merely by standing and staring at the water" - Rabindranath Tagore

So, that is why Frontend Mentor is important in my weekly study schedule.

About the challenge

The NFT Preview Card Component is a challenge with HTML and CSS only, very indicated for newbies and beginners who want to test their skills with semantic HTML and flexbox CSS, also it's has a very important detail with a hover effect in the product image that will be discussed forward.

For this challenge, the goal is to build this preview card component and get it as close to the design as possible.

  • Desktop design:
    Desktop design

  • Mobile design:
    Mobile design

  • Active state design:
    Active state design

It's important to remember that the Sketch and Figma design file access can be unlocked with Frontend Mentor PRO (clicking on this link you can read more about it), these files contain things like the size of padding, margins, fonts, and image. Unfortunately, I don't have the PRO, so everything I have done was with the "Better Ruler" extension from Chrome/Brave.

My first step, as always, was to divide the design into smaller parts:

Design divided into smaller parts

For building this, I use simple things like Paint but the most important idea is to "see" those blocks, avoiding the anxiety of coding without thinking.

The first thing we have is a container, which will be our main section. Inside this container, we will have an image, a title, a subtitle, a price, and a "countdown" in a row, a single line, a profile image, and the name of the author with some text in a row. The hover effect is present in the "product" image, title, and in the author's name.

Note that to position the elements like the container, price, countdown, and profile image with the author's name we will use the flexbox propriety.

Here we have the HTML structure:

<body>
  <main>
    <div class="container">
      <picture class="product">
        <a href="#"><img src="./images/image-equilibrium.jpg" alt="Equilibrium ilustrated" class = "product-image"></a>
      </picture>
      <h1 class="title">Equilibrium #3429</h1>

      <h2 class="description">Our Equilibrium collection promotes balance and calm.</h2>

      <div class="relevant-data">
        <p class="price"> <img src="./images/icon-ethereum.svg" alt="Ethereum icon"> 0.041 ETH</p>
        <p class="time-left"> <img src="./images/icon-clock.svg" alt="Clock icon">3 days left</p>
      </div>
      <hr>
      <footer>
        <picture>
          <img src="./images/image-avatar.png" alt="Author profile picture" class="profile-picture">
        </picture>
        <p class="author">Creation of <span>Jules Wyvern</span></p>
      </footer>

  </div>
  <div class="attribution">
    Challenge by <a href="https://www.frontendmentor.io?ref=challenge" target="_blank">Frontend Mentor</a>.
    Coded by <a href="https://github.com/thaisavieira">Thaísa Vieira</a>.
  </div>
  </main>

</body>
Enter fullscreen mode Exit fullscreen mode

And the CSS struture:

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html{
    font-size: 62.5%;
}

body {
    font-family: "Outfit", sans-serif;
}

main{
    height: 100vh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    background-color: var(--dark-blue-main);

}
.container{
    width: 35rem;
    height: 58rem;
    border-radius: 1.5rem;
    background-color: var(--dark-blue-card);
    box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.5);
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 2rem;
    gap: 2rem;
}

.product{
    width: 100%;
    height: 100vh;
}

.product img{
    width: 100%;
    display: block;
    border-radius: 1.5rem;
}

.title{
    font-size: 2.3rem;
    font-weight: 400;
    color: var(--white);
    cursor: pointer;
}

.description{
    font-size: 1.8rem;
    letter-spacing: 0.15rem;
    font-weight: 400;
    color: var(--soft-blue);
}


.relevant-data{
    display: flex;
    flex-direction: row;
    justify-content: space-between;
}

.price{
    color: var(--cyan);
    font-weight: 500;
    font-size: 1.6rem;
    display: flex;
    align-self: baseline;
    gap: 0.5rem;

}

.time-left{
    color: var(--soft-blue);
    font-size: 1.6rem;
    display: flex;
    align-self: baseline;
    gap: 0.5rem;
}

hr{
    border-color: var(--soft-blue);
}

footer{
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 1.5rem;
    color: var(--soft-blue);
    font-size: 1.6rem;

}

footer span{
    color: var(--white);
    cursor: pointer;
}

.profile-picture{
    height: 2.6rem;
}

.attribution {
    font-size: 1.1rem;
    text-align: center;
    padding-top: 2rem;
    color: var(--white);
  }

  .attribution a {
    color: var(--cyan);
  }
Enter fullscreen mode Exit fullscreen mode

So, with these, we have build the desktop/mobile design:

And now, it's time to focus on the active state part.

The hover effect

The hover effect is made by the :hover CSS selector and is used to select elements when you mouse over them and the element responds with transition effects. That's a great way to enhance the user experience. Here's a CodePen example.

First, we will look again at the title and the author's name.

  • Product title
      <h1 class="title">Equilibrium #3429</h1>

Enter fullscreen mode Exit fullscreen mode
  • Author's name
        <p class="author">Creation of <span>Jules Wyvern</span></p>

Enter fullscreen mode Exit fullscreen mode

The hover effect:

 .title:hover, footer span:hover{
    color: var(--cyan);
}
Enter fullscreen mode Exit fullscreen mode

The :hover pseudo-class is triggered when the user hovers over the element with the pointer and it changes the appearance of the element while it is being used. This is a pretty simple part (note that I used the word simple and not easy!).

Now, let's look at the class .produt-image hover. When the user hovers over the element it changes to image opacity, adds a background color, and shows an icon on top of the product image, so it's a little bit more complex than our last case.

First, we have to add new properties to the class .product:

.product{
    position: relative;
    overflow: hidden;
    cursor: pointer;
}

Enter fullscreen mode Exit fullscreen mode

Setting the top, right, bottom, and left properties of a relatively positioned element will cause it to be adjusted away from its normal position. Other content will not be adjusted to fit into any gap left by the element.
And the propriety overflow: hidden the overflow is clipped, and the rest of the content is hidden.

And now, we can start with the effects. Let's keep in mind that the ::after selector inserts something after the content of each selected element and the content property to specify the content to insert.
Some questions have helped me:

Question 1: What's the content I wanna to insert?
Answer 1: The view icon.

Question 2: Is the icon the only thing I need to add?
Answer 2: No, I need to change the background color too.

Question 3: How do I need to it show up in the design? What'll happen to the original image?
Answer 3: I need the original image "stay behind", to appear and disappear smoothly when the user hovers over the element.

.product::after{
    content: url(/images/icon-view.svg);
    background-color: var(--cyan);
    position: absolute;
    inset: 0;
    display: flex;
    justify-content: center;
    align-items: center;
    opacity: 0;
    transition: all 0.25s ease;
}

.product:hover::after{
    opacity: 0.8;
}
Enter fullscreen mode Exit fullscreen mode

My main difficulty was to realize that I didn't need to add these proprieties in the .product-image class or .product img but in the "div container" that all the changes would happen.

It's my first time writing such a "long" post like this talking about my experience (with strong points, doubts, and difficulties) and I'd like to know if it is possible to make it clearer and how to make it even better.

Also, you can check the project here:

Repository: https://github.com/thaisavieira/nft-preview-card-component
Live website: https://thaisavieira.github.io/nft-preview-card-component/
Frontend Mentor profile: https://www.frontendmentor.io/profile/thaisavieira

Top comments (1)

Collapse
 
swaraj_singh__ profile image
Swaraj Singh ☸️

Whoa! Bravo, @thaisavieira I find this to be really interesting! I would recommend that you also showcase this post on Twitter (now known as "X")!