<div id="container">
  <div class="rating-container">
    <span>Excellent</span>
    <div class="rating-buttons">
      <input type="radio" value="4" name="s1" class="rating">
      <input type="radio" value="3" name="s1" class="rating">
      <input type="radio" value="2" name="s1" class="rating">
      <input type="radio" value="1" name="s1" class="rating">
    </div>
    <span>Poor</span>
  </div>
  
  <div class="rating-container">
    <span>Excellent</span>
    <div class="rating-buttons">
      <input type="radio" value="4" name="s2" class="rating">
      <input type="radio" value="3" name="s2" class="rating">
      <input type="radio" value="2" name="s2" class="rating" checked>
      <input type="radio" value="1" name="s2" class="rating">
    </div>
    <span>Poor</span>
  </div>
</div>
@import url(https://fonts.googleapis.com/css?family=Montserrat);

.rating-container {
  background:#95a5a6;
  margin:10px 0;
  padding:15px 20px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,0.3);
  //Labels
  span {
    display:inline-block;
    font-family:Montserrat, sans-serif;
    &:first-child { margin-right:10px; }
    &:last-child { margin-left:10px; }
  }
  //Buttons
  .rating-buttons {
    display:inline-block;
    cursor:pointer;
    //The "rating" buttons
    input[type="radio"].rating {
      display:inline-block;
      background:red;
      margin:0 10px;
      cursor:pointer;
      //Instead of using labels to make a custom checkbox/radio button, I just used the &before element and put it on top of the checkbox
      &:before {
        position:relative;
        display:block;
        content:"";
        background:#bd584d;
        width:25px;
        height:25px;
        border-radius:50%;
        top:-5px;
        left:-5px;
        box-shadow:inset 0 0 2px rgba(0,0,0,0.4);
        transition:all 80ms ease 100ms;
      }
      &:hover {
        //Apply styles to this and all subsequent radio buttons
        /*  This is the reason why it has to go from high-to-low
            In CSS4, we should be able to use !, which will select
            up the DOM (select elements _before_ this one)  */
        &:before, ~:before {
          transition:none;
          background:#2ecc71;
          box-shadow:inset 0 0 4px rgba(0,0,0,0.4);
        }
      }
      &:checked {
        &:before {
          top:-7px;
          box-shadow:inset 0 0 0 4px rgba(0,80,0,0.4), 0 2px 0 rgba(0,80,0,0.7);
        }
        &:before, ~:before {
          background:#2ecc71;
        }
      }
    }
  }
}

//Just for the demo, includes hardcoded values
#container {
  padding:20px;
  width:400px;
  height:130px;
  margin:auto;
  text-align:center;
  position:absolute;
  top: 0; left: 0; bottom:0; right: 0;
}

//Better than a white background
body {
  background:#2c3e50;
}
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.