skip to Main Content

so I am writing CSS and I have a grid of five radio buttons and one input. It’s supposed to be a part of a tip calculator, and in this particular section you select the tip percentage. With the radio buttons, you can only select one at at time.

enter image description here

However, I’m not entirely sure how to link the input with the radio buttons without Javascript. For example, if the user input a custom tip, I would not like for them to be able to click on other buttons without the custom input first being cleared. Is this possible without JS?

Here is my code:

input {
  font-family      : spaceMonoBold, sans-serif;
  width            : 100%;
  border           : none;
  background-color : var(--very-light-grayish-cyan);
  font-size        : 1.5rem;
  font-weight      : bold;
  text-align       : right;
  color            : var(--very-dark-cyan);
  padding          : .35rem 1rem;
  border-radius    : .25rem;
  }
.tip-button {
  display          : none;
  }
.tip-span {
  min-width        : 100%;
  height           : 100%;
  text-align       : center;
  display          : flex;
  justify-content  : center;
  align-items      : center;
  background-color : var(--very-dark-cyan);
  color            : var(--white);
  font-size        : 1.5rem;
  border-radius    : .25rem;
  cursor           : pointer;
  transition       : .1s;
  }
input:hover + .tip-span {
  background-color : var(--light-grayish-cyan);
  color            : var(--very-dark-cyan);
  }
input:active + .tip-span {
  transform        : scale(.9);
  transform        : rotate(3deg);
  }
input:checked + .tip-span {
  background-color : var(--strong-cyan);
  color            : var(--very-dark-cyan);
  }
<div class="input-wrapper tip-section">
  <label class="tip-header" for="">Select Tip %</label>
  <div class="tip-button-container">
    <label class="tip-label" for="5">
      <input type="radio" id="5" name="radio" class="tip-button">
      <span class="tip-span">5%</span>
    </label>
    <label class="tip-label" for="10">
      <input type="radio" id="10" name="radio" class="tip-button">
      <span class="tip-span">10%</span>
    </label>
    <label class="tip-label" for="15">
      <input type="radio" id="15" name="radio" class="tip-button">
      <span class="tip-span">15%</span>
    </label>
    <label class="tip-label" for="25">
      <input type="radio" id="25" name="radio" class="tip-button">
      <span class="tip-span">25%</span>
    </label>
    <label class="tip-label" for="50">
      <input type="radio" id="50" name="radio" class="tip-button">
      <span class="tip-span">50%</span>
    </label>
    <label for="custom" class="tip-label custom-label">
      <input type="radio" name="radio" class="tip-button">
      <input id="custom" name="radio" class="custom-tip" type="number" placeholder="Custom">
    </label>
  </div>
</div>

I’ve tried using the checked pseudo-class, but couldn’t get that to work.

2

Answers


  1. You cannot acheive that without Javascript, Here is a JS script that implement this:

    document.addEventListener('DOMContentLoaded', function() {
        const customTipInputField = document.getElementById('custom');
        const radioButtons = document.querySelectorAll('input.tip-button[type="radio"]');
    
        // Function to disable or enable radio buttons based on custom input value
        function toggleRadioButtons(disabled) {
            radioButtons.forEach(radio => {
                radio.disabled = disabled;
                const label = radio.nextElementSibling;
                if (disabled) label.style.cursor = 'not-allowed';
                else label.style.cursor = 'pointer';
            });
        }
    
        // Event listener for the custom tip input
        customTipInputField.addEventListener('input', function() {
            const customValue = customTipInputField.value;
            toggleRadioButtons(customValue !== '');
        });
    
        // Event listener for the radio buttons
        radioButtons.forEach(radio => {
            radio.addEventListener('change', function() {
                if (this.checked) {
                    customTipInputField.value = '';
                    toggleRadioButtons(false);
                }
            });
        });
    });
    Login or Signup to reply.
  2. Make the custom button also a radio input and have a separate input for the user to type the amount.

    This snippet shows that number input only when the custom button is checked.

    .tip-button-container:has(#freeform:checked)+#custom {
      display: block;
      border: solid 1px red;
      color: red;
    }
    
    #custom {
      width: 300px;
    }
    
    .tip-button-container {
      display: grid;
      gap: 20px;
      grid-template-columns: 1fr 1fr 1fr;
      width: 300px;
      --very-light-grayish-cyan: #eeeeee;
      --very-dark-cyan: gray;
    }
    
    input {
      font-family: spaceMonoBold, sans-serif;
      width: 100%;
      border: none;
      background-color: var(--very-light-grayish-cyan);
      font-size: 1.5rem;
      font-weight: bold;
      text-align: right;
      color: var(--very-dark-cyan);
      padding: .35rem 1rem;
      border-radius: .25rem;
    }
    
    .tip-button {
      display: none;
    }
    
    .tip-span {
      min-width: 100%;
      height: 100%;
      text-align: center;
      display: flex;
      justify-content: center;
      align-items: center;
      background-color: var(--very-dark-cyan);
      color: var(--white);
      font-size: 1.5rem;
      border-radius: .25rem;
      cursor: pointer;
      transition: .1s;
    }
    
    input:hover+.tip-span {
      background-color: var(--light-grayish-cyan);
      color: var(--very-dark-cyan);
    }
    
    input:active+.tip-span {
      transform: scale(.9);
      transform: rotate(3deg);
    }
    
    input:checked+.tip-span {
      background-color: var(--strong-cyan);
      color: var(--very-dark-cyan);
    }
    
    #custom {
      display: none;
    }
    <div class="input-wrapper tip-section">
      <label class="tip-header" for="">Select Tip %</label>
      <div class="tip-button-container">
        <label class="tip-label" for="5">
          <input type="radio" id="5" name="radio" class="tip-button">
          <span class="tip-span">5%</span>
        </label>
        <label class="tip-label" for="10">
          <input type="radio" id="10" name="radio" class="tip-button">
          <span class="tip-span">10%</span>
        </label>
        <label class="tip-label" for="15">
          <input type="radio" id="15" name="radio" class="tip-button">
          <span class="tip-span">15%</span>
        </label>
        <label class="tip-label" for="25">
          <input type="radio" id="25" name="radio" class="tip-button">
          <span class="tip-span">25%</span>
        </label>
        <label class="tip-label" for="50">
          <input type="radio" id="50" name="radio" class="tip-button">
          <span class="tip-span">50%</span>
        </label>
        <label class="tip-label" for="freeform">
          <input id="freeform" type="radio" name="radio" class="tip-button">
          <span class="tip-span">Custom</span>
        </label>
      </div>
      <input id="custom" name="radio" class="custom-tip" type="number" placeholder="Amount">
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search