Making radio buttons look like buttons instead

JqueryHtmlCss

Jquery Problem Overview


I would like to have a set of radio buttons for a donation form, however I want them to look like buttons instead of the circle dials.

What is the best approach to making something like that? Also, keep in mind, it has to work with IE8.

Here's what I have so far, http://jsfiddle.net/YB8UW/

.donate-now {
     list-style-type:none;
     margin:25px 0 0 0;
     padding:0;
}

.donate-now li {
     float:left;
     margin:0 5px 0 0;
}

.donate-now label {
     padding:5px;
     border:1px solid #CCC; 
     cursor:pointer;
}

.donate-now label:hover {
     background:#DDD;
}

Thank you

Jquery Solutions


Solution 1 - Jquery

It can be done with CSS and without the need of a large framework. I have done this with checkboxes and radio buttons.

This works without adding new HTML, or bringing in any JS libraries. => jsFiddle

THE NEW ORDER OF THE HTML

This is the ten minute hacky version, you can clean it up even further, but it shows a good example of how simple it is.

.donate-now {
  list-style-type: none;
  margin: 25px 0 0 0;
  padding: 0;
}

.donate-now li {
  float: left;
  margin: 0 5px 0 0;
  width: 100px;
  height: 40px;
  position: relative;
}

.donate-now label,
.donate-now input {
  display: block;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

.donate-now input[type="radio"] {
  opacity: 0.01;
  z-index: 100;
}

.donate-now input[type="radio"]:checked+label,
.Checked+label {
  background: yellow;
}

.donate-now label {
  padding: 5px;
  border: 1px solid #CCC;
  cursor: pointer;
  z-index: 90;
}

.donate-now label:hover {
  background: #DDD;
}

<ul class="donate-now">
  <li>
    <input type="radio" id="a25" name="amount" />
    <label for="a25">$25</label>
  </li>
  <li>
    <input type="radio" id="a50" name="amount" />
    <label for="a50">$50</label>
  </li>
  <li>
    <input type="radio" id="a75" name="amount" checked="checked" />
    <label for="a75">$75</label>
  </li>
  <li>
    <input type="radio" id="a100" name="amount" />
    <label for="a100">$100</label>
  </li>
  <li>
    <input type="radio" id="other" name="amount" />
    <label for="other">other:</label>
  </li>
  <li>
    <input type="text" id="otherAmount" name="numAmount" />
  </li>
</ul>

Solution 2 - Jquery

EDIT: this isn't a solution if you need to support IE browsers.


You could use CSS appearance property:

$(':radio').on('change', function() {
  console.log(this.id);
});

input[name=amount] {
  display: none
}

.donate-now {
  list-style-type: none;
  margin: 25px 0 0 0;
  padding: 0;
}

.donate-now li {
  float: left;
  margin: 0 5px 0 0;
}

.donate-now label {
  padding: 5px;
  cursor: pointer;
  -webkit-appearance: button;
  /* WebKit */
  -moz-appearance: button;
  /* Mozilla */
  -o-appearance: button;
  /* Opera */
  -ms-appearance: button;
  /* Internet Explorer */
  appearance: button;
  /* CSS3 */
}

.donate-now label:hover {
  background: #DDD;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="donate-now">
  <li>
    <label for="a25">
            <input type="radio" id="a25" name="amount">$25</label>
  </li>
  <li>
    <label for="a50">
            <input type="radio" id="a50" name="amount">$50</label>
  </li>
  <li>
    <label for="a75">
            <input type="radio" id="a75" name="amount" checked="checked">$75</label>
  </li>
  <li>
    <label for="a100">
            <input type="radio" id="a100" name="amount">$100</label>
  </li>
  <li>
    <label for="other">
            <input type="radio" id="other" name="amount">other:
            <input type="text" id="otherAmount" name="numAmount">
        </label>
  </li>
</ul>

-webkit-appearance: button; /* WebKit */
-moz-appearance: button; /* Mozilla */
-o-appearance: button; /* Opera */
-ms-appearance: button; /* Internet Explorer */
appearance: button; /* CSS3 */

Solution 3 - Jquery

OR IF YOU WANT TO DO THIS YOURSELF...

What I would do would be to create the buttons with the <button> element and a hidden form field element to remember which one is "pressed" like so:

<button type="button" id="btn1">Choice 1</button>
<button type="button" id="btn2">Choice 2</button>
<button type="button" id="btn3">Choice 3</button>
<input type="hidden" id="btnValue" value="" />

You will CSS to show that the button is "pressed down" or not "pressed down" so you would need them by default to be something like this:

button
{
    border-width: 2px;
    border-style: outset;
    border-color: /*Insert a darker version of your button color here*/
}

Then in jQuery (if you can do it in jQuery, you can do it in straight JavaScript, so keep that in mind if you don't want to use jQuery):

$("#btn1").click(function () {
    $(this).css("border-style", "inset")
    $("#btn2").css("border-style", "outset;");
    $("#btn3").css("border-style", "outset;");
    $("btnValue").val("btn1IsPressed");
});
$("#btn2").click(function () {
    $(this).css("border-style", "inset")
    $("#btn1").css("border-style", "outset;");
    $("#btn3").css("border-style", "outset;");
    $("btnValue").val("btn2IsPressed");
});
$("#btn3").click(function () {
    $(this).css("border-style", "inset")
    $("#btn1").css("border-style", "outset;");
    $("#btn2").css("border-style", "outset;");
    $("btnValue").val("btn3IsPressed");
});

Now all you need to do is request the value from #btnValue after POST (or GET or whatever), just like you normally would to tell which "button" they had pressed.

Be advised you will need to add a little more functionality to "unpress" the buttons, but I think you get the point. All you would need to do is read the value of #btnValue on click and, along with your other statements,use an if branch to handle whether it is already pressed or not and switch the borders accordingly (don't forget to clear ("") the value of #btnValue on the "unpressing" of a button so you can tell whether they left them all unpressed or not).

Solution 4 - Jquery

Unfortunately you can't style radio buttons directly in any browser. The way to do it is to use <label> elements with properly set for attributes, then hide the radio button itself using visibility: hidden rather than display: none. You can then position the labels wherever you want and they will act as radio buttons. You will need a bit of javascript to control the styling of the labels based on the state of the <input> element because IE8 won't support advanced CSS pseudoclasses like :checked.

It's a bit of a hack but it is the only way to use native radio buttons with custom graphics and still preserve accessibility.

Solution 5 - Jquery

Try this simple logic with jQuery.

$.each($('.radio-btn'), function(key, value) {
  $(this).click(function(e) {
    $('.radio-btn-selected')
      .removeClass('radio-btn-selected')
      .addClass('radio-btn');

    $(this)
      .removeClass('radio-btn')
      .addClass('radio-btn-selected');

    //do whatever you want on click
  });
});

.radio-btn-row {
  display: flex;
  flex-direction: row;
  justify-content: center;
  margin-top: 20px;
}

.radio-btn-wrapper {
  margin: 0px 4px;
}

.radio-btn {
  background-color: #FFFFFF;
  border: 1px solid #4A4A4A;
  color: #4A5362;
  font-size: 14px;
  line-height: 26px;
  outline: none;
}

.radio-btn-selected {
  background-color: #FFFFFF;
  border: 1px solid #55BC7E;
  color: #55BC7E;
  font-size: 14px;
  line-height: 26px;
  outline: none;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="radio-btn-row">
  <div class="radio-btn-wrapper">
    <button id="bt1" class="radio-btn" type="button">Button 1</button>
  </div>
  <div class="radio-btn-wrapper">
    <button id="btn2" class="radio-btn" type="button">Button 2</button>
  </div>
  <div class="radio-btn-wrapper">
    <button id="btn3" class="radio-btn" type="button">Button 3</button>
  </div>
  <div class="radio-btn-wrapper">
    <button id="btn4" class="radio-btn" type="button">Button 4</button>
  </div>
  <!--No matter how many buttons do you want -->
</div>

Solution 6 - Jquery

/* Adapted from https://stackoverflow.com/a/16243163 */

.donate-now label,
.donate-now input {
  text-align: center;
  align-items: center;
  justify-content: center;
  position: absolute;
  display: flex;
  width: 100px;
  height: 50px;
  border: 1px solid #CCC;
  padding: 0;
  cursor: pointer;
}

.donate-now input[type="radio"] {
  display: none;
}

.donate-now label:hover {
  background: #DDD;
}

.donate-now input[type="radio"]:checked + label {
  background: yellow;
}

#a25 {
  top: 20px;
  left: 20px;
}

#a50 {
  top: 20px;
  left: 140px;
}

#a75 {
  top: 20px;
  left: 260px;
}

#a100 {
  top: 20px;
  left: 380px;
}

