Вопрос:

CSS: Предотвратить получение родительского элемента: активный псевдокласс при нажатии на дочерний элемент

html css html5 css3

6791 просмотра

12 ответа

1416 Репутация автора

JSFiddle

Когда вы нажимаете на button, вы видите, что :activeпсевдокласс запущен для родителя div. Существует ли чистый CSS (или некоторая библиотека JS) способ :activeпсевдокласса не переключаться при buttonнажатии?

Я пытался z-index, position: absolute & fixedно безуспешно.

Автор: knitevision Источник Размещён: 13.10.2015 11:36

Ответы (12)


13 плюса

37885 Репутация автора

Решение

Из спецификации :

Селекторы не определяют, находится ли родительский элемент элемента «: active» или «: hover» также в этом состоянии.

Это означает, что это зависит от реализации. Если реализация решила действовать именно так (как, очевидно, делают нынешние браузеры), в стандарте нет ничего, что могло бы это изменить.

С CSS4 вы можете сделать:

.parent:active:not(:has(:active)) {
   color: red;
}

но это еще не доступно и не доработано.

Автор: Amit Размещён: 13.10.2015 11:50

0 плюса

6938 Репутация автора

вот решение JQuery вместо использования псевдо-класса CSS :active

$(document).ready(function() {
    $('button').mousedown(function(e){
        e.stopPropagation();
        console.log('i got clicked');
    });

    $('div').mousedown(function(e){
        $('div').css('background', 'red')
    }).mouseup(function(e){
        $('div').css('background', '#eee')
    });
    $(document).mouseup(function(e){
        $('div').css('background', '#eee')
    });
});
div {
  width: 200px;
  height: 200px;
  background-color: #eee;
  border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <button>Qlick me</button>
</div>

Автор: indubitablee Размещён: 23.10.2015 01:43

4 плюса

2547 Репутация автора

Если вы действительно хотите решить эту проблему только с помощью CSS :

Если вы используете кнопку active, добавьте :before-pseudo-element и добавьте position: absolute;: перед тем же фоном, что и у родителей.

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

Теперь все, что нужно, это то, что родитель:

position: relative;
z-index: 0;

Посмотрите: http://jsfiddle.net/s0at4w4b/4/

Это не решает основную проблему, но является решением вашей текущей проблемы.

Автор: MMachinegun Размещён: 23.10.2015 03:20

2 плюса

3519 Репутация автора

Возможно, самый простой способ достичь того, что вы, вероятно, действительно хотите сделать, - это поместить кнопку «не помещать» внутрь, divкоторую вы не хотите активировать.

Здесь у вас есть контейнер div, который содержит фон div(эквивалент родительского divв вашем исходном примере). Фон divимеет активное состояние отдельно от кнопки.

.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>

Автор: Alfred Xing Размещён: 25.10.2015 09:03

0 плюса

1388 Репутация автора

Вместо div:active {...}вас следует кодировать div:active:not(:hover) {...}и background-colorостается нетронутым.

(старый фрагмент удален)

ОБНОВИТЬ

Чтобы сохранить основное divповедение и более общий подход, я обычно создаю несколько слоев.

Посмотрите на фрагмент ниже, переключение на greenэто просто для того, чтобы доказать, что он работает в то время, positionи aboluteпока он быстр и грязен:

#layer-data {
  width: 200px;
  height: 200px;
  background-color: #eee;
  border: 1px solid black;
}
#layer-data:active {
  background-color: red
}
#layer-btns:active {
  background-color: green
}
#layer-btns {
  z-index: 1;
  position: absolute;
  top: 1px;
  left: 1px;
  background: transparent;
  padding: 5px;
  width: auto;
  height: auto
}
#layer-data {
  z-index: 0;
  position: absolute;
  top: 0;
  left: 0;
  text-align: center;
  line-height: 200px
}
<div id="layer-btns">
  <button>Qlick me</button>
  <br/>
  <button>Qlick me too</button>
  <br/>
  <button>Qlick me three</button>
</div>

<div id="layer-data">
  some data-layer
</div>

Автор: Rene van der Lende Размещён: 26.10.2015 03:38

0 плюса

326 Репутация автора

Насколько я знаю, активное состояние будет пузыриться. Таким образом, все родительские узлы будут иметь активное состояние.

Таким образом, я не имею чистого решения CSS. Вы можете избежать решения javascript (которое, как я полагаю, является тем, что вам действительно нужно), изменив разметку так, чтобы div, имеющий активное состояние, больше не являлся родителем кнопки. Вы можете сделать их братьями и сестрами, например.

Затем CSS-часть этого решения исправляет макет, поэтому теперь он выглядит так же, как если бы он был родительским> дочерним.

Я не могу предложить вам более конкретного решения, я боюсь, не видя, как вы работаете, и ничего не понимая.

Автор: Harry Robbins Размещён: 27.10.2015 10:15

0 плюса

161 Репутация автора

попробуй это

HTML:

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

скрипт css:

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: включить файл библиотеки JQuery

Автор: becky1990 Размещён: 28.10.2015 04:22

0 плюса

11 Репутация автора

