CSS: Prevent parent element getting :active pseudoclass when child element is clicked

后端 未结 12 827
暖寄归人
暖寄归人 2021-01-07 16:19

JSFiddle

When you click the button, you see that :active pseudoclass is triggered for the parent div. Is ther

相关标签:
12条回答
  • 2021-01-07 17:04

    try this

    html:

    <div class="current" id="current">
      <button id="btnclick" >Qlick me</button>
    </div>
    

    css script:

    div {
      width: 200px;
      height: 200px;
      background-color: #eee;
      border: 1px solid black;
    }
    .current_active{
      background-color: red;
    }
    

    jquery:

    $("#btnclick").click(function(){
        $("#current").toggleClass("current_active");
    });
    

    JSFiddle

    ps: include the jquery library file

    0 讨论(0)
  • 2021-01-07 17:06

    If you really want to solve this with CSS only:

    If your button is active, add a :before-pseudo-element and with position: absolute; give the :before the same background as the parents.

    button:active::before {
        content: '';
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: #eee;
        z-index: -1;
    }
    

    Now all that is needed is that the parent is :

    position: relative;
    z-index: 0;
    

    Have a look: http://jsfiddle.net/s0at4w4b/4/

    This does not solve the underlying issue, but is a solution for your current problem.

    0 讨论(0)
  • 2021-01-07 17:09

    I don't think :has pseudo-class will ever be available in stylesheets. If browsers finally decide to implement it, it will probably be only for JS APIs like querySelector.

    However, I have much more hopes for :focus-within, which seems much simpler to implement.

    #parent:active:not(:focus-within) {
      background-color: red;
    }
    

    Of course, it will only prevent :active from being applied to #parent when clicking a focusable element like a button. You can make other elements focusable by adding tabindex = "-1"

    Sadly, :focus-within is not widely supported, but you can use a JS polyfill.

    #parent {
      border: 1px solid black;
      width: 300px;
      height: 300px;
    }
    #parent:active:not(.focus-within) {
      background-color: red;
    }
    <script src="https://gist.githubusercontent.com/aFarkas/a7e0d85450f323d5e164/raw/"></script>
    <div id="parent">
      <button>Click me</button>
      <p tabindex="-1">Or me</p>
    </div>

    Github does not allow hotlinking, so the snippet above might not work unless you copy the polyfill to your server and use it.

    0 讨论(0)
  • 2021-01-07 17:10

    The :active pseudo-class applies while an element is being activated by the user. For example, between the times the user presses the mouse button and releases it. On systems with more than one mouse button, :active applies only to the primary or primary activation button (typically the "left" mouse button), and any aliases thereof.

    There may be document language or implementation specific limits on which elements can become :active. For example, [HTML5] defines a list of activatable elements.

    The parent of an element that matches :active also matches :active. So there,s no way

    0 讨论(0)
  • 2021-01-07 17:13

    This may or may not work for you, but this is how I achieve it with pure CSS. The only caveat is the dependence of focus-within which isn't supported by IE or Edge.

    .parent {
      transition: background-color;
    }
    .parent:active:not(:focus-within) {
      background-color: red;      
      transition-delay: 1ms; // Delay one cycle to allow child to focus 
    }
    

    What's going on here is, the parent element will get the active state, as will the child that gets clicked. The only difference is that the focus will apply to the child element, but only on the next cycle. To circumvent any animations from while in this 2 step process, apply a 1ms delay. The next cycle, the element will be active, but the focus will be applied to the child. Thus, the parent will not apply the transition. I would imagine animation delay: 1ms would work the same way.

    Another alternative is to give the item a tabindex=-1 attribute and use

    .parent {
      transition: background-color;
    }
    .parent:active:focus {
      background-color: red;      
    }
    

    The only issue with this is the fact it may change keyboard navigation behavior and relies on some HTML as well. If you do want keyboard navigation use tabindex=0 or any value besides -1. But there's no JS used.

    There are some nice polyfills for focus-within that you can use for IE/Edge but that would go outside "CSS Only".

    But, we can put both of them together to create this:

    .parent {
      transition: background-color;
    }
    
    .parent[tabindex]:active:focus {
      background-color: red;
    }
    
    .parent:active:not(:focus):not(:focus-within) {
      background-color: red;
      transition-delay: 1ms;
    }
    

    This works on IE11, Edge, and Chrome.

    http://jsfiddle.net/s0at4w4b/42/

    0 讨论(0)
  • 2021-01-07 17:15

    Perhaps the simplest way of achieving what you probably really want to do is to put not put the button inside the div you don't want activated.

    Here, you have a container div, which contains a background div (the equivalent of the parent div in your original example). The background div has an active state separate from the button's.

    .container {
      position: relative;
      width: 200px;
      height: 200px;
    }
    .background {
      position: absolute;
      width: 100%;
      height: 100%;
      border: 1px solid black;
      background-color: #eee;
    }
    .background:active {
      background-color: red;
    }
    button {
      position: relative;
    }
    <div class="container">
      <div class="background"></div>
      <button>Click me!</button>
    </div>

    0 讨论(0)
提交回复
热议问题