重学CSS(1)

1. CSS@规则

@charset
@import
@media
@page:打印机相关
@counter-style
@keyframes:https://www.w3.org/TR/css-animations-1/
@fontface:https://www.w3.org/TR/css-fonts-3/
@supports:不推荐使用该规则检测浏览器css兼容性
@namespace:

2. CSS规则的结构

3. CSS选择器

3.1 选择器语法

  1. 简单选择器
  • *
  • div 类型选择器,svg中有一个a标签和html中的a标签重复,注意使用@namespace区分
  • .cls 类选择器
  • #id id选择器
  • [attr=value] 属性选择器
  • :hover 伪类选择器
  • ::before 伪元素选择器
  1. 复合选择器
  • <简单选择器 ><简单选择器><简单选择器 >
  • *或者tagName必须写在前边
  1. 复杂选择器
  • <复合选择器><复合选择器>,子孙选择器
  • <复合选择器>">"<复合选择器>,父子选择器
  • <复合选择器>"~"<复合选择器>,兄弟选择器,p~ul选择前面有<p>元素的每个<ul>元素
  • <复合选择器>"+"<复合选择器>,兄弟选择器,div+p选择紧接在 <div> 元素之后的所有 <p> 元素
  • <复合选择器>"||"<复合选择器>,leve4新增,选中表格某一列

3.2 选择器的优先级

  • 行内样式 <div style="xxx"></div> ==> 标记a类
  • ID 选择器 ==> 标记b类
  • 类,属性选择器和伪类选择器 ==> 标记c类
  • 标签选择器、伪元素 ==> 标记d类
  • 计算方式[a,b,c,d] ==> a*N^ + b*N^2 + c*N + d,其中N在大多数浏览器中取值为65536

3.3 伪类

  1. 链接/行为
  • :any-link 匹配所有超链接
  • :link 匹配未访问的超链接,:visited 匹配已访问的超链接,这两个伪类只能修改元素的字体颜色
  • :hover
  • :active
  • :focus
  • :target
  1. 树结构
  • :empty 匹配没有子元素的元素
  • :nth-child()
  • :nth-last-child()
  • :first-child:last-childonly-child
  • 除了empty之外的伪类会增加CSS的计算难度,可能会影响浏览器样式渲染的性能
  1. 逻辑型
  • :not
  • :where:has,leve4新增

3.4 伪元素

  • ::before
  • ::after,设置content属性后就可以生成盒,像其他元素一样参与后续的布局排版
  • ::first-line,选择第一行
  • ::first-letter,选中第一个字母
    在这里插入图片描述

4 一个小练习

//元素和选择器是否匹配
function match(selector, element) {

    let selectorParts = selector.split(' ').reverse();
    let match = /(?<tagName>(\w+)?)(?<id>(#\w+)?)(?<classNames>(.[\w.]+)?)/;

    //取到第一个选择器,该选择器必须和当前节点匹配
    let part = selectorParts.shift();

    let matchResult = part.match(match);
    let {tagName, id, classNames} = matchResult.groups;

    let _tagName = element.tagName.toLowerCase();
    let _classList = element.className.split(' ');
    let _id = element.id;

    if(id && id !== ('#'+_id) || tagName && tagName !== _tagName) {
        return false;
    }

    if(classNames){
        let classList = classNames.split('\.').filter(val => !!val);
        if(_classList.length < classList.length) {
            return false;
        }else {
            for (let className of classList) {
                if (_classList.indexOf(className) === -1) {
                    return false;
                }
            }
        }
    }

    //走到此处说明已匹配目标元素
    let len = selectorParts.length, i = 0;
    element = element.parentElement;
    for(let part of selectorParts) {
        let matchResult = part.match(match);
        let {tagName, id, classNames} = matchResult.groups;

        element: while (element){
            let _tagName = element.tagName.toLowerCase();
            let _classList = element.className.split(' ');
            let _id = element.id;

            if(id && id !== ('#'+_id) || tagName && tagName !== _tagName) {
                element = element.parent;
                continue;
            }

            if(classNames){
                let classList = classNames.split('.').filter(val => !!val);
                if(_classList.length < classList.length) {
                    element = element.parent;
                }else {
                    for (let className of classList) {
                        if (_classList.indexOf(className) === -1) {
                            element = element.parent;
                            continue element;
                        }
                    }
                }
            }

            //走到此处证明匹配到了,则该跳出循环匹配下一个元素和选择器了
            element = element.parentElement;
            i++;
            break;
        }

        //判断元素是否为空,为空表示遍历到了根节点
        if(!element) {
            break;
        }

    }

    //i !== len说明选择器未遍历完,但是已经遍历到了根节点
    return i === len;
}


match("div #id.class", document.getElementById("id"));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值