整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

前端开发如何更好的避免样式冲突?级联层(CSS@layer)

者:vivo 互联网前端团队 - Zhang Jiqi


本文主要讲述了CSS中的级联层(CSS@layer),讨论了级联以及级联层的创建、嵌套、排序和浏览器支持情况。级联层可以用于避免样式冲突,提高代码可读性和可维护性。


一、什么是级联层(Cascade Layers)?


1.1 级联层的官方定义


我们参看Cascading and Inheritance Level 5(13 January 2022) 中6.4节所述:

级联层提供了一种结构化的方式来组织和平衡单个起源中的问题。单个级联层内的规则级联在一起,不与层外的样式规则交错。


开发者可以创建层来表现元素默认值、第三方库、主题、组件、覆盖和其他样式问题,并且能够以显式方式重新排序层级,而无需更改每个层内的选择器或特异性,或依赖源顺序来解决跨层的冲突。


单纯看官方定义和概括可能比较晦涩,下面我们会结合案例来说清楚。


1.2 级联层为了解决什么问题?


简而言之:级联层的出现就是为了使 CSS 开发者可以更简单直接地控制级联。


我们来假设日常开发中的一个场景,从场景去理解级联层在解决什么问题。


如下图:


我们原来的'display'文案是红色,当我们引入了一个第三方组件库,第三方库中有以下样式。

/* 开发者样式 */
  .item {
    color: red;
  }
 
/* 第三方库 */
  #app .item {
    color: green;
    border: 5px solid green;
    font-size: 1.3em;
    padding: 0.5em;
    width: 120px;
  }


就会导致'display'文案变成绿色。


我们想要将'display'文案的颜色由绿色改成红色一般的手段是增加选择器特异性(优先级)。比如在开发页面中对开发者样式进行修改:

 /* 开发者样式 */
  #app div.item {
    color: red;
  }
 /* 第三方库 */
  #app .item {
    color: green;
    border: 5px solid green;
    font-size: 1.3em;
    padding: 0.5em;
    width: 120px;
  }


或者借助级联中出场顺序对优先级的影响在用户页面中重写

 /* 第三方库 */
  #app .item {
    color: green;
    border: 5px solid green;
    font-size: 1.3em;
    padding: 0.5em;
    width: 120px;
  }
 /* 开发者样式 */
  #app .item {
    color: red;
  }


效果如下:


再举个例子:

比如有可能第三方组件写了

a { color: blue; }


那项目开发中由于引入这个第三方组件 就会导致样式污染,因为第三方库的样式往往都在项目设置的通用样式比如common.css后加载。


如果后面想在代码中覆盖某些属性,使用高特异性选择器的语句就可能会导致问题。然后因为有问题就会选择更高特异性的择器的语句或使用!important,这会使代码变得冗长也可能会带来副作用。低特异性选择器的语句很容易被后面出现在代码中的语句覆盖。在自己的代码之后加载第三方 CSS 时特别会出现这种问题。


所以级联层就是为了解决以上场景出现的,级联层在级联中的的位置是在内联样式和选择器特异性之间。当有些css声明就是设置要低优先级且不受选择器特异性影响那么使用级联层再合适不过。


运用级联层解决第一个日常开发场景痛点的css代码如下:

/* 排序层 */
@layer reset, lib;
/* 通用样式 */
@layer reset {
  #app .item {
    color: black;
    width: 100px;
    padding: 1em;
  }
}
/* 第三方库样式 */
/*我们将第三方库的样式全部放到lib层*/
/*这里一般使用@import导入的方式*/
/*为了示例简单我们简化了操作*/


@layer lib {
  #app .item {
    color: green;
    border: 5px solid green;
    font-size: 1.3em;
    width: 130px;
  }
}
/* 开发者样式 */
.item {
  color: red;
}


为了知道为什么上面的css代码能解决冲突问题,更好地理解级联层的作用,理解一些现象背后的根因,了解级联层和级联的关系,我们继续往下看。


二、理解级联层的前提——级联(cascade)


