skip to Main Content

I have a div with some input fields:

<div class="container">
  <input id="input-a" type="text" name="input-a" tabindex="0">
  <input id="input-b" type="text" name="input-b" tabindex="0">
</div>

In special cases I have to disable this div by adding the following .disable class to the div:

.disable {
    pointer-events: none;
    opacity: .15;
}

This way it is no further possible to select the input fields with the mouse. However, you can still access the fields by tabbing into them via tab key. I have tried to add tab-index: -1 to the .disable class, but that just gives me an Invalid property name in the Firefox developer tools (tabindex without hyphen as well).

Is there any way to disable the input fields through CSS comepletely so that no access at all can be guaranteed?

2

Answers


  1. You cannot directly manipulate the tabindex attribute via CSS, as it is an HTML attribute responsible for defining the tab order of elements on a page. To achieve the desired behavior of making input fields inaccessible when applying the .disable class to the container div, JavaScript is necessary. You can dynamically set the tabindex attribute to -1 on the input elements under these conditions.

    Here’s an example of how you can do this with JavaScript:

    <div class="container">
      <input id="input-a" type="text" name="input-a" tabindex="0">
      <input id="input-b" type="text" name="input-b" tabindex="0">
    </div>
    
    <style>
      .disable {
        pointer-events: none;
        opacity: 0.15;
      }
    </style>
    
    <script>
      function disableInputs() {
        const container = document.querySelector('.container');
        const inputs = container.querySelectorAll('input');
        container.classList.add('disable');
        inputs.forEach(function(input) {
          input.tabIndex = -1;
        });
      }
    
      function enableInputs() {
        const container = document.querySelector('.container');
        const inputs = container.querySelectorAll('input');
        container.classList.remove('disable');
        inputs.forEach(function(input) {
          input.tabIndex = 0;
        });
      }
    
      // Call the functions to disable and enable inputs as needed
      // For example, you can call disableInputs() when you want to disable them.
    </script>
    

    In this example, the disableInputs() function applies the .disable class to the container div, effectively rendering the input elements unselectable through both mouse and keyboard interaction by setting their tabindex attributes to -1. Conversely, the enableInputs() function removes the .disable class and resets the tabindex values to 0, restoring the ability to select the inputs.

    Login or Signup to reply.
  2. I don’t think it is achievable by only use of CSS. I wasn’t able to find any way of setting up the tab index value with CSS.

    Only way I can image if it comes to vanilla JavaScript would be to select the elements and add the disable attribute (https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/disabled) to the inputs:

    function toggleDisable() {
      const container = document.querySelector('#container');
      const inputs = container.querySelectorAll('input');
    
      if (container.classList.contains('disable')) {
        container.classList.remove('disable');
        inputs.forEach((input) => {
          input.disabled = false;   
        });
      } else {
        container.classList.add('disable');
        inputs.forEach((input) => {
          input.disabled = true;
        });
      }
    }
    .disable {
      pointer-events: none;
      opacity: 0.5;
    }
    <h4>Container for comparison:</h4>
    <div id="different-container">
      <input id="input-a" type="text" name="input-a" tabindex="1">
      <input id="input-b" type="text" name="input-b" tabindex="2">
    </div>
    
    <h4>Container we want to disable inputs in:</h4>
    <div id="container">
      <input id="input-a" type="text" name="input-a" tabindex="3">
      <input id="input-b" type="text" name="input-b" tabindex="4">
    </div>
    
    <h4>Container for comparison:</h4>
    <div id="different-container2">
      <input id="input-a" type="text" name="input-a" tabindex="5">
      <input id="input-b" type="text" name="input-b" tabindex="6">
    </div>
    
    <h4>Use button to disable/enable the targeted container's inputs:</h4>
    <div>
      <button onclick="toggleDisable()">Toggle Disable</button>
    </div>

    Additionally, instead of adding the disable class you can use :disable pseudo class to style the elements as you want them. (https://developer.mozilla.org/en-US/docs/Web/CSS/:disabled)

    In that case the code would look like this:

    function toggleDisable() {
      const inputs = document.querySelectorAll('#container input');
    
      inputs.forEach((input) => {
        input.disabled = !input.disabled;
      });
    }
    #container input:disabled {
      opacity: 0.5;
      background-color: red;
      border: 4px solid blue
    }
    <h4>Container for comparison:</h4>
        <div id="different-container">
          <input id="input-a" type="text" name="input-a" tabindex="1">
          <input id="input-b" type="text" name="input-b" tabindex="2">
        </div>
    
        <h4>Container we want to disable inputs in:</h4>
        <div id="container">
          <input id="input-a" type="text" name="input-a" tabindex="3">
          <input id="input-b" type="text" name="input-b" tabindex="4">
        </div>
    
        <h4>Container for comparison:</h4>
        <div id="different-container2">
          <input id="input-a" type="text" name="input-a" tabindex="5">
          <input id="input-b" type="text" name="input-b" tabindex="6">
        </div>
    
        <h4>Use button to disable/enable the targeted container's inputs:</h4>
        <div>
          <button onclick="toggleDisable()">Toggle Disable</button>
        </div>

    Hope that helps.

    Note: I changed the container class into id of the container, just to be more specific about what we want to disable. This solution can be also used with the class name – use <div class="container"></div> and then instead of #container selector will be .container. This can be used for example for grouping of the inputs if you want to apply same logic to different elements.

    Note 2: I also change the tab indexes from zero to ascending values, so it can be easily observed what is actually happening when you tab through them.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search