2023-06-26
CSS
00
请注意,本文编写于 397 天前,最后修改于 144 天前,其中某些信息可能已经过时。

目录

常见面试题
CSS函数
CSS变量
语法规范
用途
主题色 替代预处理器方案 示例
响应式布局
与JS通信
CSS Houdini
API
CSS Parsing API
CSS 自定义属性与值
CSS Typed OM
Worklets
案例 主体切换
案例 透明背景
CSS新特性
has伪元素选择器
CSS 兼容性
如何检测css样式性?
常见兼容性问题
CSS 奇淫技巧
常见问题
其他

前两篇文章《CSS基础入门》《CSS合模型与布局》介绍了CSS基础和理论。但是CSS知识点总的来说比较杂乱,这边记录CSS比较零碎相对高级一些的知识点以及一些常见问题。

常见面试题

  • 你了解哪些css函数?
  • css变量有用过吗?它有什么特点
  • 如何检测CSS的兼容性?
  • 有了解JS in CSS吗?

CSS函数

  • clamp(MIN, VAL, MAX) 选择最佳值
  • attr 返回当前元素的属性值
    • a:after {content: " (" attr(title) ")";}
  • rgb() rgba() hsl() hsla()
  • calc 允许计算CSS属性值 ios10不支持f
    • 推荐写法 height: 90%; height: calc(100%-50px)
  • counter() 计数器
    • 示例 搭配 counter-reset counter-increment使用
  • max() min()
  • var() 用于插入自定义属性值
    • 示例 p{--color:red;} .text{ background-color: var(--color)}
  • 渐变
    • linear-gradient() repeating-linear-gradient()
    • radial-gradient() repeating-radial-gradient()
    • conic-gradient() repeating-conic-gradient()
  • grid布局中函数 repeat() minmax()

CSS变量

目前技术的展随着web浏览器的升级,CSS变量的应用越来越普遍了,不考虑IE11的话,可以大胆的用了

css
:root{ --color1: blue; } .box { background-color: var(--color1); }

