<div class="emoji">
  <i class="fas fa-question-circle emoji-icon"></i>
</div>
<div class="rating">
  <i class="far fa-star star" data-rate="1"></i>
  <i class="far fa-star star" data-rate="2"></i>
  <i class="far fa-star star" data-rate="3"></i>
  <i class="far fa-star star" data-rate="4"></i>
  <i class="far fa-star star" data-rate="5"></i>
</div>
body {
  padding: 0;
  margin: 0;
  background-color: #2c3e50;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  height: 100vh;
  position: relative;
}

.emoji {
  font-size: 30px;
  background-color: #34495e;
  width: 50px;
  height: 50px;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #27ae60;
  border-radius: 3px;
  transition: 0.5s;
  
  &:hover {
    transform: translateY(-20px) scale(1.7);
  }
}

.rating {
  margin-top: 15px;
  padding: 10px 20px;
  background-color: #34495e;
  border-radius: 3px;
  
  i {
    &.far {
      &.star {
        opacity: 0.2;
      }
    }
    &.star {
      color: #fff;
      font-size: 23px;
      margin: 0 4px;
      cursor: pointer;

      &.active {
        color: #f1c40f;
      }
    }
  }
}
View Compiled
const stars = document.querySelectorAll('.star');
const emojiIcon = document.querySelector('.emoji-icon');
const emojiContainer = document.querySelector('.emoji');

// add the click event listener on all stars
stars.forEach(star => {
  star.addEventListener('click', onClick);
});

// handle click 
function onClick(e) {
  
  const rating = parseInt(e.target.dataset.rate, 10);
  // get middle position of the clicked star
  const halfPos = e.target.offsetWidth / 2;
  // check if user clicks on left half of a star
  const isHalf = e.offsetX < halfPos;
  updateRating(rating, isHalf);
}

// update the rating by changing the stars colors
function updateRating(rating, isHalf) {
  stars.forEach(star => {
    star.classList.remove('fa-star-half-alt');
    star.classList.add('fa-star');
    star.classList.remove('active');
  });
  
  if(isHalf) {
    stars[rating-1].classList.remove('fa-star');
    stars[rating-1].classList.add('fa-star-half-alt');
  }
  
  for(let i = 0; i < rating; i++) {
    stars[i].classList.remove('far');
    stars[i].classList.add('fas');
    stars[i].classList.add('active');
  }
  
  for(let i = rating; i < stars.length; i++) {
    stars[i].classList.remove('fas');
    stars[i].classList.add('far');
  }
  
  updateEmoji(rating);
}

// update the emoji based on the rating
function updateEmoji(rating) {
  emojiIcon.classList = '';
  let emoji;
  switch (rating) {
    case 1:
      emoji = 'fa-sad-cry';
      break;
    case 2:
      emoji = 'fa-frown';
      break;
    case 3:
      emoji = 'fa-meh';
      break;
    case 4:
      emoji = 'fa-smile';
      break;
    case 5:
      emoji = 'fa-grin-alt';
      break;
    default:
      emoji = 'fa-question-circle';
  }
  
  emojiIcon.classList.add('fas', emoji, 'emoji-icon');
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://kit.fontawesome.com/81465618c0.js