2.1 什么是级联?


CSS中有两个重要的基础规则,一个是继承,一个是级联。


继承

指的是类似 color,font-family,font-size,line-height 等属性父元素设置后,子元素会继承的特性。


级联

可以简单理解为是CSS 用来解决要应用于元素的具体样式的算法。也就是基于一些优先级排序输出给给定元素上属性值一个级联值。级联值是级联的结果。


2.2 当前级联的排序标准


我们参看Cascading and Inheritance Level 5(13 January 2022) 中6.1节,

相比于Cascading and Inheritance Level 4(14 January 2016) 中的定义有明显变化。


最重要的变化就是增加了级联层。由此级联排序变成:

  1. 起源和重要性(Origin and Importance)
  2. 上下文(Context)
  3. 样式属性(Element-Attached Styles)
  4. 层(Layers)
  5. 特异性(Specificity)
  6. 出场顺序(又名源代码顺序)(Order of Appearance)


浏览器在确定最终元素样式呈现的时候,会依据这些准则按照优先权从高到低排序,并且会一个一个的检查,直到确定最终样式。


2.3 级联起源(Cascading Origins)


2.3.1 三个核心起源


css中每个样式规则有三个核心起源,它决定了它进入级联的位置,理解起源优先级是理解级联的关键。

  • 用户代理来源(浏览器内置样式)
  • 用户来源(浏览器的用户设置 )
  • 作者来源(Web开发者)


2.3.2 起源的优先级


Css声明的起源取决于它来自哪里,重要性在于它是否用!important声明。


各种起源的优先级按降序排列:

  1. 过渡
  2. 重要的用户代理
  3. 重要用户
  4. 重要作者
  5. 动画
  6. 普通作者
  7. 普通用户
  8. 普通用户代理


越靠前来源的声明优先级越高。过渡和动画我们可以暂时忽略。


2.4 熟悉又陌生的 !important


通常作为开发者,!important会被我们视为一种增加特异性的方法,用以覆盖内联样式或特异性较高的选择器。


但是!important设计出来的初衷是作为整体级联中的一个特性,来平衡开发者、用户设置和浏览器内置之间对css优先级的影响能力。


默认情况下三者的优先级是:作者来源> 用户来源>用户代理来源(可以参看上文起源优先级中6-8的排序)。但是当css声明添加!important之后会使它们的优先顺序颠倒(参看上文起源优先级中2-4的排序)。


如果站在浏览器和用户的角度看!important提供了在必要时重获优先级控制权的能力,而非只是简单的增加特异性。


举个例子:

浏览器默认样式表包含我们开发者无法覆盖的重要样式。


浏览器对具有'hidden'类型的input输入框设置了默认的展示属性并且将其声明为重要。

input[type=hidden i] { display: none !important; }


看下面两张图例:


第一张可以看出我们对具有'hidden'类型的input输入框的展示属性设置成了显示并且声明为重要


第二张是样式最终计算结果:隐藏


从上面的浏览器表现可以看到我们作为开发者在作者样式表中设置的规则没能覆盖用户代理样式表中的相同规则。


这验证了上面说的:在级联中!important会颠倒三大核心起源默认优先顺序。


验证的过程中还发现了一个chrome控制台这边的bug,看上面的第一张图例:没生效的规则不划删除线,生效的反而划删除线了。


再看一个官方文档的例子加强一下理解:


图片来源:w3.org


font-size的值最终是‘12pt ’。

因为作者样式表中添加!important的规则优先权高于用户样式表中普通规则。


text-indent的值最终是‘1em’。

因为虽然两个样式表都标注了!important,但是标注!important用户声明优先级大于标注!important作者声明。


2.5 一张图带你理解级联


下图可以帮助我们直观的理解级联以及级联层在级联中的位置:


图片来源:css-tricks


我们会发现平时操作最多的选择器特异性(selector specificity)只是级联中的一小部分。也轻松地理解了为什么内联样式优先级天然高。同时我们会发现!important在级联中有特殊地位。他穿插在级联规则的各个阶段并能颠倒优先级。


