一、CSS调试
有时写 CSS
会碰到这样的问题:结果看起来和你想的不太一样。你可能会认为 selector
(选择器)匹配到了元素但是什么都没发生,还可能会觉得盒子的大小与你想的有出入。那么这时候就需要调试工具,具体调试看看页面实际的问题。
审查CSS
从页面上选择一个元素,可以通过以下方法:右键该元素,选择审查元素 (Inspect);从浏览器开发者工具 DevTools
左侧 HTML tree
中选择该元素。
Element面板
调试 html 和 css,主要用到的就是浏览器开发者工具 element 面板。在这个面板里,你可以直接开关、编辑、新增属性的值。如图所示修改字体颜色:
理解盒模型
上篇文章重学CSS基础介绍了盒模型概念,现在我们打开开发者工具来瞅瞅,帮助你真正理解盒模型。
Layout view 给你展示了一张选定元素的盒模型示意图,还有对能改变元素展示方式的属性和值的描述。你可能原本没有精确地使用元素的属性,只设定了初始值, 盒模型也可能包含对于这些属性的描述。
上图体现了主流浏览器,默认采用标准盒模型布局,盒子实际的宽/高= width
/height
+ padding
+ border
。
如果要改变成IE盒模型,添加 box-sizing: border-box
即可,div在浏览器实际宽高就等于设置的width
/height
,如图所示:
二、CSS扩展
CSS预处理
另一种组织 CSS
的方法是利用一些对于前端开发者可用的工具,它们让你可以稍微更程式化地编写 CSS
。预处理工具以你的原文件为基础运行,将它们转化为样式表。代表工具有:
- less
- sass
- stylus
less为例
这里以 less 为例,看看能够 CSS 扩充哪些功能。 变量,编译后会填充到对应位置。
变量
less使用变量,无需多说,看代码一目了然:
mixin混合
混合(Mixin)是一种将一组属性从一个规则集包含(或混入)到另一个规则集的方法。
更多
更多 less 使用语法,可查阅官网文档:lesscss.org/
三、CSS革新(面向未来)
前端技术日新月异,我们需要持续学习来更新自己的前端知识并运用到自己的项目中。这次重点是整理一些未来普及或者现在小伙伴可能已经用到的 CSS
特性,包括 CSS
现代伪类、CSS
自定义属性、混合模式、CSS in JS
、滚动特性、SVG
图标。
1、现代伪类
:is() 减少重复
可以使用 :is()
伪类来删除选择器列表中的重复项,减少冗余重复代码。
/* BEFORE */
header p:hover,
main p:hover,
footer p:hover {
color: red;
cursor: pointer;
}
/* AFTER */
:is(header, main, footer) p:hover {
color: red;
cursor: pointer;
}
复制代码
注意,许多浏览器通过一个更旧的、带前缀的伪类 :any()
来支持这个功能,包括旧版本的 Chrome
、Firefox
和 Safari
。
/* 向后兼容的版本:-*-any() */
:-webkit-any(header, main, footer) p:hover {
color: red;
cursor: pointer;
}
:-moz-any(header, main, footer) p:hover {
color: red;
cursor: pointer;
}
:matches(header, main, footer) p:hover {
color: red;
cursor: pointer;
}
复制代码
:where() 保持低特殊性
使用 :where() 来保持低特殊性。伪类:where()
几乎与:is()
相同,除了一个关键的区别:它将_永远_具有零特异性。这对那些正在建立框架、主题和设计系统的人来说有不可思议的影响。使用:where()
,作者可以设置默认值,下游的开发者可以包括覆盖或扩展,而不会出现特定性冲突。
:where()
伪类及其任何参数都不对选择器的特殊性有所帮助,它的特殊性始终为零
下面这组img
样式。使用:where()
,即使有一个更高的特异性选择器,特异性仍然是零。在下面的例子中,你认为图片的边框会是哪种颜色?
测试代码见:testing :where()
:not() 反选
基本的:not()
选择器从Internet Explorer 9开始被支持。但是选择器增强了:not()
,允许它接受一个选择器列表,就像:is()
和:where()
。
测试代码见:testing :not()
:empty 选中空元素
:empty
,当一个元素_没有_子元素时,它可以匹配该元素,包括文本节点。
规则p:empty
将匹配<p></p>
,但不匹配<p>Hello</p>
。
你可以使用:empty
的一个方法是隐藏那些可能是用JavaScript填充的动态内容的占位符的元素。也许你有一个将接收搜索结果的div,当它被填充时,它将有一个边框和一些填充。但由于还没有结果,你不希望它在页面上占用空间。使用:empty
,你可以用隐藏它。
.search-results:empty {
display: none;
}
复制代码
:focus-visible 设置聚焦样式
使用 :focus-visible
伪类,是只在用户代理通过启发式方法确定焦点环应该是可见的时候才显示。换句话说:浏览器会根据输入法、元素的类型和交互的上下文来决定何时应用:focus-visible
。比如我们需要给文本输入框设置聚焦样式,就可以使用,如下图:
测试代码见:testing :focus-visible
更多伪类
其他更多新伪类,有兴趣的小伙伴可以查阅 MDN 了解学习。
2、CSS自定义属性
自定义属性(有时候也被称作CSS变量或者级联变量)是由CSS作者定义的,它包含的值可以在整个文档中重复使用。复杂的网站都会有大量的CSS代码,通常也会有许多重复的值。举个例子,同样一个颜色值可能在成千上百个地方被使用到,如果这个值发生了变化,需要全局搜索并且一个一个替换(很麻烦哎~)。这时自定义属性就发挥极大的作用啦。
自定义属性用法:标记设定值(比如: --theme-color: black;
),由var() 函数来获取值(比如: color: var(--theme-color) ;
)
body {
--theme-color: orange;
}
button {
background-color: var(--theme-color);
}
.title {
color: var(--theme-color);
}
.box {
border: 2px solid var(--theme-color);
}
复制代码
备用值
如果开发者并没有定义过 –theme-color 这个变量呢?var() 可以接收第二个参数作为备用值,当前面第一个参数(自定义属性)未生效会用到:
button {
background-color: var(--theme-color, gray);
}
复制代码
注意:如果你想把另一个自定义属性作为缺省值,语法应该是 background-color: var(
--theme-color
, var(--fallback-color
))。
3、CSS in JS
前面我们已经学会使用 CSS 自定义属性,开发中其实还可以通过 JavaScript 来操作自定义属性,把交互效果做的更炫酷灵动些。
下面我们来实现下悬浮跟踪按钮 效果,感受下 css in js:
<!-- html -->
<div class="track-btn">
<span>妙用CSS变量,让你的CSS变得更心动</span>
</div>
复制代码
/* css */
.track-btn {
overflow: hidden;
position: relative;
border-radius: 25px;
width: 400px;
height: 50px;
background-color: #66f;
cursor: pointer;
line-height: 50px;
text-align: center;
font-weight: bold;
font-size: 18px;
color: #fff;
}
.track-btn span {
position: relative;
pointer-events: none;
}
.track-btn::before {
--size: 0;
position: absolute;
left: var(--x);
top: var(--y);
width: var(--size);
height: var(--size);
background-image: radial-gradient(circle closest-side, #09f, transparent);
content: "";
transform: translate3d(-50%, -50%, 0);
transition: width 200ms ease, height 200ms ease;
}
.track-btn:hover::before {
--size: 400px;
}
复制代码
// js
// 监听鼠标移动事件,动态改变css自定义属性
const btn = document.getElementsByClassName("track-btn")[0];
const btnStyle = btn.style;
btn.addEventListener("mousemove", e => {
btnStyle.setProperty("--x", `${e.offsetX}px`);
btnStyle.setProperty("--y", `${e.offsetY}px`);
});
复制代码
随着这些年 CSS 的发展,我们编写样式已经不一定需要写 css 文件了。 以 styled-components 为代表的 css in js 方案,用 JavaScript 的力量就能武装 css。
4、CSS混合模式
CSS3 新增了一个很有意思的属性 — mix-blend-mode
,直译过来就是混合模式。
我们只使用 css 就可以实现滤镜换肤效果,主要就是借助 mix-blend-mode
属性,具体实现代码如下:
<!-- html -->
<input type="color" value="#0000ff">
<img src="https://images.unsplash.com/photo-1508974491678-7ec251d629fd?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1427&q=80">
复制代码
img {
height: 100%;
width: 100%;
object-fit: cover;
}
input {
position: absolute;
padding: 0;
border: none;
width: 100%;
height: 100%;
/* mix blend mode makes the color of the swatch alter the image behind it. */
mix-blend-mode: hue; /* try screen, multiply or other blend modes for different effects */
cursor: pointer;
}
复制代码
5、滚动行为
网页内容超过可视区,浏览器就会出现滚动条。有关于容器滚动方面的CSS新特性有很多个,比如:
- 自定义滚动条的外观
scroll-behavior
指定容容器滚动行为,让滚动效果更丝滑overscroll-behavior
优化滚动边界,特别是可以帮助我们滚动的穿透
自定义滚动条的外观
浏览器默认滚动条样式,分为window和mac版:
window:
mac:
在CSS中,我们可以使用伪元素来自定义滚动条的外观,主要涉及了如下七个伪元素:
::-webkit-scrollbar
— 整个滚动条::-webkit-scrollbar-button
— 滚动条上的按钮 (上下箭头)::-webkit-scrollbar-thumb
— 滚动条上的滚动滑块::-webkit-scrollbar-track
— 滚动条轨道::-webkit-scrollbar-track-piece
— 滚动条没有滑块的轨道部分::-webkit-scrollbar-corner
— 当同时有垂直滚动条和水平滚动条时交汇的部分::-webkit-resizer
— 某些元素的corner部分的部分样式(例:textarea的可拖动按钮)
html {
min-height: 2284px;
overflow-x: hidden;
}
html::-webkit-scrollbar {
width: 12px;
height: 8px;
}
/* 滚动条的滑块 */
html::-webkit-scrollbar-thumb {
background-color: #0ae;
background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(.5, rgba(255, 255, 255, .2)), color-stop(.5, transparent), to(transparent));
}
/* 滚动条的轨道 */
html::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgb(0 0 0 / 30%);
border-radius: 10px;
background-color: #F5F5F5;
}
复制代码
指定容容器滚动行为
当用户手动导航触发滚动操作时,scroll-behavior
为一个滚动框指定滚动行为,让滚动效果更丝滑。
scroll-behavior: auto(立即滚动) | smooth(平稳滚动);
复制代码
优化滚动边界
当多个滚动视窗嵌套时,外面的对话框中含有可滚动内容时,一旦滚动至对话框的边界,对话框下方的页面内容也开始滚动了——这被称为“滚动链”。在某些情况下我们不想要这些表现,我们就可以使用 overscroll-behavior
来去除不需要的滚动链。
来看一个案例,我们展现一个虚构的联系人全页列表,和一个包含聊天窗口的对话框。
/* 聊天小框设置滚动边界行为不变 */
.messages {
height: 220px;
overflow: auto;
overscroll-behavior-y: contain;
}
/* 外面联系人列表,默认滚动到边界的表现被阻止,不受滚动链影响 */
body {
margin: 0;
overscroll-behavior: none;
}
复制代码
6、SVG图标
可缩放矢量图形(Scalable Vector Graphics,SVG),是一种用于描述二维的矢量图形,基于 XML 的标记语言。
和传统的点阵图像模式,像JPEG和PNG不同,SVG格式提供的是矢量图,这意味着它的图像能够被无限放大而不失真或降低质量,并且可以方便地修改内容。
使用 SVG
的图标还有一优势,我们可以在 CSS
中直接通过代码来控制图标的颜色:
<!-- HTML -->
<svg t="1631461658126" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2487" width="200" height="200">
<path d="M800.164 415.232c0-160.322-130.576-290.146-291.182-288.924-158.234 1.204-286.914 131.116-286.684 289.356 0.126 85.816 37.668 162.852 97.184 215.686 40.054 35.558 65.026 85.046 68.224 138.51l3.994 66.758h239.062l3.988-66.678c3.15-52.664 26.706-102.316 66.446-137.02 60.648-52.962 98.968-130.846 98.968-217.688z" fill="#FFC751" p-id="2488"></path><path d="M800.17 415.224c0 86.858-38.322 164.738-98.968 217.696-39.742 34.71-63.3 84.35-66.452 137.014l-3.982 66.692H391.692l-3.982-66.764c-3.134-52.11-26.912-100.442-65.216-135.778a295.974 295.974 0 0 0 75.134 9.64c163.244 0 295.594-132.35 295.594-295.594 0-79.042-31.024-150.838-81.548-203.89 110.064 40.808 188.496 146.744 188.496 270.984z" fill="#FFAF40" p-id="2489"></path>
<path d="M681.978 652.33c-28.092 32.664-44.626 74.102-47.226 117.604l-3.982 66.692H391.692l-3.982-66.764a196.862 196.862 0 0 0-14.396-62.894c32.718 10.95 67.724 16.866 104.11 16.866 77.346-0.002 148.444-26.75 204.554-71.504z" fill="#FF993A" p-id="2490"></path>
<path d="M511.232 944.774m-79.226 0a79.226 79.226 0 1 0 158.452 0 79.226 79.226 0 1 0-158.452 0Z" fill="#B5B1A4" p-id="2491"></path>
<path d="M590.454 944.77c0 43.758-35.466 79.222-79.222 79.222-24.784 0-46.886-11.366-61.416-29.19a79.114 79.114 0 0 0 39.296 10.402c43.758 0 79.222-35.466 79.222-79.222a78.944 78.944 0 0 0-17.732-49.976c23.822 13.66 39.852 39.332 39.852 68.764z" fill="#8F8B81" p-id="2492"></path>
<path d="M579.452 971.714h-136.442c-39.944 0-72.324-32.38-72.324-72.324v-109.528a18.08 18.08 0 0 1 18.08-18.08h244.928a18.08 18.08 0 0 1 18.08 18.08v109.528c0.002 39.944-32.378 72.324-72.322 72.324z" fill="#8F8B81" p-id="2493"></path>
<path d="M370.686 841.678h281.09v54.78H370.686z" fill="#706C64" p-id="2494"></path>
<path d="M651.784 789.858v109.53c0 39.944-32.388 72.332-72.332 72.332h-136.442a72.9 72.9 0 0 1-6.36-0.276c0.866 0.036 1.732 0.036 2.6 0.036 88.792 0 160.774-71.982 160.774-160.774 0-13.42-1.64-26.47-4.756-38.932h38.434c9.972 0.002 18.082 8.094 18.082 18.084z" fill="#706C64" p-id="2495"></path>
<path d="M645.668 868.03H376.794a18.08 18.08 0 0 1-18.08-18.08v-22.478a18.08 18.08 0 0 1 18.08-18.08h268.874a18.08 18.08 0 0 1 18.08 18.08v22.478a18.08 18.08 0 0 1-18.08 18.08z" fill="#B5B1A4" p-id="2496"></path>
<path d="M559.662 809.39h-141.106c-16.192 0-29.32 13.128-29.32 29.32s13.128 29.32 29.32 29.32h141.106c16.192 0 29.32-13.128 29.32-29.32s-13.126-29.32-29.32-29.32z" fill="#D8D4C9" p-id="2497"></path>
<path d="M489.964 809.39h-32.214c-16.192 0-29.32 13.128-29.32 29.32s13.128 29.32 29.32 29.32h32.214c16.192 0 29.32-13.128 29.32-29.32s-13.128-29.32-29.32-29.32z" fill="#E8E4D8" p-id="2498"></path>
<path d="M330.148 568.842c16.37-14.21 20.47-37.976 9.804-56.848a196.752 196.752 0 0 1-25.496-96.458c-0.128-93.48 65.648-172.33 153.37-192.224 20.98-4.758 35.868-23.406 35.868-44.918 0-29.422-27.246-51.508-55.944-45.018-128.896 29.154-225.652 145.054-225.46 282.29 0.078 51.682 13.74 100.18 37.596 142.126 14.204 24.974 47.866 30.488 69.564 11.654z" fill="#FFE059" p-id="2499"></path>
<path d="M381.774 157.122c-76.14 38.454-133.168 109.634-152.406 194.69-6.448 28.51 15.254 55.638 44.484 55.638h0.99c21.43 0 39.764-14.97 44.536-35.862 13.204-57.806 52.012-106.12 103.798-132.212 19.836-9.994 29.512-32.836 23.012-54.076l-0.27-0.882c-8.252-27.024-38.922-40.034-64.144-27.296z" fill="#FFF370" p-id="2500"></path>
<path d="M346.71 307.668a198.7 198.7 0 0 1 29.194-34.956c15.342-14.586 18.588-37.808 7.394-55.776l-0.486-0.782c-15.606-25.05-50.324-29.356-71.59-8.892a292.152 292.152 0 0 0-40.862 48.978c-14.148 21.322-7.896 50.308 13.536 64.29l0.786 0.512c20.742 13.538 48.438 7.332 62.028-13.374z" fill="#FFF7C7" p-id="2501"></path>
<path d="M898.472 347.924h-34.656c-17.42 0-31.544 14.122-31.544 31.544 0 17.42 14.122 31.544 31.544 31.544h34.656c17.42 0 31.544-14.122 31.544-31.544s-14.124-31.544-31.544-31.544zM125.528 411.732h34.656c17.42 0 31.544-14.122 31.544-31.544 0-17.42-14.122-31.544-31.544-31.544H125.528c-17.42 0-31.544 14.122-31.544 31.544 0 17.42 14.124 31.544 31.544 31.544zM823.982 174.872L793.968 192.2c-15.086 8.71-20.256 28.002-11.546 43.088 8.71 15.086 28.002 20.256 43.088 11.546l30.014-17.328c15.086-8.71 20.256-28.002 11.546-43.088-8.71-15.086-28.002-20.256-43.088-11.546zM680.788 61.4l-17.328 30.014c-8.71 15.086-3.542 34.378 11.546 43.088 15.086 8.71 34.378 3.542 43.088-11.546l17.328-30.014c8.71-15.086 3.542-34.378-11.546-43.088-15.086-8.71-34.378-3.542-43.088 11.546zM480.096 31.544V66.2c0 17.42 14.122 31.544 31.544 31.544 17.42 0 31.544-14.122 31.544-31.544V31.544C543.182 14.122 529.06 0 511.64 0c-17.422 0-31.544 14.122-31.544 31.544zM287.952 93.304l17.328 30.014c8.71 15.086 28.002 20.256 43.088 11.546 15.086-8.71 20.256-28.002 11.546-43.088l-17.328-30.014c-8.71-15.086-28.002-20.256-43.088-11.546-15.088 8.71-20.256 28-11.546 43.088z" fill="#79FF79" p-id="2502"></path>
<path d="M168.114 230.132l30.014 17.328c15.086 8.71 34.378 3.542 43.088-11.546 8.71-15.086 3.542-34.378-11.546-43.088l-30.014-17.328c-15.086-8.71-34.378-3.542-43.088 11.546-8.71 15.086-3.54 34.378 11.546 43.088z" fill="#79FF79" p-id="2503"></path>
</svg>
复制代码
svg {
stroke: #c2c2c2;
width: 64px;
}
复制代码
四、总结
上述主要是介绍了 CSS 革新的优秀特性,还要很多新东西等待大家学习探索。我们应该及时去了解学习并运用,才可以做到对项目精益求精。