Emojis are some of the most commonly used icons on social apps today. Whether you want to convey emotions or enhance communication, there is an emoji or a combination of emojis to accomplish the task. In this tutorial, we will build a rating emoji component that will allow the user to rate their level of satisfaction by using a slider.

HTML Structure

The HTML Structure will consist of a container div element with the following child elements:

  • A title and a subtitle
  • The image element to show the current emoji
  • A div to show the rating content.
  • A range input element.

Styling With CSS

We will start by applying the following styles to the body to center all our elements in the page. 

Bricolage Grotesque is a font available from Google fonts. And the color I’ve chosen uses a slight transparency so  that when the background changes, the text color will change too.

Lastly, you’ll see a transition property on the background, so that when we change the color it fades nicely from one to the other.

1
body {
2
  font-family: 'Bricolage Grotesque', sans-serif;
3
  display: flex;
4
  justify-content: center;
5
  align-items: center;
6
  flex-direction: column;
7
  min-height: 100vh;
8
  background: #fff;
9
  color: rgba(0,0,0,0.7);
10
  transition: background .5s ease-in-out;
11
}

For the container element, apply the following styles so that the child elements are centered and vertically stacked. 

1
.container {
2
  width: 300px;
3
  padding: 0 10px;
4
  background: #B4BED9;
5
  border-radius: 20px;
6
  padding: 40px 5px;
7
  display: flex;
8
  flex-direction: column;
9
  align-items: center;  
10
  text-align: center;
11
  justify-content: space-around;
12
  position: relative;
13

14
}

The title and subtitle are placed at the top of the container element with the following styles.

1
.title {
2
  font-size: 3rem;
3
  font-weight: 800;
4
  margin: 0 0 1rem 0;
5
  line-height: .9;
6
}
7
.subtitle {
8
  font-size: 1rem;
9
  margin: 0;
10
}

Custom Slider

The range input consists of a bar and a slider control element by default. The slider control element (the thumb) moves along the horizontal bar, allowing users to select a specific value. The input range also looks different depending on the browser it’s displayed on. Here is the default range input on Chrome.

range inputrange inputrange input

Instead of using the default slider above, we will customize it to look much better. Set -webkit-appearance: none; and appearance: none; on the range input. 

1
input[type="range"] {
2
  -webkit-appearance: none;
3
  appearance: none;
4
}

The effect of these styles is to remove the default appearance so that we can provide our custom style. Set the following  additional styles on the slider bar.

1
input[type="range"] {
2
  position: absolute;
3
  top: 85%;
4
  -webkit-appearance: none;
5
  appearance: none;
6
  width: 80%;
7
  background: #e5e5e5;
8
  height: 2px;
9
  border-radius: 5px;
10
  outline: none;
11
  box-shadow: #F2D2BD;
12
}

The appearance of the thumb varies across different browsers; hence, we will apply individual styles based on the browser to make the thumb consistent across different browsers. The style  -webkit-appearance: none;  will remove the default thumb style provided by the browser. Let’s  also apply a custom height, width, padding, and background color. 

1
input[type="range"]::-webkit-slider-thumb {
2
  -webkit-appearance: none;
3
  padding: 5px;
4
  height: 5px;
5
  width: 5px;
6
  border:5px solid #fff;
7
  border-radius: 50%;
8
  cursor: pointer;
9
  background: #4c4c4c;
10
}
11

12
/* FIREFOX */
13
input[type="range"]::-moz-range-thumb {
14
  padding: 5px;
15
  height: 5px;
16
  width: 5px;
17
  border:5px solid #fff;
18
  border-radius: 50%;
19
  cursor: pointer;
20
  background: #4c4c4c;
21

22
}

Set dimensions to the image and add a bounce effect animation.

1
@keyframes bounce {
2
  0%, 100% {
3
    transform: translateY(0);
4
  }
5
  50% {
6
    transform: translateY(-10px);
7
  }
8
}
9

10
img {
11
  height: 150px;
12
  width: 150px;
13
  outline: none;
14
  animation: dance 1s infinite;
15
}

Finally style the rating content div.

1
.rating {
2
  font-size: 20px;
3
  font-weight: 100;
4
  width: 150px;
5
}

JavaScript Functionality

As the value on the range input changes, we will use JavaScript to update the emoji type, the color of the container, and the rating message. 

I downloaded a brilliant set of 100 SVG emojis from Envato Elements, ideal for this project.