三、级联层(CSS@layer) 使用探索


3.1 @layer 是什么?


我们来看MDN上的定义:

The @layer CSS at-rule is used to declare a cascade layer and can also be used to define the order of precedence in case of multiple cascade layers.

也就是说 @layer 这个at-rule(AT规则) 用于声明级联层(cascade layer),也能用于定义多个级联层的优先级。


At-rules 是什么?

At-rules是指导 CSS 如何表现的CSS 语句。它们以 at 符号 ' @' ( U+0040 COMMERCIAL AT) 开头,后跟一个标识符,包括下一个分号 ' ;' ( U+003B SEMICOLON) 或下一个CSS 块之前的所有内容。


我们开发常见的at-rule有@charset、@media、@font-face 、@keyframes 等。


3.2 @layer的句法规则


@layer的句法如下:

@layer layer-name {rules}
@layer layer-name;
@layer layer-name, layer-name, layer-name;
@layer {rules}


3.3 如何创建级联层


可以通过多种方式创建级联层。


第一种方法是:创建命名的级联层,其中包含该层的 CSS 规则,如下所示:

@layer green {
  .item {
    color: green;
    border: 5px solid green;
    font-size: 1.3em;
    padding: 0.5em;
    width: 120px;
  }
}
 
@layer special {
  .item {
    color: rebeccapurple;
  }
}


第二种方法是:创建一个命名的级联层而不分配任何样式。这可以是单层,如下所示:

@layer green;


可以一次定义多个层,如下:

@layer green, special


一次定义多个层有什么好处呢?

因为声明层的初始顺序决定了层的优先级。与声明一样,如果在多个层中找到声明,最后定义的层声明将最终生效。看下面代码:

@layer green,special;
 
@layer green {
  #app .item {
    color: green;
    border: 5px solid green;
    font-size: 1.3em;
    padding: 0.5em;
    width: 120px;
  }
}
@layer special {
  .item {
    color: rebeccapurple;
  }
}


效果如下图:


special层中item样式规则将被应用即使它的特异性低于 green层中的规则。这是因为一旦层顺序定义完成,就会忽略选择器特异性。


同样也会忽略出现的顺序:

我们声明层名称并设置它们的顺序后,可以通过重新声明名称来将 CSS 规则添加到图层。然后将样式附加到层,并且层顺序不会更改。比如如下代码虽然@layer green重新声明了并在文件后方但是由于顺序一开始已经设置所以字体颜色还是紫色:

@layer green,special;
 
@layer special {
  .item {
    color: rebeccapurple;
  }
}
 
@layer green {
  .item {
    color: green;
    border: 5px solid green;
    font-size: 1.3em;
    padding: 0.5em;
    width: 120px;
  }
}


效果如下:


忽略选择器特异性和代码出现顺序可以让我们创建更简单的 CSS 选择器,并使代码优雅,因为不必确保选择器具有足够高的特异性来覆盖其他css规则,只需要确保它出现在后面的层中。


第三种方法是:创建一个没有名称的级联层。例如:

@layer {
  .item {
    color: black;
  }
}


这将创建一个匿名级联层,该层功能与命名层相同。但是使用匿名层有如下缺点:

  1. 可读性较差:匿名层没有名称,会导致样式表不易阅读和理解。特别是在大型项目中,可能会出现样式不断增加,难以跟踪和管理的问题。
  2. 难以扩展:如果稍后想要更改特定样式或组合,也会很难找到特定的代码块。
  3. 不可复用性:匿名层中的样式不能在其他地方重复使用或引用。这样会使样式表更难以管理和维护。


平时我们尽量避免使用匿名层。但当我们是样式库的作者,并想将某些css代码不被使用者修改可以借助匿名层做到这一点。


第四种方法是:使用@import。CSS 原生支持 @import 导入其他 CSS 文件。

@import url(index.css) layer(index);


同时,也支持匿名引入,例如:

