The rate scoring component is generally written in javascript. About a year ago, I wrote an article in Jane about the implementation of the star scoring component in native javascript. If you are interested, you can go to see it. Use CSS to achieve a rate score ❗ core code is also three lines 😂

rendering

The principle of

The comb is as follows:

  1. Go find a nice oneiconfont.Iconfont- Alibaba vector icon library;
  2. Borrow fiveradioSingle box, remove the default styles, show the default stars;
  3. withcheckedPseudo-class monitor user select ✅, from the default star to the highlighted star;
  4. And then with~The sibling operator highlights all currently selected sibling elements together 💥;
  5. The fiveradioSingle boxes in reverse order ❗;

code

This is my pre-generated iconfont

<link rel="stylesheet" href="//at.alicdn.com/t/font_1356455_c5d3d3ohlbq.css">
Copy the code

A very neat layout:

<div class="rate-content">
  <input type="radio" name="rate">
  <input type="radio" name="rate">
  <input type="radio" name="rate">
  <input type="radio" name="rate">
  <input type="radio" name="rate">
</div>
Copy the code

To display the default star:

// Remove the default style input {-webkit-appearance: none; border: none; outline: none; cursor: pointer; } .rate-content {$main: #ffa822; // Highlight colors
  $basic: # 999; // Default color// Single star input[name="rate"] {
    font-family: "iconfont"; Background-color: 30px; background-color: 30px; padding-right: 10px; // The default display of stars &::after {content:"\e645";
      color: $basic; transition: color .4s ease; // Add color transition effect}}}Copy the code

The effect is as follows:

Implement selecting a single star:

input[name="rate"] {// The highlighted star &:checked {&::after {content:"\e73c";
      color: $main; }}}Copy the code

The effect is as follows:

Implementation is highlighted with sibling elements:

input[name="rate"] {// Highlight the star &:checked, &:checked ~ input[name="rate"] {... }}Copy the code

The effect is as follows:

Then put theinputIn reverse order:

.rate-content {
  display: flex;
  flex-flow: row-reverse;
}
Copy the code

The effect is as follows:

Mouse over preview selected effect:

The verbose version:

input[name="rate"] {// Highlight the star &:checked, &:checked ~ input[name="rate"],
  &:hover,
  &:hover ~ input[name="rate"] {... }}Copy the code

Optimized version:

input[name="rate"] {// Hover {&:checked, &:hover {&::after {content:"\e73c";
      color: $main; } // Highlight & ~ input[name="rate"] {
      &::after {
        content: "\e73c";
        color: $main; }}}}Copy the code

The effect is as follows:

Add zoom in animation

input[name="rate"] { transition: transform .2s ease; Hover {// Hover {// hover {// hover {// hover {... } // hover {transform: scale(1.2); }}Copy the code

The effect is as follows:

conclusion

The core code is actually these two pieces, the others are optional 🈚

Elements in reverse order:

display: flex;
flex-flow: row-reverse;
Copy the code

Sibling element operations:

input:checked ~ input
Copy the code

Instead of using Flex, you can also use rotateZ:

.rate-content {
  display: flex;
  // flex-flow: row-reverse;
  transform: rotateZ(180deg);
}
Copy the code

The effect is as follows:

After rotating the z axis 180deg, the star’s head and tail are reversed, so the child element is rotated 180deg:

.rate-content {
  input[name="rate"] { transform: rotateZ(180deg); Hover {transform: scale(1.2) rotateZ(180deg); }}}Copy the code

The effect is as follows:

Attention to detail

input[name="rate"] {
  // padding-right: 10px;
  margin-right: 10px;
}
Copy the code

If margins were used, the following would happen:

Inside margins keep elements coherent and expand the range of clicks;

Finally, attach the codepen address of this article code: CSS implementation rate scoring;

About how to get points

Native javascript fetching is also easy, but you need to add values or custom indexes to each of the five inputs:

<input type="radio" name="rate" value="1">
<input type="radio" name="rate" value="2">
<input type="radio" name="rate" value="3">
<input type="radio" name="rate" value="4">
<input type="radio" name="rate" value="5">
Copy the code

Assume that the maximum score is 5:

const getScore = () => {
  let checkedInput = document.querySelector("input[name=rate]:checked"); Retrun checkedInput returns 0 retrun checkedInput? 5 - Number(checkInput.value) + 1: 0; }Copy the code

Why subtract, because the elements are in reverse order, and selecting the first is actually selecting the fifth 👌

How to achieve half a star

10 input, odd number display the left of the star, even number display the right of the star, other logic unchanged;

The last

If you think this article is good, please don’t forget to like and follow 😊