Step-By-Step Solution: Interactive rating component

Let's Get Technical

Here is a link to the challenge discussed in this article

Hey there! Often I have written articles challenging you to participate in a few of the FrontEnd Mentor IO challenges. Today I will share a step-by-step guide to solving the Interactive Rating Card challenge Here are the steps:

The Design

For the styling, We will use an external CSS file and only plain CSS over SCSS/SASS

We will also implement a single-page application using JavaScript by making the thank you page a modal

Write the HTML

There are comments to help with any questions. Leave a comment if your questions are not answered:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="icon" type="image/png" sizes="32x32" href="./images/favicon-32x32.png">
  <link rel="stylesheet" href="style.css"> //link to CSS styling
  <title>Frontend Mentor | Interactive rating component</title>
</head>

<body>
  <main> //The main element holds all the contents of the page 
    //    START OF SECTION ONE
  <section class="section_one"> // This section has the content for all rating
      <div>
        <img src="images/icon-star.svg" alt="star image">
      </div>
      <h1>How did we do?</h1>
      <p> Please let us know how we did with your support request. All feedback is appreciated 
        to help us improve our offering!
      </p>
      <ul class= "rating-btns">
        <li class="rating-no">1</li>
        <li class="rating-no">2</li>
        <li class="rating-no">3</li>
        <li class="rating-no">4</li>
        <li class="rating-no">5</li>
      </ul>
      <button class="submit-btn">Submit</button>
    </section>
//    END OF SECTION ONE

//    START OF SECTION TWO
  <section class="thankyou-container"> // This section has the content for the thankyou note
    <div>
      <img src="images/illustration-thank-you.svg" alt="transactional image">
    </div>
    <h2 class="message-title">You selected <span class="display-rating">
      <!-- rating goes here-->
    </span> out of 5</h2>
    <h2> Thank you!</h2>
    <p> We appreciate you taking the time to give a rating. If you ever need more support, don’t hesitate to get in touch!
    </p>
  </section>
//    END OF SECTION TWO
</main>
<script src="main.js"></script> //  Link to the JavaScript file
</body>
</html>

Let's Add the styles with CSS(the best part)!

//import the font Cabin and Overpass
@import url('https://fonts.googleapis.com/css2?family=Cabin:ital,wght@0,400;0,500;0,600;0,700;1,400;1,500;1,600;1,700&family=Overpass:ital,wght@0,200;0,300;0,400;0,700;1,400;1,700&display=swap');


//set up the css variable for repeated styles
:root{
    --mainOrange: hsl(25, 97%, 53%);
    --whiteShade: hsl(0, 0%, 100%);
    --lightGrey: hsl(217, 12%, 63%);
    --mediumGrey: hsl(216, 12%, 54%);
    --darkBlue: hsl(213, 19%, 18%);
    --veryDarkBlue: hsl(216, 12%, 8%);
    --fontFamily: 'Overpass', sans-serif;
    --transition: all 0.5s ease-in-out;

}
body{
    background-color: var(--veryDarkBlue);
    font-family: var(--fontFamily);
    display: flex;
    align-items: center;
    justify-content: center;
}

//General styling for the pages
section{
    background-color: var(--darkBlue);
    border-radius: 1.5rem;
    display: flex;
    flex-direction: column;
    color: var(--whiteShade);
    gap: 0.2rem;
    width: 100%;
    max-width: 19rem;
    margin: 3rem auto;
    padding: 2rem;
    box-sizing: border-box;
}
p{
    color: var(--lightGrey);
    font-size: 0.9rem;
    margin: 0;
}
.rating-btns{
    display: flex;
    gap: 1rem;
    align-items: center;
    justify-content: center;
    padding: 0;
}
.rating-btns li{
    border-radius: 100%;
    list-style-type: none;
    background-color: var(--mediumGrey);
    opacity: 0.6;
    font-weight: 700;
    width: 35px;
    height: 35px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--fontFamily);
    font-size: 0.8rem;
    transition: var(--transition);
    cursor: pointer;
}
.rating-btns li:hover{
    background-color: var(--lightGrey);
    opacity: 1;
}
//this enables the background color to change to orange on click
.rating-btns li.active-rate{ 
    background-color: var(--mainOrange);
    opacity: 1;
}
.submit-btn{
    background-color: var(--mainOrange);
    height: 2.4rem;
    border-radius: 50px;
    outline: none;
    border: none;
    color: var(--whiteShade);
    text-transform: uppercase;
    letter-spacing: 0.2rem;
    font-family: var(--fontFamily);
    transition: var(--transition);
    cursor: pointer;

}
.submit-btn:hover{
    background-color: var(--whiteShade);
    color: var(--mainOrange);
}

//the thanyou page code set to display none
.thankyou-container{
    align-items: center;
    text-align: center;
    gap: 0.1rem;
    display: none; --->> for the thankyou page to only appear on submission of a rating
}
.message-title{
    background-color: rgb(75, 74, 74);
    border-radius: 1.2rem;
    padding: 0.3rem 0.5rem;
    font-size: 0.8rem;
    font-weight: 400;
    color: var(--mainOrange);
}

Add interactivity with JavaScript:

This involves creating event listeners and manipulating the DOM.

const mainSection = document.querySelector('.section_one')
const thankyouSection = document.querySelector('.thankyou-container')

const ratingCard = document.querySelector('.rating-btns')
const ratingValues = document.querySelectorAll('.rating-no')

const submitBtn = document.querySelector('.submit-btn')
const pickedRating = document.querySelector('.display-rating')
let rating;

//the active-rate is only added on the clicked number of rating
let parseRating = (e) => {
    ratingValues.forEach(item => item.classList.remove('active-rate'))
    e.target.classList.add('active-rate')
    rating = e.target.innerText
}

// the thankyou page display is changed from none to flex and vv for rating card
let getRating = (e) => {
    e.preventDefault
    mainSection.style.display = "none"
    thankyouSection.style.display = "flex"
    pickedRating.innerText = `${rating}`
}

// add events
ratingCard.addEventListener('click', parseRating);

submitBtn.addEventListener('click', getRating)

Test your code:

Before you submit your solution to Frontend Mentor, be sure to test your code thoroughly. This might involve checking for errors in the console, testing the responsiveness of the design, or ensuring that any functionality works as expected.

My GitHub Code

If you wish to see the code, find it on my GitHub repository

Be sure to add all the correct images and a ReadME file, in case you have files you need to ignore add them in the .gitignore file/

Thank you for reading be sure to ask any questions you may have. All the best!

Good luck!