@import url(index.css) layer;


我们在使用@import时候需要放在除@charset之外的样式规则前,否则无法导入。


可能的第五种方式仍在讨论中:通过元素上的属性。请参阅[css-cascade] Provide an attribute for assigning ato a cascade layer #5853。


3.4 层的嵌套规则


图层可以嵌套。例如:

@layer base {
  p { max-width: 70ch; }
}
 
@layer framework {
  @layer base {
    p { margin-block: 0.75em; }
  }
 
  @layer theme {
    p { color: #222; }
  }
}


生成的层可以表示为一棵树:

1.base

  • framework
  • base

2.theme


或可以用扁平列表表示

  1. base
  2. framework.base
  3. framework.theme


要将样式附加到嵌套层,您需要使用以下全名来引用它:

@layer framework {
  @layer default {
     p { margin-block: 0.75em; }
  }
 
  @layer theme {
    p { color: #222; }
  }
}
 
@layer framework.theme {
  /* 这些样式会被添加到framework层里面的theme层 */
  blockquote { color: rebeccapurple; }
}


看效果:


3.5 层的排序规则


级联层按照它们声明的顺序排序。第一层优先级最低,最后一层优先级最高。但是,未分层的样式具有最高优先级:

/* 未分层 */a { color: green; }
@layer layer-1 { a { color: red; } }
@layer layer-2 { a { color: orange; } }
@layer layer-3 { a { color: yellow; } }


优先级顺序如下:

  1. 未分层样式
  2. layer-3
  3. layer-2
  4. layer-1


看下图示例:


层可以在一个地方被定义图层(以建立图层顺序),然后在任何地方添加样式

/* 定义在一个地方 */
@layer my-layer;
/* 其他样式*/
...
/* 在某个地方添加样式 */
@layer my-layer { a { color: red; } }


3.6 加上!important之后的排序规则


/* 未分层 */ a { color: green !important; }
@layer layer-1 { a { color: red !important; } }
@layer layer-2 { a { color: orange !important; } }
@layer layer-3 { a { color: yellow !important; } }


任何加上重要声明的样式都以相反的顺序应用


优先级顺序如下:

  1. !important layer-1
  2. !important layer-2
  3. !important layer-3
  4. !important 未分层样式


看下图示例:


这里我们看到对应规则在chrome浏览器的显示是正确的。但是在开发者控制台中的样式一栏规则显示有问题。应该是chrome浏览器开发者控制台的bug。


3.7 嵌套层的排序规则


@layer layer-1 { a { color: red; } }
@layer layer-2 { a { color: orange; } }
@layer layer-3 {
  @layer sub-layer-1 { a { color: yellow; } }
  @layer sub-layer-2 { a { color: green; } }
  /* 未嵌套 */ a { color: blue; }
}
/* 未分层 样式 */ a { color: black; }


优先级顺序如下:

  1. 未分层 样式
  2. layer-3
  3. -layer-3 未嵌套
  4. -layer-3 sub-layer-2
  5. -layer-3 sub-layer-1
  6. layer-2
  7. layer-1



3.8 媒体查询对层排序的影响


以下层顺序将取决于匹配的媒体条件:


例如:

@media (min-width: 600px) {
   @layer layout {
     .item {
       font-size: x-large;
     }
   }
 }
 
@media (prefers-color-scheme: dark) {
  @layer theme {
     .item {
        color: red;
     }
   }
}


如果两个媒体查询的规则中匹配一个那么对应的级联层生效。如果两者都匹配,那么图层顺序将为layout, theme都生效。如果两个都不匹配则不定义层。下图是两者都匹配的场景。


四、现在就能使用级联层吗?


4.1 目前浏览器支持程度



图片来源:developer.mozilla.org


目前所有现代浏览器均已经支持 @layer 规则。所有浏览器厂商都支持的特性未来一定比较实用。


4.2 W3C 鼓励可以作为日常使用


SS 的标准化流程由 W3C Cascading Style Sheets Working Group (CSSWG)——W3C层叠样式列表小组以及独立CSS专家组成。W3C 本身并不制定标准,而是作为一个论坛式的平台,接收来自小组成员的提交,并通过会议来商讨制定标准,所有的提交以及讨论都是公开透明的,可以在 W3C 网站上看到会议的记录,可以简单分为4个大阶段:

  • 工作草案( WD )
  • 候选人推荐( CR )
  • 提议的建议( PR )
  • W3C 推荐( REC )


下图可以帮助理解:



图片来源:w3.org


W3C 通过状态码表示规范的成熟度。成熟度从低到高排序如下图。


图片来源:w3.org


再看下图:包含layer概念的标准讨论已经到达CR阶段。


图片来源:w3.org


W3C 鼓励从 CR阶段的标准 开始可以作为日常使用。


五、总结


最后,我们回到通过级联层如何解决“引入了一个第三方组件库导致样式覆盖“的问题上。


css代码如下:

/* 排序层 */
@layer reset, lib;
/* 通用样式 */
@layer reset {
  #app .item {
    color: black;
    width: 100px;
    padding: 1em;
  }
}
/* 第三方库样式 */
/*我们将第三方库的样式全部放到lib层,这里一般使用@import导入的方式,为了示例简单我们简化了操作*/
@layer lib {
  #app .item {
    color: green;
    border: 5px solid green;
    font-size: 1.3em;
    width: 130px;
  }
}
/* 开发者样式 */
.item {
  color: red;
}



