如果鼠标悬停在 HTML 页面中的某个元素上,浏览器会为该元素及其所有父元素创建一个
:hover
伪类,即使鼠标没有悬停在父元素本身的任何部分上也是如此。
您可以在下面的代码片段中看到这一点。在“两个嵌套 Div”示例中,将鼠标悬停在蓝色方块上还将为其父红色方块创建一个
:hover
伪类。
是否有一个CSS选择器可以用来对鼠标做出反应仅当鼠标位于红色方块本身上方时?
我在三个重叠的 Div 示例中展示了一种解决方法。在这里,红色和蓝色方块是兄弟,并且在可见方块的交点处有一个不可见的方块 div。这个不可见的方块拦截了触发创建
:hover
伪类的指针事件。这使我能够编写 CSS,其反应就好像两个可见方块都有一个 :hover
伪类一样。当鼠标悬停在蓝色方块上时,它还可以防止 :hover
类附加到红色方块,因为没有继承。
但是,在三个重叠的 Div 示例中,蓝色方块不再是红色方块的子元素。在我的现实生活中,这种继承是我想要的。
:root {
--line: 1px;
--side: 1vmin;
--size: max(min(100vh, 50vw), min(50vh, 100vw));
--font: calc(var(--size) / 20);
--rect: calc(var(--size) * 0.666 - var(--line));
--drop: calc(var(--rect) * 0.5);
--edge: calc(var(--drop) - var(--side));
--red: #9009;
--blue: #0099;
--bg: #040;
}
body {
margin: 0;
height: 100vh;
color: #ddd;
background-color: #222;
font-size: 0;
display: flex;
justify-content: center;
align-items: center;
}
@media (aspect-ratio < 1/1) {
main {
width: var(--size);
}
}
div {
position: relative;
box-sizing: border-box;
}
div[id] {
font-size: var(--font);
display: inline-block;
width: var(--size);
height: var(--size);
border: var(--line) solid #ddd;
p {
position: absolute;
pointer-events: none;
z-index: 1;
span {
display: block;
width: var(--rect);
margin-top: 0.5em;
font-size: 0.7em;
}
}
div.red,
div.blue,
div.overlap {
width: var(--rect);
height: var(--rect);
border: var(--side) solid red;
}
div.red:hover {
background-color: var(--red);
}
div.blue {
border-color: blue;
&:hover {
background-color: var(--blue);
}
}
&#two {
background-color: var(--bg);
.blue {
top: var(--edge);
left: var(--edge);
}
}
&#three {
.blue {
position: absolute;
top: var(--drop);
left: var(--drop);
}
.overlap {
position: absolute;
top: var(--drop);
left: var(--drop);
width: var(--drop);
height: var(--drop);
border-color: transparent;
}
}
}
#three:has(.overlap:hover) {
.red {
background-color: var(--red);
}
.blue {
background-color: var(--blue);
}
}
<div id="two">
<p>Two nested divs
<span>Roll over the red square to highlight it</span>
<span>Rolling over the blue square also highlights its parent red square, even when the mouse is not over the intersection</span>
</p>
<div class="red">
<div class="blue"></div>
</div>
</div>
<div id="three">
<p>Three overlapping divs<span>Roll over either square to highlight it</span><span>Roll over the intersection to highlight both squares</span></p>
<div class="red"></div>
<div class="blue"></div>
<div class="overlap"></div>
</div>
将
.overlap
设为 .blue
的子级,并将 .blue
设为 .red
的子级,然后稍微更改 .red
的条件。
:root {
--line: 1px;
--side: 1vmin;
--size: max(min(100vh, 50vw), min(50vh, 100vw));
--font: calc(var(--size) / 20);
--rect: calc(var(--size) * 0.666 - var(--line));
--drop: calc(var(--rect) * 0.5);
--edge: calc(var(--drop) - var(--side));
--red: #9009;
--blue: #0099;
--bg: #040;
}
body {
margin: 0;
height: 100vh;
color: #ddd;
background-color: #222;
font-size: 0;
display: flex;
justify-content: center;
align-items: center;
}
@media (aspect-ratio < 1/1) {
main {
width: var(--size);
}
}
div {
position: relative;
box-sizing: border-box;
}
div[id] {
font-size: var(--font);
display: inline-block;
width: var(--size);
height: var(--size);
border: var(--line) solid #ddd;
p {
position: absolute;
pointer-events: none;
z-index: 1;
span {
display: block;
width: var(--rect);
margin-top: 0.5em;
font-size: 0.7em;
}
}
div.red,
div.blue,
div.overlap {
width: var(--rect);
height: var(--rect);
border: var(--side) solid red;
}
div.red:hover:not(:has(.blue:hover)),
div.red:has(.overlap:hover) {
background-color: var(--red);
}
div.blue {
border-color: blue;
&:hover {
background-color: var(--blue);
}
}
&#three {
.blue {
position: absolute;
top: var(--drop);
left: var(--drop);
}
.overlap {
position: absolute;
width: var(--drop);
height: var(--drop);
border-color: transparent;
}
}
}
<div id="three">
<p>Three overlapping divs<span>Roll over either square to highlight it</span><span>Roll over the intersection to highlight both squares</span></p>
<div class="red">
<div class="blue">
<div class="overlap"></div>
</div>
</div>
</div>