#other {
  top: 20px;
  left: 500px;
}

#otherAmount {
  top: 20px;
  left: 620px;
}

<!-- Adapted from https://stackoverflow.com/a/16243163 -->

<div class="donate-now">
  <input type="radio" id="a25" name="amount" checked="checked" />
    <label for="a25" id="a25">$25</label>
  <input type="radio" id="a50" name="amount" />
    <label for="a50" id="a50">$50</label>
  <input type="radio" id="a75" name="amount" />
    <label for="a75" id="a75">$75</label>
  <input type="radio" id="a100" name="amount" />
    <label for="a100" id="a100">$100</label>
  <input type="radio" id="other" name="amount" />
    <label for="other" id="other">other:</label>
  <input type="text" id="otherAmount" name="numAmount" />
</div>

An adapted version of https://stackoverflow.com/a/16243163 to work without having to have all of the buttons next to each other. Change the CSS as you see fit to adjust the positions. jsFiddle

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRichardView Question on Stackoverflow
Solution 1 - JqueryPlantTheIdeaView Answer on Stackoverflow
Solution 2 - JqueryA. WolffView Answer on Stackoverflow
Solution 3 - JqueryVoidKingView Answer on Stackoverflow
Solution 4 - JquerynullabilityView Answer on Stackoverflow
Solution 5 - JquerySerenkiyView Answer on Stackoverflow
Solution 6 - JquerySomeRandomStackOverflowUserView Answer on Stackoverflow