我们将第三方库的样式全部放到lib层,将需要重置的一些样式放到reset层,自己开发的样式不放入层中(当然你也可以放入到一层然后排序在最后)。由此我们实现了样式的分层解决了第三方组件库导致样式覆盖的问题,而且做到开发者样式简单不冗长。


效果如下:


级联层(CSS@layer)已经历概念提出到到浏览器全面支持的阶段。也许在不久的将来大家都会普遍使用它,期望本文能给大家带来一定帮助。


参考资料:

  1. CSS Cascading and Inheritance Level 5
  2. A Complete Guide to CSS Cascade Layers
  3. The Future of CSS: Cascade Layers (CSS @layer)
  4. CSS必学基础:理解CSS中的级联规则
  5. 详解日后定会大规模使用的CSS @layer 规则
  6. W3C Process Document
  7. Cascade Layers Explainer

作者:Zhang Jiqi

来源:微信公众号:vivo互联网技术

出处:https://mp.weixin.qq.com/s/4M-RvnTq8rJuKDC3VZOONQ

过CSS文本装饰可以为文本添加装饰线、为装饰线设置颜色、为装饰线指定风格、为装饰线设置厚度等效果。

为文本添加装饰线通过 text-decoration-line 属性实现,可以结合一个以上的值,如上划线和下划线,来显示文本上方和下方的线条。具体的值有三个:

overline,在文本上方添加线条修饰。

line-through,在文本中间添加线条修饰,实现了删除线的效果。

underline,在文本下方添加线条修饰,实现了下划线的效果。

我们来做个例子。

打开编辑器,在 005 文件夹下创建 decoration.html 文件,构建好基本代码。

添加 h1,h2,h3,p 四个元素。分别填入一些文本。

在 005 文件夹下再创建一个 mystyle-3.css 文件,

定义 h1 选择器,声明样式属性 text-decoration-line,值为 overline。

定义 h2 选择器,也声明样式属性 text-decoration-line,值为 line-through。

定义 h3 选择器,再声明样式属性 text-decoration-line,值为 underline。

回到页面,通过 link 元素引入 mystyle-3.css 这个外部样式。

在浏览器上预览效果,我们看:上边线、删除线和下划线就做好了!

实际上,可以同时给文本添加多个线条,实现方法是给 text-decoration-line

