• CSS选择器世界


    CSS选择器世界

    CSS选择器的分类与优先级

    css选择器分为四类:选择器、选择符(后代关系的空格、>、+、~、||)、伪类、伪元素(::before、::after、::first-letter等)。

    css的优先级:
    css的优先级有很多划分方法,所有的方法其实都大同小异。这里将CSS优先级划分为6个等级:

    • 0级:通配选择器(*)、选择符(+、>、~、空格、||)、逻辑组合伪类(:not()、:is()等)
    • 1级:标签选择器
    • 2级:类选择器、属性选择器、伪类
    • 3级:ID选择器
    • 4级:style内联属性
    • 5级:!important

    CSS优先级的计算规则:0级选择器优先级数值+0,1级选择器+1,2级选择器+10,三级选择器+100

    #foo a:not([ref=nofollow]){}     优先级数值:100+1+0+10 = 111

    tips1:增加CSS优先级的小技巧
    重复自身选择器,如以下选择器即提高了优先级,又不会增加耦合:
    .foo.foo
    或者如下写法:
    .foo[class] 、 #foo[id]
    tips2: 实现类似:first-child的效果
    有如下场景,我们希望列表除了第一个第一个以外其他的都有margin-top,一般我们会这样写:

    1:.cs:not(:first-child){margin-top:1em;}
    2:.cs{margin-top:1em};
    .cs:first-child{margin-top:0}

    下面我们利用兄弟选择器:

    .cs+.cs{margin-top1em}

    tips3:实现前面兄弟选择符的效果
    如下场景:输入框聚焦时,前面文字高亮显示
    1:flex布局;
    2:float浮动;
    3:absolute绝对定位;
    4:direction属性实现,代码如下:

    <div class="cs-direction">
      <input class="cs-input"><label class="cs-label">用户名:</label>
    </div>

    .cs-direction{
      direction: rtl
    }
    .cs-direction .cs-input,.cs-direction .cs-label{
      direction: ltr;
    }
    .cs-label{
      display:inline-block;
    }
    :focus + .cs-label{
     color: darkblue;
     text-shadow: 0 0 1px;
    }

    注意:使用direction属性时,针对的必须为内联元素,因此,对于块级元素需进行转化为内联

    属性选择器

    • [attr]

    • [attr = ''val']

    • [attr ~= 'val']

    • [attr ^= 'val']

    • [attr $= 'val']

    • [attr *= 'val']

    用户行为伪类

    1:手型经过伪类:hover(支持所有HTML元素)

    一个简单的应用场景:当鼠标经过a标签时,'显示' 文字显示,因为:hover是即时的,所以通过transition对visibility进行过渡(trantion对display不起作用)起到时延作用。

      <a href class="icon-deletedata-title="显示">删除</a>

    .icon-delete{

        display: inline-block;
        height: 20px;
        position: relative;
      }
      .icon-delete::before{
        content: attr(data-title);
        position: absolute;
        bottom: 30px;
        left: 0;
      }
      .icon-delete::before,
      .icon-delete::after {
        transition: visibility 00.2s;
        visibility: hidden;
      }
      .icon-delete:hover::before,
      .icon-delete:hover::after {
        visibility: visible;
      }

    纯hover显示浮层的体验问题:纯hover显示浮层确实很方便,但是如果鼠标坏了,或者是触屏设备通过Tab来切换,如果是一个下拉列表,那么久完全瘫痪了,我们可以通过增加:focus来优化css,上述代码可以优化为:

    <a href class="icon-deletedata-title="删除">删除</a>

     .icon-delete{

        display: inline-block;
        height: 20px;
        position: relative;
      }
      .icon-delete::before{
        content: attr(data-title);
        position: absolute;
        bottom: 30px;
        left: 0;
      }
      .icon-delete::before,
      .icon-delete::after {
        transition: visibility 00.2s;
        visibility: hidden;
      }
      .icon-delete:hover::before,
      .icon-delete:hover::after {
        visibility: visible;
      }
    .icon-delete:focus::before,
    .icon-delete:focus::after {
        visibility: visible;
        transition: none;
    }

    但是,上述并没有解决所有的问题,如果浮层的内部有链接或者按钮的话,使用:focus浮层内的连接或者按钮是无法被点击的,因为Tab在切换焦点元素的时候,浮层会失焦而迅速隐藏。这时需要另外一个伪类:focus-within来解决,详细我们在下面讨论。


    2:激活伪类:active
    :active可以用于设置元素激活状态的样式,可通过点击鼠标主键,也可以通过手指或者触控笔点击触摸屏触发激活状态。具体表现为 点击按下触发,点击抬起取消。:active支持所有HTML元素

    :active的不足之处:

    • IE浏览器下,:active无法冒泡。即当一个元素与父级都设置:active样式时,点击子元素,父元素的:active不会被触发
    • IE浏览器,html、body用:active设置背景后,背景色无法还原;
    • 移动端safari浏览器下,:active伪类默认无效

    按钮的通用:active样式技巧(主要应用移动端)
    在桌面端可以通过:hover来反馈状态变化,移动端只能通过:active来反馈,移动端有很多需求点击反馈链接跟按钮,有如下通用技巧:

    • 使用box-shadow(兼容IE9,该方法对非对称闭合标签无效)
     [href]:active,button:active{
        box-shadow:  0 0 0 999px rgba(0,0,0,.05);
      }
    • 使用linear-gradient线性渐变(兼容IE10以上)
    [href]:active,button:active,[type=reset]:active,[type=button]:active,[type=submit]:active{
      background-imagelinear-gradient(rgba(0,0,0,.05),rgba(0,0,0,.05));
    }

    3:焦点伪类:focus(支持IE8+)
    :focus只能匹配特定的元素,包括:

    • 非disabled状态的表单元素;
    • 包含href的<a>元素
    • <area>、<summary>

    那么如何让普通的元素也可以用:focus伪类呢?
    设置HTML tabindex属性,如下写法:

     <div tabindex='-1'>内容</div>
     <div tabindex='0'>内容</div>
     <div tabindex='1'>内容</div>

    如果期望<div>元素被Tab索引,且被点击的时候触发:focus伪类样式,设置tabindex='0';如果期望不希望被索引,只在点击的时候触发:focus,则设置为-1。
    如下,实现点击一个图标显示大图的交互:

    <span class="cs-smalltabindex='0'></span><span class="cs-big"></span>

    .cs-small{

        display: inline-block;
         10px;
        height: 10px;
        background: green;
      };
      .cs-big{
        display: inline-block;
         50px;
        height: 50px;
        background: green;
        margin-left: 10px;
        display: none;
      };
      :focus + .cs-big{
        display: inline-block;
      }

    实际上,使用tabindex也并不是那么完美,在ios safari浏览器下,元素处于focus状态后,除非有其他可聚焦的元素转移焦点,否则会一直保持聚焦状态。解决方法只需要再套个父盒子,设置tabindex=‘-1’,同时该复盒子需要取消outline样式(outline:0 none;)

    4:整体焦点伪类:focus-within(移动端以及非IE浏览器)

    :focus-within功能通:focus类似,但是:focus是对当前元素而言,:focus-within在当前元素或者当前元素的子元素处于聚焦状态都会匹配。
    例::focus-within 实现无障碍访问的下拉列表,解决上面:focus在浮层里也有链接无法Tab切换的问题:

    <div class="cs-bar">
            <div class="cs-details">
              <a href='javascript:void(0)' class="cs-summary">我的消息</a >
              <div class="cs-datalist">
                <a href class="cs-datalist-a">我的回答<sup class="cs-datalist-sup">12</sup>
                </a >
                <a href class="cs-datalist-a">我的私信</a >
              </div>
            </div>
          </div>

    cs-bar {
        background-color: #e3e4e5;
        color: #888;
        padding-left: 40px;
        margin-bottom: 200px;
      }
      .cs-details {
        display: inline-block;
        text-align: left;
      }
      .cs-summary {
        display: inline-block;
        padding: 5px 28px;
        text-indent: -15px;
        user-select: none;
        position: relative;
        z-index: 1;
      }

      .cs-datalist {
        display: none;
        position: absolute;
        min- 100px;
        border: 1px solid #ddd;
        background-color: #fff;
        margin-top: -1px;
      }

      .cs-datalist-a {
        display: block;
        padding: 5px 10px;
        transition: background-color 0.2s, color 0.2s;
        color: inherit;
      }
      .cs-datalist-a:hover {
        background-color: #f5f5f5;
      }
      .cs-datalist-a:active {
        background-color: #f0f0f0;
        color: #555;
      }
      .cs-datalist-sup {
        position: absolute;
        color: #cd0000;
        font-size: 12px;
        margin-top: -0.25em;
        margin-left: 2px;
      }
       .cs-details:focus-within .cs-summary,
       .cs-summary:hover {
         background-color: #fff;
       }
       .cs-details:focus-within .cs-datalist {
         display: block;
       }

    URL定位伪类

    :link伪类(基本被a标签取代,不做讨论)

    :visited伪类(怪癖最多的CSS伪类)

    • 1:支持:visited的CSS属性有限
      目前仅支持以下CSS: color、background-color、border-color、border-bottom-color、border-top-color、border-left-color、border-right-color、column-rule-color、outline-color。类似::before跟::after也不支持。
      例:实现访问过的连接文字后面加上一个visited的字样
    <a href=''>文字<small></small></a>

      small{
        color: white;
      }
      small:after{
        content: 'visited';
      }
      a:visited small{
        color: lightskyblue;
      }
    • 2:没有半透明,该伪类控制颜色时,加透明度无效
    • 3:只能重置,不能凭空设置
      如下:
    a{
     color: blue;
    }
    a:visited{
     color: red;
     background-color: gray;
    }

    以上代码设置只会使color生效。

    • 4:无法获取:visited设置和呈现的色值
      该伪类设置的色值,用js的getComputedStyle()无法获取。

    :any-link伪类(IE9+)
    两大特性:
    1.匹配所有设置了href的连接元素,包括<a>、<link>、<area>
    2.匹配所有匹配:link伪类或者:visited伪类的元素(:link只匹配没有访问过的连接)
    目标伪类:target
    URL锚点可以跟页面中元素的id匹配进行锚定,例:

    <div>
           <p id='cs-first'>第一行,id:cs-first</p>
           <p id='cs-second'>第二行,id:cs-second</p>
           <p id='cs-last'>第三行,id:cs-last</p>
         </div>

    p:target{
        font-size: bold;
        color: skyblue;
      }

    通过链接的hash值就可以匹配到对应的元素

    树结构伪类

    :root伪类
    在html中:root等同于html元素;
    :empty伪类

    • :empty用来匹配空标签元素
    • :empty伪类可以匹配前后闭合的替换元素(button、textarea等);
    • :empty伪类匹配非闭合的元素(input、img等)

    若元素有注释或者空格、换行等都是不能匹配到的
    ::before、::after都可以插入内容,但是不会影响:empty的匹配

    :empty的实际应用

    • 隐藏空元素。
      比如像一个动态列表有内容的时候可能会加margin、padding等布局,但是没有内容的时候就会空出一大块,这时候就可以用:empty伪类在匹配到空的时候隐藏掉。
    • 字段缺失只能提示
      如在一个动态详情列表中,如果对应的字段没有内容,则在后面显示 '暂无'的字样,代码如下:
      <dl>
       <dt>姓名:</dt><dd>张三</dd><br/>
       <dt>年龄:</dt><dd></dd><br/>
       <dt>身高:</dt><dd>178cm</dd>
      <dl>

      dt,dd{
        display: inline-block;
      }
      dd:empty:before{
        content: '暂无';
      }

    子索引伪类

    :first-child、:last-child
    :only-child
    :nth-child()伪类和:nth-last-child()伪类

    适用于动态匹配场景,可以匹配制定索引序号的元素。参数可以是关键字(odd/even),也可以是函数符号。
    函数符号形式如下:

    1. An+B: A、B必须为整数,n前面可以有负数,n为从1开始的自然序列(0,1,2…..),第一个子元素匹配序号为1.
    2. 一些示例:
    • tr:nth-child(odd),匹配1、3、5…..行;
    • tr:nth-child(even),匹配2、4、6…..;
    • li:nth-child(1),匹配第一个;
    • li:nth-child(n+4):nth-child(-n+10): 匹配4-10个li
    :first-of-type伪类和:last-of-type伪类

    表示当前标签类型元素第一个和最后一个

    :only-of-type
    :nth-of-type()伪类和:nth-last-of-type伪类

    :nth-of-type与:nth-child的不同之处::nth-of-type匹配的是所有相同标签的兄弟元素,而另一个无视标签类型。

    <div>
      <h3>标题一</h3>
      <p>段落一</p>
      <p>段落二</p>
      <h3>标题二</h3>
      <p>段落三</p>
      <p>段落四</p>
    </div>

      p:nth-child(2n+1){
        color: red;
      }
      p:nth-child(4n){
        color: darkblue;
      }
      p:nth-of-type(2n+1){
        color: skyblue;
      }

    图中,第2、5行为浅蓝色,第三行为红色。

    逻辑组合伪类

    否定伪类:not()
    :not()主要的应用场景为重置CSS
    例:input:not(:disabled):not(:read-only)()
    表示匹配所有不处于禁用,也不是只读状态的input

    例: 列表一行5个,每个都向右有空隙,每一行的最后一个没有空隙;

     li:not(:nth-of-type(5n+1)){
       margin-right10px;
     }

    任意匹配伪类:is()
    例:

      .cs-a img,.cs-b img,.cs-c img,.cs-d img{
        border1px solid skyblue;
      }
      可以简化为如下:

      :is(.cs-a,.cs-b,.cs-c,.cs-dimg{
        border1px solid skyblue;
      }

    :where()、:has()

    输入伪类

    输入控件状态:

    可用状态与禁用状态伪类 :enabled和:disabled (IE9+)
    • 对于表单元素来说,:enable跟:disabled是完全对立的。但是有一个例外<a>元素,在chrome浏览器下,带href的a元素是可以匹配:enabled伪类的,但是却无法匹配:disabled伪类,其他浏览器也有各种各样的问题,不展开讨论。
    • 设置tabindex属性的元素不能匹配:enabled伪类;
    • 元素设置visibility:hidden跟display:none的能够匹配:enabled伪类跟:disabled伪类。
    读写特性伪类:read-only和:read-write

    readonly与disabled的区别:
    设置readonly的输入框不能输入内容,但是可以被表单提交;
    设置disabled的输入框不能输入内容美也不能被表单提交。

    占位符显示伪类:placeholder-shown(除IE)

    表示当输入框的placeholder内容显示的时候,匹配输入框
    由于其只在内容为空值状态的时候才显示,所以我们可以借助placeholder-shown伪类来判断一个输入框是否有值。
    例: 输入框没有值得时候显示空值提示

    input:placeholder-shown + small:before{
      content'尚未输入验证码';
      color: red;
    }
    默认选项伪类default

    输入值状态:

    选中选项伪类:checked
    1. :checked与[checked]的比较:
    • :checked只能匹配标准的表单控件元素,[checked]可以与任意元素匹配;
    • [checked]是非实时的,因此不建议用此属性选择器;
    • 伪类可以从祖先元素继承;
    不确定值伪类:indeterminate

    输入值验证:

    有效验证伪类:valid和:invalid
    范围验证伪类:in-range和:out-of-range
    可选性伪类:required和:optional

    参考资料:

  • 相关阅读:
    Python装饰器理解(新手)
    vue项目随笔
    ajax 请求数据传到后台为空字符
    关于document.body.scrollTop 的谷歌,火狐浏览器兼容问题
    Nginx 反向代理解决浏览器跨域问题
    SpringBoot maven build a new demo
    UI收集
    git
    编译
    网络2
  • 原文地址:https://www.cnblogs.com/ylweb/p/12348605.html
Copyright © 2020-2023  润新知