语法规范

  • 首先变量的声明必须在css代码块中,变量的使用必须在dom后代元素中使用
  • 使用:root包裹css变量后, 就可以在任何元素对应的样式中使用css变量了
  • 使用var()函数读取变量
    • 支持设置默认值 var(--foo, #7F583F);
    • 支持多个默认参数, 如字体 var(--font-stack, "Roboto", "Helvetica");
    • 第二个参数没有逗号或空格会视为一个整体,var(--padding, 10px 15px 20px);
    • CSS变量不能用作属性名
  • 如果变量是字符串可以拼接
  • 如果变量是数值,必须使用calc()函数将他们连接
css
/* 如果变量是字符串可以拼接*/ :root { --bar: 'hello'; --foo: var(--bar)' world'; } .box:after { content: '--foo : 'var(--foo); } /* 如果变量是数值,必须使用`calc()`函数将他们连接 */ .foo { --gap: 20; margin-left: calc(var(--gap) * 1px); }
  • css变量作用域
html
<style> :root { --color: blue; } div { --color: green; } #alert { --color: red; } * { color: var(--color); } </style> <p>blue</p> <div>green</div> <div id="alert">red</div>

用途

主题色 替代预处理器方案 示例

html
/* 主题色切换示例代码 */ <style> :root { --color: white; --bg: black; } p{ color: var(--color); background-color: var(--bg); } </style> <span onclick="setTheme(1)"> <input name="theme" type="radio" id="checkbox1" value="1"> <label for="checkbox1">白天</label> </span> <span onclick="setTheme(2)"> <input name="theme" type="radio" id="checkbox2" value="2"> <label for="checkbox2">黑夜</label> </span> <p>白天color is white, bg is black</p> <p>黑夜color is black, bg is white</p> <script> function setTheme(type) { const style = document.documentElement.style if(type === 1) { style.setProperty('--color', 'white'); style.setProperty('--bg', 'black'); } else { style.setProperty('--color', 'black'); style.setProperty('--bg', 'white'); } } </script>

响应式布局

css
body { --primary: #7F583F; --secondary: #F7EFD2; } a { color: var(--primary); text-decoration-color: var(--secondary); } @media screen and (min-width: 768px) { body { --primary: #F7EFD2; --secondary: #7F583F; } }

与JS通信

  • 获取刘海高度
  • 存储JS数据
js
// 获取刘海高度示例 // css .root { --safetop: env(safe-area-inset-top); } const top = getComputedStyle(document.documentElement).getPropertyValue('--safetop'); // 存储js数据 document.documentElement.style.setProperty('--obj', JSON.stringify({a:1}))

CSS Houdini

CSS Houdini就是传说中的JS IN CSS

  • CSS Houdini是一组底层API,它们公开了CSS引擎的各个部分.
  • 开发者可以通过这组API来编写浏览器可解析的CSS代码,不需要等待浏览器的实现就能实现自己想要的CSS功能。

image.png

工作流程

image.png

传统开发流程中开发者只能介入DOM和 CSSOM这两个环节,有了Houdini可以作用域整个渲染流程,如下图 image.png 注意: 灰色内容是还在实现中的标准,目前暂时无法使用。

本段落主要参考资料

API

CSS Parsing API

CSS Parsing API 还没有被写入规范,下面所说内容随时都会有变化,但是它的基本思想不会变。

允许开发者自由扩展CSS词法分析器,引入新的结构,比如新的媒体规则、新的伪类、嵌套、@extends、@apply等等。

CSS 自定义属性与值

CSS Properties and Values API的出现进一步推动了自定义属性,它还允许自定义的属性添加类型,大大增强了自定义属性的能力

js
window.CSS.registerProperty({ name: "--bg-color", syntax: "<color>", inherits: false, initialValue: "#ffffff", });

CSS Typed OM

你可以把 CSS Typed OM 视为 CSSOM 2.0,它的目的在于解决目前模型的一些问题,并实现 CSS Parsing API 和 CSS 属性与值 API 相关的特性。

提升性能是 Typed OM 的另一重任。将现在 CSSOM 的字符串值转成有意义的 JS 表达式可以有效的提升性能。

Worklets

  • Worklets 的概念和 web worker 类似,它们允许你引入脚本文件并执行特定的 JS 代码,这样的 JS 代码要满足两个条件:第一,可以在渲染流程中调用;第二,和主线程独立。
  • Worklet 脚本严格控制了开发者所能执行的操作类型,这就保证了性能。

更多关于Worklets的草案

js
// index.html CSS.paintWorklet.addModule('paint-grid.js'); // paint-grid.js registerPaint('transparent-grid', class { // ... }}

案例 主体切换

案例实现主体切换,附加动画效果 image

css
<script> window.CSS.registerProperty({ name: "--bg-color", syntax: "<color>", inherits: false, initialValue: "#ffffff", }); window.CSS.registerProperty({ name: "--my-color", syntax: "<color>", inherits: false, initialValue: "#000000", }); setTimeout(() => { document.body.setAttribute('class', "night-theme"); }, 2000); </script> <style> body { --bg-color: #fff; --my-color: #000; background-color: var(--bg-color); color: var(--my-color); transition: --bg-color 2s linear, --my-color 2s linear; } body.night-theme { --bg-color: #000; --my-color: #fff; } </style> <div> 2s后发生将变成黑夜模式 </div>

案例 透明背景

image.png

核心代码

  • 使用
html
<script> if (window.CSS) { window.CSS.registerProperty({ name: "--unit", syntax: "<number>", inherits: false, initialValue: 10, }); CSS.paintWorklet.addModule('paint-grid.js'); } </script> <style> .box { --unit: 8; background: paint(transparent-grid); } </style> <div class="box"></div>
  • worklets 实现
js
registerPaint('transparent-grid', class { static get inputProperties() { return ['--unit']; } paint(context, size, properties) { // 两个格子颜色 const color1 = '#fff'; const color2 = '#eee'; // 格子尺寸 const units = properties.get('--unit')?.value || 20; // 横轴竖轴循环遍历下 for (let x = 0; x < size.width; x += units) { for (let y = 0; y < size.height; y += units) { context.fillStyle = (x + y) % (units * 2) === 0 ? color1 : color2; context.fillRect(x, y, units, units); } } } });

案例

CSS新特性

has伪元素选择器

image.png

image.png

案例

CSS 兼容性

如何检测css样式性?

  • CSS@support检测
css
@supports (padding: revert) { /* todo something */ } /* css变量兼容性检测 */ @supports ( (--a: 0)) { /* supported */ } @supports ( not (--a: 0)) { /* not supported */ }
  • JS 检测
js
const isSupported = window.CSS?.supports?.('--a', 0); if (isSupported) { /* supported */ } else { /* not supported */ }
  • 还有一种比较笨的方式 先赋值样式,渲染后再查询布局,
    • 该方式适用于区分样式属性有差异的浏览器。
js
document.head.style.filter = 'blur(5px)'; result = window.getComputedStyle(document.head).filter == 'blur(5px)';

常见兼容性问题

  • IOS开启惯性回弹
    • iOS页面非body元素的滚动操作会非常卡(Android不会出现此情况),通过overflow-scrolling:touch调用Safari原生滚动来支持弹性滚动,增加页面滚动的流畅度
  • 移动端双向滚动问题
    • 不要在同一个容器同时设置横向和纵向滚动
  • autofocus 自动聚焦
    • 移动端不支持首次自动聚焦,但如果你手动点击过输入框, 就可以通过JS自动聚焦了(给目标元素设置autofocus属性)
    • 视频自动播放也如此,必须用户手动点击播放一次,才能唤起自动播放
  • 清除ios15 输入自带的icon
css
input[type="search"] { -webkit-appearance: none; }
  • 关于ios端h5页面双击会页面发生滚动的解决办法
js
// https://blog.csdn.net/weixin_44777146/article/details/108219654 var agent = navigator.userAgent.toLowerCase(); var iLastTouch = null; if (agent.indexOf('iphone') >= 0 || agent.indexOf('ipad') >= 0) { document.body.addEventListener('touchend', function (event) { let a = new Date().getTime(); iLastTouch = iLastTouch || a + 1; let c = a - iLastTouch; if (c < 500 && c > 0) { event.preventDefault(); return false; } iLastTouch = a; }, false); };

CSS 奇淫技巧

- `-webkit-overflow-scrolling: touch;`
  • CSS动画启用GPU加速
    • transform: translate3d(0, 0, 0);translateZ(0)
    • 场景:动画元素(绝对定位、同级中超过6个以上使用动画)
  • pointer-events禁用事件触发
    • 通过pointer-events:none禁用事件触发(默认事件、冒泡事件、鼠标事件、键盘事件等),相当于<button>的disabled
    • 场景:后台系统水印
  • css控制元素的现实和隐藏 上一章节的checkbox特效
  • 基于伪元素的图片内容生成技术 image
css
img::after{ /* 生成 alt 信息 */ content: attr(alt); /* 尺寸和定位 */ postion:absolute; bottom: 0; width:100%; background-color:rgba(0,0,0,.5); transform: translateY(100%); transition: transform .2s; } img:hover::after{ transform: translateY(0); }

常见问题

  • link与@import的区别

  • CSS隐藏元素的几种方式及区别

    • display:none
      • 元素在页面上将彻底消失,元素本来占有的空间就会被其他元素占有,也就是说它会导致浏览器的重排和重绘。
      • 不会触发其点击事件
    • visibility:hidden
      • 和display
        的区别在于,元素在页面消失后,其占据的空间依旧会保留着,所以它只会导致浏览器重绘而不会重排。
      • 无法触发其点击事件
    • opacity:0
      • 和visibility
        的一个共同点是元素隐藏后依旧占据着空间
      • 可以触发点击事件
  • CSS颜色体系有哪些值?

    • 色彩关键字
    • transparent --透明
    • currentColor -- 原始color值
    • rgb()与rgba()
    • hsl()与hsla()
  • content属性的特点

    • content生成的文本是无法选中、无法复制的,好像设置了user-select
      声明一般
    • content生成的文本无法被屏幕阅读设备读取,也无法被搜索引擎抓取
    • content属性只能用来生成一些无关紧要的内容
  • 打点loading效果

css
dot { display: inline-block; height: 1em; line-height: 1; text-align: left; vertical-align: -.25em; overflow: hidden; } dot::before { display: block; content: '...\A..\A.'; white-space: pre-wrap; animation: dot 3s infinite step-start both; } @keyframes dot { 33% { transform: translateY(-2em); } 66% { transform: translateY(-1em); } } /* HTML*/ /* 正在加载中<dot>...</dot> */
  • border-color和color
    • border-color 默认颜色就是color色值,就是当没有指定border-color颜色值的时候,会使用当前元素的color计算值作为边框色
  • border-width支持的关键字
    • thin:薄薄的,等同于1px
    • medium:(默认值)薄厚均匀,等同于3px
    • thick:厚厚的,等同于4px

其他

这里介绍一些优先级不是很高的CSS知识点 (https://juejin.cn/post/6941206439624966152)


本文作者:郭敬文

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!