[ˌdekəˈreɪʃn】属性设置多个值,每个值通过空格分开。

在 mystyle-3.css 再定义一个 p 选择器,声明样式属性 text-decoration-line,值写为 overline underline (读作overline 空格 underline )。

看一下效果,段落被添加了两条装饰线。

有的小伙伴还记得,给文本添加链接后,浏览器会默认给这个文本添加一个下划线。所以,添加了链接的文本就不要使用 underline 下划线装饰了。

为文本设置装饰线的颜色通过 text-decoration-color 属性实现,属性值为任意合法的颜色值。

给 h1 元素设置 text-decoration-color 属性,颜色值设置为 red。再快速的给 h2,h3,p 元素设置 text-decoration-color 属性,值分别为 blue,green,purple。

我们看,线条都有了颜色。

为装饰线指定风格通过 text-decoration-style 属性实现,属性值有五个:

solid,实线。

double,双实线。

dotted,圆点线。

dashed[dæʃt],虚线。

wavy[ˈweɪvi],波浪线。

为了演示方便,在 html 中再添加一个标题 h4,填入一些文本,在 css 中将全部元素的 text-decoration-line 样式属性都设置为 underline。再定义一个 h4 选择器,声明样式 text-decoration-line: underline。

给 h1, h2,h3,h4,p 全部添加 text-decoration-style 属性,值分别为 solid,double,dotted,dashed[dæʃt],wavy。

这样,各种线条的风格就设置好了!

通过 text-decoration-thickness 属性为线条设置厚度,也就是线条的粗细。属性值有三种设置方法:

auto, 默认值,这个值是不确定的,和所修饰的文字大小有关系。

px,像素大小,是一个绝对值。比如 5px。

%,是一个相对值,根据修饰文字的高度计算出来。比如 25%。

在 h1 元素上声明样式属性 text-decoration-thickness,值为 auto。在 h2,h3 上也声明这个样式属性,值分别为 5px,50%。

在浏览器里仔细观察,h1 上的下划线厚度是浏览器给的默认值。h2 上的下划线厚度是 5px。h3 上的下划线厚度为文字高度的一半。

回到样式表代码,我们分析一下:每个文本修饰的属性名,均为三个单词连接起来的,这样写起来比较啰嗦,能不能简化一下呢?可以的!

h1 {

/* text-decoration-line: overline; */

text-decoration-line: underline;

text-decoration-color: red;

text-decoration-style: solid;

text-decoration-thickness: auto;

}

素的显示与隐藏

使用CSS让元素不可见的方法很多,剪裁、定位到屏幕外、透明度变化等都是可以的。虽然它们都是肉眼看不见,但背后却在多个维度上都有差别

下面是总结的一些比较好的隐藏实践,大家一起来根据实际开发场景来选择合适的使用

比较好的隐藏实践

不占空间,资源可以加载,DOM可访问 使用display:none

不占空间,隐藏显示时有transition效果

占空间,不能点击 visibility: hidden

不占空间,不能点击,键盘能访问 clip裁切

占空间,不能点击,键盘能访问 relative

占空间,可以点击 opacity

隐藏文字 使用text-indent

根据实际的隐藏场景选择合适的隐藏方法,这里就不再多说了,接着往下看吧

display与元素的显隐

我们都知道display如果值为none,则该元素以及所有后代元素都隐藏,反之如果值是非none的情况,则都为显示了

display可以说是web显隐交互中出场频率最高的一种隐藏方式,是真正意义上的隐藏,干净利落,不留痕迹

none做到了无法点击、无法使用屏幕阅读器等辅助设备访问,不占空间,其实不仅仅是这样,更应该知道的是

me: 我有酒,那么别说你没有故事

我知道display:none你才不是一个没有故事的女同学

display: none的元素的background-image图片根据不同浏览器的情况加载情况不一

在Firefox浏览器下,display:none的background-image图片不加载,包括父元素display:none也是如此在Chrome和Safari浏览器,则根据父元素是否是否为none来影响图片加载情况,父元素带有display:none,图片不加载。

父元素不带有display:none,而自身有背景图元素带的话,那也照样加载

3.在IE浏览器下,无论怎么搞都会请求图片资源,就是这么任性

因此,在实际开发的时候,例如头图轮播切换效果

那些默认需要隐藏的图片作为背景图藏在display:none元素的子元素上,这样的细小改动就可以明显提升页面的加载体验,也是非常实用的小技巧

whatever

上面说的兴致盎然,但实际中不可能全部都是背景图去加载图片资源的

还有另外一个好朋友,img元素,然并卵的是,上面说了一大堆加载不加载的情况,对img来说没个鸟用,人家不管你none不none的,依旧带着勇闯天涯的气概去请求着资源

活久见

都说display:none做事最纯粹,最干净,不能被点击,触碰到,然而下面这种情况又是什么鬼?

出来解释解释,我们都是文明人是绝对不会动武的!

隐藏的按钮会触发click,触发表单提交,此现象出现在时髦的浏览器中(IE9+,现代标准浏览器中)

既然有这种例外情况那加了display:none的意义又是什么呢?

很多都是纯天然的

HTML中有很多标签和属性天然自带display:none

HTML5中新增了hidden这个布尔属性,可以让元素天生隐藏起来

既然说到了visibility了,那么就赶紧邀请visibility闪亮登场吧

visibility与元素的显隐

visibility要为自己正名,不仅仅是保留空间这么简单

看点多多:

继承性(最有意思的一个特点,不是我说的)

2. 与css计数器

visibility:hidden虽然让元素不可见了,但是不影响其计数效果,不会重新计算结果

3. 与transition

设置了visibility:hidden的元素,可以很好的展现transition过渡效果

这是因为transition支持的css属性中有visibility(果然是兄弟),而并没有display属性

4.与JS

visibility:hidden除了对transition友好外,对js来说也很友好

在实际开发中,需要对隐藏元素进行尺寸和位置的获取,来实现布局精确定位的交互

此时,就建议使用visibility:hidden

好了以上内容要告一段落了,我们继续开始新的征程吧,哈哈

用户界面样式

用户界面样式指的是CSS世界中用来帮助用户进行界面交互的一些CSS样式,主要有outline和cursor等属性

和border形似的outline属性

outline表示元素的轮廓,语法也和border一样,分为宽度、类型和颜色三个值

样式表示上相同,但是设计的初衷却是不太相同的,这一点天地日月可鉴

outline是一个和用户体验密切相关的属性,与focus状态以及键盘访问密切相关

对于按钮或链接,通常的键盘操作是:Tab键按次序不断focus控件元素(链接、按钮、输入框等表单元素),或者focus设置了tabindex的普通元素,然后按Shift+Tab是反向访问

重点来了!

默认状态下,对于处于focus状态的元素,浏览器会通过发光or虚框的形式进行区分和提示,这是友好的用户体验,很有必要,不然用户很难知道自己当前聚焦在了哪个元素上面,会迷失自我

元素如果聚焦到了a链接上,按下回车键就会跳转到相应链接,以上的交互都是基于键盘访问的,这就是为什么outline和键盘访问如此亲密了

不专业的行为

很多时候直接在reset样式的时候,写成如下形式是非常不可取的

这样直接一竿子打死一群鸭子的做法是不对的,更多的时候是因为浏览器内置的focus效果和设计风格格格不入,才需要重置,而且要使用专门的类名

最后再强调一遍:万万不可在全局设置outline: 0 none;

这样的操作会造成键盘访问的时候用户找不到当前焦点,容易产生困扰的,为了大家好,收敛一下吧

下面来点干货: 在实际开发中,有时候需要让普通元素代替表单控件元素有outline效果

举个栗子:submit按钮来完成UI设计是非常麻烦的,所以使用label元素来移花接木,通过for属性和这些原生的表单控件相关联

真正的不占据空间的outline及其应用

outline是一个真正意义上不占任何空间的属性,Amazing

头像剪裁的矩形镂空效果

先来看个效果图

上图就是矩形镂空效果,那么下面直接上代码,满满的干货

用一个大大的outline来实现周围半透明的黑色遮罩,因为outline无论设置多么多么大,都不会占据空间影响布局,至于超出的部分,直接给父元素设置一个overflow:hidden就搞定了 注意:

自动填满屏幕剩余空间的应用技巧

开发中很多时候,由于页面内容不够多,导致底部footer会出现尴尬的剩余空间,解决方法往往也有很多种,在此我们还是依然利用outline的功能来完美实现一下

关键的css就是设置一个超大轮廓范围的outline属性,如给个9999px,保证无论屏幕多高,轮廓颜色都能覆盖

值得注意的是,outline无法指定方位,它是直接向四周发散的,所以需要配合clip剪裁来进行处理,以左边和上边为边界进行裁剪

光标属性

光标属性cursor我们真的是最熟悉的陌生人啊

为什么这么说呢,因为在众多的属性值面前,我们似乎只用到了pointer(手形)(最常用的,没有之一),move(移动),default(系统默认)这几样

在cursor的世界里,远比我们想象的要丰富很多,下面按照功能特性来对其进行分类吧

琳琅满目的cursor属性值

友情不友情的小提示:☆(表示常用)

链接和状态

cursor: progress; 进行中

选择

拖拽都是CSS3新增的光标类型

以上内容就介绍完了用户界面样式的全部内容了,还有最后一章的冷知识,大家不要方,继续看下去,了解一下,了解一下,了解一下

流向的改变

说出来你可能不信,direction可以改变水平流向,尽管知道或者使用过的人少之又少,但并不妨碍它的发光发热

而且属性简单好记,值少,兼容极好ie6支持,可以来挖掘一下它的神奇功效

direction

仅仅两个值:

direction: rtl;

当然看到这里你可能会感觉,这些说起来都没什么鸟用,因为大招是不轻易放出的,而真正有用的地方在于改变网页布局的时候

direction属性默认有一个特性

可以改变替换元素(img,input,textarea,select)或inline-block/inline-table元素的水平呈现顺序

举个例子:颠倒顺序

再举个例子:

比如制作弹窗组件的时候,确认和取消按钮有的时候会根据用户的使用行为会显示在不同的位置

下面来看看这种特性的表现在实际开发中的作用

windows用户看到的样子

好了,direction的话题就告一段落,接下来介绍最后一个知识了,坚持住,快休息了

writing-mode

改变CSS世界纵横规则的writing-mode,如此强大的功能,居然没有被大家发掘和广发应用起来,实属遗憾了,话不多说,往下看

writing-mode作用及真正需要关注的属性值

writing-mode可以改变排版,变成垂直流,如下图所示

在使用语法上,也是需要记两套的,一套是IE私有属性,一套是CSS3规范属性

CSS3语法:

IE语法:

针对实战版来整理一份writing-mode是这样的

对于垂直排版来说,实际开发是很少会遇到的,不过还是要说说writing-mode带来的改变

水平方向也能margin合并

我们都知道两个相邻的元素垂直的margin会合并,当元素变为垂直流的时候,水平的margin也会合并

普通块元素可以使用margin: auto实现垂直居中

text-align:center实现图片垂直居中(同上实现的效果)

实现全兼容的icon fonts图标旋转效果

老IE下让小图标旋转很麻烦,writing-mode把文档变成垂直流的时候,英文、数字和字符号都天然的转了90°

@font-face的兼容性很好IE5.5就支持了,所以就算是IE6和IE7也没问题

好了,这就是《CSS世界》里最后三章的全部内容了,终于写完了,哈哈,希望大家有收获一些冷知识。

简单说两句

做个个人的小总结吧:

css有很多奇妙的地方,在某些特性当初被设计出来的时候可能只是为了某些图文排版而生

但是我们可以利用它们带来的特性发挥自己的创造力,实现其他很多意想不到的效果,因此,上面所讲述的所有知识点,尽管很多内容都有点奇技淫巧以悦妇孺的过程

但这也给我们开发的过程中,提供了一些很出奇的妙招,值得我们好好学习领悟

感谢个位的观看了,再见了,哈哈