hover 父对子、子对父、同级之间的控制
- hover 父对子
- 指父元素触发hover事件,并且控制父元素中的子元素做出响应。js
<div class="d1"> <p class="p1">hello</p> </div> .d1:hover .p1{ color:#fff }
- 指父元素触发hover事件,并且控制父元素中的子元素做出响应。
- hover 同级之间
- 控制后续同层级的元素,使用
~或者+ - 用+号控制兄弟元素,但是只能控制一个元素,并且是相邻的后面的兄弟元素
- 用~号来控制兄弟元素,可以控制后面的所有兄弟元素,不用是相邻的元素js
<div class="d1"> <p class="p1">hello</p> </div> <div class="d2"> <p class="p1">hello</p> </div> .d1:hover + .d2{ background-color: #fff; } .d1:hover ~ .d2 .p1{ color: #fff; }
- 控制后续同层级的元素,使用
- hover 子对父
- 这里首先要了解
:has伪类选择器:has伪类的语法非常简单,表示满足一定条件后,就会匹配该元素。jsa:has(> img) //只会匹配直接包含 img 子元素的 a 元素: h1:has(+ p) //只会匹配其后紧跟着 p 元素的 h1 元素- 表单元素必填项html
<form> <item> <label>用户名</label> <input required /> </item> <item> <label>备注</label> <input /> </item> </form> <style> label:has(+input:required)::before{ /*可以通过 :has 在必填项的前面加上红色的星号 */ content: '*'; color: red; } </style> - 拖拽指定区域html
<div class="content"> <div class="item">列表<span class="thumb"></span></div> <div class="item">列表<span class="thumb"></span></div> <div class="item">列表<span class="thumb"></span></div> </div> <style> .thumb{ /**/ opacity: 0 } .item:hover .thumb{ opacity: 1; } .item:has(.thumb:hover){ -webkit-user-drag: element; } </style> - 多层级 hoverhtml
<div class="box-1"> <div class="box-2"> <div class="box-3"></div> </div> </div> <style> div:hover{ outline:4px dashed rebeccapurple /*会有类似冒泡的效果,hover里层,外层元素也会触发同样的hover*/ } div:not(:has(:hover)):hover{ outline:4px dashed rebeccapurple /* div:has(:hover) 表示有子元素正处于 hover 的 div ,比如当 hover 到 box-3 时, div:has(:hover) 选中的就是除 box-3 以外的两个父级,然后加上 :not 就刚好反过来,只选中 box-3 本身*/ } </style> - 评星组件html
<star> <input name="star" type="radio" /> <input name="star" type="radio" /> <input name="star" type="radio" /> <input name="star" type="radio" /> <input name="star" type="radio" /> </star> <style> star{ display: flex; } star [type="radio"]{ appearance: none; width: 40px; height: 40px; margin: 0; cursor: pointer; background: #ccc; transition: .3s; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E %3Cpath d='M462.3 62.6C407.5 15.9 326 24.3 275.7 76.2L256 96.5l-19.7-20.3C186.1 24.3 104.5 15.9 49.7 62.6c-62.8 53.6-66.1 149.8-9.9 207.9l193.5 199.8c12.5 12.9 32.8 12.9 45.3 0l193.5-199.8c56.3-58.1 53-154.3-9.8-207.9z'%3E%3C/path%3E %3C/svg%3E") center / 80% no-repeat; } /*交互功能,当 :hover 或者 :checked 时,当前元素和当前元素之前的元素都触发选中.在之前,由于只有后置兄弟选择器 ~ ,所以必须要将 dom 元素更改顺序,然后通过其他方式在视觉上再翻转过来。*/ /*[type="radio"]:has(~:hover) 表示选中当前 hover 元素之前的元素*/ star [type="radio"]:hover, star [type="radio"]:has(~:hover), star:not(:hover) [type="radio"]:checked, star:not(:hover) [type="radio"]:has(~:checked){ background: orangered; } </style> - 日期范围选择html
<div class="date"> <span>1</span> <span>2</span> <span class="select">3</span> <!--先看选中的功能,当有两个元素被选中时,这两个元素之间的元素都会匹配上,假设选中的类名是 select--> ... <span class="select">30</span> <span>31</span> </div> <style> /*通过 :has 找到 select 之前的元素,再结合 ~ 匹配之后的元素,两者结合就可以匹配到中间的元素了*/ .select, .select~span:has(~.select){ background-color: blueviolet; color: #fff; } /*第一条表示鼠标在已选中之前,匹配当前 hover 之后、 .selelct 之前的元素, 第二条表示已选中之后,匹配 .selelct 之后、 hover 之前的元素*/ span:hover~span:has(~.select), .select~span:has(~:hover) { background-color: blueviolet; color: #fff; } /*,需要区分一下选中两个和只选中一个的情况,因为两个表示区间选择已经完成,此时 hover 不会有效果,借助 :has 伪类,可以很轻易的区分子元素的个数*/ .date:not(:has(.select~.select)){ /*匹配到没有两个.select的父级*/ } .date:not(:has(.select~.select)) .select, .date:not(:has(.select~.select)) span:hover{ background-color: transparent; color: inherit; outline: 2px solid blueviolet; outline-offset: -2px; } /*.select~.select表示选中.select 后面的 .select ,也就是表示至少有两个 .select ,然后通过 :has 就可以区分这两种情况了*/ .date:not(:has(.select~.select)) span:hover~span:has(~.select), .date:not(:has(.select~.select)) .select~span:has(~:hover) { background-color: blueviolet; color: #fff; } </style> <script> //元素的选中时通过 JS 实现的,这时候的 JS 完全就只是工具人了,和视觉完全不相干,只需要记录选中的元素 date.addEventListener('click', ev => { const current = date.querySelectorAll('.select'); if (current.length == 2) { current.forEach(el => { el.classList.remove('select') }) } ev.target.classList.add('select') }) </script>
- 这里首先要了解
一些好用的选择器
- :focus-within :自己或者后代元素被聚焦时
- ::first-letter :选中第一个字母
- ::selection :鼠标选中的文字