100 svg emojis100 svg emojis100 svg emojis

So, with my SVG icons selected and uploaded, let’s get our elements and define our data.

1
const container = document.querySelector('.container')
2
const slider = document.getElementById("slider");
3
const emoji = document.querySelector(".emoji");
4
const rate = document.getElementById("message");
5
const colors = ["#d35e65", "#d3965c", "#cad48a", "#6ed494", "#18c574"];
6
const emojis = [
7
  {
8
    text: "Awful",
9
    url: "Disappointed.svg"
10
  },
11
  {
12
    text: "Bad",
13
    url: "Sad.svg"
14
  },
15
  {
16
    text: "Okay",
17
    url: "Expressionless.svg"
18
  },
19
  {
20
    text: "Good",
21
    url: "Smile.svg"
22
  },
23
  {
24
    text: "Great",
25
    url: "Love.svg"
26
  }
27
];

The emojis array defines objects; each object contains an emoji image and text describing the emoji sentiment. We will use this data to dynamically display emojis based on user interactions with the rating component. 

Next, create a function called UpdateRating(). Inside the UpdateRating() function, get the value on the moving slider.

1
function UpdateRating() {
2
   const value =slider.value;
3
  }

Next, we will create if statements that will check the value on the slider and update the emoji style, the background color, and message depending on the value on the slider. Low values will attract a low rating, sad emojis, and negative messages, while high values will attract a high rating, positive messages, and positive emojis.

The slider spans from 0 to 100; we’ll therefore allocate each message a 20-unit interval.

Update the UpdateRating function as shown below.

1
function UpdateRating() {
2
  const value =slider.value;
3
  
4
  if (value >= 0 && value < 20) {
5
    emoji.src = emojis[0].url
6
    rate.textContent =  emojis[0].text;
7
    container.style.backgroundColor =colors[0];
8

9
  } else if (value >= 20 && value < 40) {
10
    emoji.src = emojis[1].url
11
    rate.textContent =  emojis[1].text;
12
    container.style.backgroundColor =colors[1];
13
    
14
  } else if (value >= 40 && value < 60) {
15
    emoji.src = emojis[2].url
16
    rate.textContent =  emojis[2].text;
17
    container.style.backgroundColor =colors[2];
18
    
19
  } else if (value >= 60 && value < 80) {
20
    emoji.src = emojis[3].url
21
    rate.textContent =  emojis[3].text;
22
    container.style.backgroundColor = colors[3];
23
    
24
  } else if (value >= 80 && value <= 100) {
25
    emoji.src = emojis[4].url
26
    rate.textContent =  emojis[4].text;
27
    container.style.backgroundColor = colors[4];   
28
  }}

Let’s refactor our conditional logic to ensure the code is not repetitive. Create a function called setProperties(), which takes index as an argument . Inside setProperties(),  add the repetitive logic.

1
function setProperties(index){
2
  emoji.src = emojis[index].url
3
  rate.textContent =  emojis[index].text;
4
  container.style.backgroundColor =colors[index];
5
  }

For each condition, call the setProperties() function like this:

1
function UpdateRating() {
2
  const value =slider.value;
3
 
4
  if (value >= 0 && value < 20) {
5
    setProperties(0)
6
    
7
  } else if (value >= 20 && value < 40) {
8
    setProperties(1)
9
    
10
  } else if (value >= 40 && value < 60) {
11
    setProperties(2)
12
    
13
  } else if (value >= 60 && value < 80) {
14
    setProperties(3)
15
    
16
  } else if (value >= 80 && value <= 100) {
17
    setProperties(4) 
18
  }}

Finally, we need to add an event listener to the input range. The event listener will listen for the oninput event and then call the UpdateRating() function. An oninput event occurs when the value of an input element is changed.Regarding the input range, the oninput event will provide real-time feedback(value) when the user interacts with it.  

1
slider.addEventListener("input", UpdateRating);

The UpdateRating() function will be invoked every time the user moves the slider.

Conclusion

This tutorial has covered how to build a functional emoji rating component. We have also learned how the input range element is styled on different browsers. To enhance the functionality, you can also request additional feedback from users.  

Let’s remind ourselves of what we’ve built—and I hope you enjoyed this experience!

©2024 SIRRONA Media, LLC.  All Rights Reserved.  

Log in with your credentials

Forgot your details?