Псевдокласс: active применяется, когда элемент активируется пользователем. Например, между моментами, когда пользователь нажимает кнопку мыши и отпускает ее. В системах с более чем одной кнопкой мыши: активная применяется только к основной или основной кнопке активации (обычно это «левая» кнопка мыши) и любым их псевдонимам.

Могут существовать ограничения на язык документа или реализацию, в которых элементы могут стать активными. Например, [HTML5] определяет список активируемых элементов.

Родитель элемента, который соответствует: active, также соответствует: active. Так что нет пути

Автор: Albert Navasardyan Размещён: 29.10.2015 03:01

0 плюса

2600 Репутация автора

Кажется, нет никакого способа CSS справиться с этим делом. (не уверен насчет CSS4, как предложил Амит.) Итак, вот способ JQuery.

Идея в том, что вы управляете событиями mousedown и mouseup на 3 уровнях:

  1. родительский див
  2. кнопка, где вы не хотите, чтобы активное состояние распространялось на родительский div (".btn1" в примере ниже)
  3. любые другие дети, кроме кнопки во втором состоянии. («.btn2» в примере ниже)

JS Fiddle

HTML:

<div>
  <button class="btn1">Qlick me1</button>
  <button class="btn2">Qlick me2</button>
</div>

JQuery:

$(function(){
    $('div').each(function(e){
        $(this).mousedown(function(e){
            $(this).addClass("activeClass");
        }).mouseup(function(e){
            $(this).removeClass("activeClass");
        });
    });
    $('div .btn1').each(function(e){
        $(this).mousedown(function(e){
            e.stopPropagation();
        }).mouseup(function(e){
            e.stopPropagation();
        });
    });
    $('div :not(.btn1)').each(function(e){
        $(this).mousedown(function(e){
            $(this).parent().addClass("activeClass");
        }).mouseup(function(e){
            $(this).parent().removeClass("activeClass");
        });
    });
});

CSS:

div {
  width: 200px;
  height: 200px;
  background-color: #eee;
  border: 1px solid black;
}
.activeClass {
  background-color: red;
}
Автор: Vivek Athalye Размещён: 30.10.2015 08:02

0 плюса

1070 Репутация автора

Псевдоэлементы CSS невероятно полезны - они позволяют нам создавать треугольники CSS для всплывающих подсказок и выполнять ряд других простых задач, предотвращая при этом необходимость в дополнительных элементах HTML. До сих пор эти свойства CSS псевдоэлементов были недоступны JavaScript, но теперь есть способ их получить!

Проверь это:

http://davidwalsh.name/pseudo-element

http://davidwalsh.name/ways-css-javascript-interact

Автор: AsimRazaKhan Размещён: 30.10.2015 11:32

3 плюса

177956 Репутация автора

Я не думаю, что :hasпсевдокласс будет когда-либо доступен в таблицах стилей. Если браузеры наконец решат реализовать его, это будет возможно только для API-интерфейсов JS, таких как querySelector.

Тем не менее, у меня гораздо больше надежд :focus-within, которые, кажется, гораздо проще реализовать.

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

Конечно, он будет предотвращать :activeприменение только #parentпри нажатии на фокусируемый элемент, например кнопку. Вы можете сделать другие элементы фокусируемыми, добавивtabindex = "-1"

К сожалению, :focus-withinне поддерживается широко, но вы можете использовать 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 не разрешает хотлинкинг, поэтому приведенный выше фрагмент может не работать, если вы не скопируете полифилл на свой сервер и не используете его.

Автор: Oriol Размещён: 27.06.2016 01:04

0 плюса

2498 Репутация автора

Это может или не может работать для вас, но именно так я добиваюсь этого с помощью чистого CSS. Единственное предостережение - это зависимость, focus-withinкоторая не поддерживается IE или Edge.

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

Здесь происходит то, что родительский элемент получит активное состояние, так же как и дочерний элемент, по которому щелкают. Единственное отличие состоит в том, что фокус будет применяться к дочернему элементу, но только на следующем цикле . Чтобы обойти анимацию во время этого двухэтапного процесса, примените задержку в 1 мс. В следующем цикле элемент будет активен, но фокус будет применен к дочернему элементу. Таким образом, родитель не будет применять переход. Я думаю, animation delay: 1msчто будет работать так же.

Другой альтернативой является придание предмету tabindex=-1атрибута и использование

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

Единственная проблема, связанная с этим, заключается в том, что она может изменить поведение при навигации по клавиатуре, а также зависит от некоторого HTML. Если вы хотите использовать навигацию с помощью клавиатуры tabindex=0или любое другое значение -1. Но JS не используется.

Есть несколько хороших полифилов, focus-withinкоторые вы можете использовать для IE / Edge, но это выходит за рамки «Только CSS».

Но мы можем соединить их вместе, чтобы создать это:

.parent {
  transition: background-color;
}

.parent[tabindex]:active:focus {
  background-color: red;
}

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

Это работает на IE11, Edge и Chrome.

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

Автор: ShortFuse Размещён: 05.02.2018 06:23
Вопросы из категории :
32x32