skip to Main Content
div {
  padding: 1em;
}

div:has(input:focus-visible) {
  outline: 2px auto red;
  border: 0;
}

div:has(input:focus-within) {
  border: 1px solid green;
  outline: none;
}
<div>
  <input/>
</div>

I have a container with an input inside and some other divs. What I want to achieve is when I focus with the keyboard (using Tab) on the input, the container should be outlined with red, and when I directly click on the container, it should be bordered with green. But in this case only green works.

3

Answers


  1. You need JavaScript to achieve the second part of your question, you can add a click event listener on the document and check whether the inputContainer === e.target in case you want the effect when clicking on the container only or inputContainer.contains(e.target) in case you want the effect when clicking on the container or any of its children:

    const inputContainer = document.querySelector('.inputContainer');
    document.addEventListener('click', function(e) {
      if (inputContainer === e.target) {
        inputContainer.classList.add('green-border');
      } else {
        inputContainer.classList.remove('green-border');
      }
    })
    .inputContainer {
      padding: 10px;
    }
    
    .inputContainer:has(input:focus-visible) {
      border: 1px solid red;
    }
    
    .inputContainer.green-border {
      border: 1px solid green;
    }
    <div class="inputContainer">
    
     <input />
    
    </div>
    Login or Signup to reply.
  2. You can do it with Javascript event listeners, stopping the bubbling at the right times:

    let input = document.querySelector(".input");
    let container = document.querySelector(".container");
    
    input.addEventListener("focus", function() {
        this.parentNode.style.border = "2px solid red";
    });
    
    input.addEventListener("click", function(evt) {
        evt.stopPropagation();
    });
    
    container.addEventListener("click", function (evt) {
        this.style.border = "1px solid green";
        evt.stopPropagation();
    });
    
    document.body.addEventListener("click", function() {
        container.style.border = "";
    });
    div {
      padding: 1em;
    }
    
    body {
        height: 100%;
        width: 100%;
    }
    <div class="container">
      <input class="input" />
    </div>
    Login or Signup to reply.
  3. This will create the behavior you describe, which is, if you tab to the input, the container with have a red outline. If you click the container, it will have a green border. If, however, you click the input, the container will have the red outline, since the input has focus, and the div :has it, so the selector matches.

    div {
      padding: 1em;
    }
    
    div:has(input:focus-visible) {
      outline: 2px auto red;
      border: 0;
    }
    
    div:focus {
      border: 1px solid green;
      outline: none;
    }
    <div tabindex=0>
      <input/>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search