积累的问题
2009 年一直工作到现在开发和日常学习中能想起来的并且已经解决的 CSS
中积累的问题, 已经被淘汰不值得一提的例如 IE hack 就不会再提起了
CSS3 中 box-shadow 存在的问题
CSS3
中box-shadow
的溢出问题 子容器加了box-shadow
在父容器中可能存在溢出,可以通过给父元素添加overflow:hidden
解决。box-shadow
阴影被覆盖问题- 使用相对定位解决
position:relative
和z-index
提高层数可以把阴影显示出来
- 使用相对定位解决
- 开启
gpu
加速, 设置3d
效果{ transform: translate3d(0, 0, 0); }
- 开启
CSS
中实现 0.5px
边框 解决 Android 兼容性
问题
标准1px边框
.border {
border: 1px solid #ff0000;
}
可以利用缩放-发虚
.border {
height: 1px;
background-color: red;
transform: scaleY(0.5);
}
四条边框都需要的样式
.border {
padding: 10px;
border: 1px solid red;
transform-origin: 0 0;
transform: scale(0.5, 0.5);
}
给伪元素添加设置边框
.border {
position: relative;
}
.border::before {
content: "";
position: absolute;
padding: 20px;
border: 1px solid blue;
transform-origin: 0 0;
transform: scale(0.5, 0.5);
}
利用 @media 匹配 dpr 设置边框
@media screen and (-webkit-min-device-pixel-ratio: 2) {
.border {
border-top: 0.5px solid red;
}
}
/*ios dpr=2和dpr=3情况下border相差无几,下面代码可以省略*/
@media screen and (-webkit-min-device-pixel-ratio: 3) {
.border {
border-top: 0.333333px solid red;
}
}
postcss-write-svg
@svg 1px-border {
height: 2px;
@rect {
fill: var(--color, black);
width: 100%;
height: 50%;
}
}
.border {
border: 1px solid transparent;
border-image: svg(1px-border param(--color #00b1ff)) 2 2 stretch;
}
编译之后
.border {
border: 1px solid transparent;
border-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' height='2px'%3E%3Crect fill='%2300b1ff' width='100%25' height='50%25'/%3E%3C/svg%3E")
2 2 stretch;
}
初始化 CSS 样式
最简单的初始化方法(强烈不建议)
* {
padding: 0;
margin: 0;
}
淘宝前端团队的样式初始化代码
body,
h1,
h2,
h3,
h4,
h5,
h6,
hr,
p,
blockquote,
dl,
dt,
dd,
ul,
ol,
li,
pre,
form,
fieldset,
legend,
button,
input,
textarea,
th,
td {
margin: 0;
padding: 0;
}
body,
button,
input,
select,
textarea {
font: 12px/1.5tahoma, arial, \5b8b\4f53;
}
h1,
h2,
h3,
h4,
h5,
h6 {
font-size: 100%;
}
address,
cite,
dfn,
em,
var {
font-style: normal;
}
code,
kbd,
pre,
samp {
font-family: couriernew, courier, monospace;
}
small {
font-size: 12px;
}
ul,
ol {
list-style: none;
}
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
sup {
vertical-align: text-top;
}
sub {
vertical-align: text-bottom;
}
legend {
color: #000;
}
fieldset,
img {
border: 0;
}
button,
input,
select,
textarea {
font-size: 100%;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
style 初始化的利弊
因为浏览器的兼容问题,不同浏览器对有些标签的默认值是不同的,如果没对 CSS 初始化有可能会造成页面的差异。
初始化样式会对 SEO 有一定的影响,但鱼和熊掌不可兼得,但力求影响最小的情况下初始化。
CSS 里的 visibility 属性有个 collapse 属性值
- 对于一般的元素,它的表现跟 visibility:hidden;是一样的。元素是不可见的,但此时仍占用页面空间。
- 如果这个元素是 table 相关的元素,例如 table 行,table group,table 列,table column group,它的表现却跟 display:none 一样,也就是说,它们占用的空间也会释放。
- 在不同浏览器下的区别
- 在谷歌浏览器里,使用 collapse 值和使用 hidden 值没有什么区别。
- 在火狐浏览器、Opera 和 IE11 里,使用 collapse 值的效果就如它的字面意思:table 的行会消失,它的下面一行会补充它的位置。
width:auto 和 width:100%的区别
width:auto
会使元素撑满整个父元素,margin
、border
、padding
、content
区域会自动分配水平空间。width:100%
会使元素box
的宽度等于父元素的content box
的宽度。
进一步解释
自动分配
设置了盒子的宽度,当内容过多时会超出父容器。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.p1 {
width: auto;
margin: 20px;
padding: 20px;
}
.p2 {
width: 100%;
margin: 20px;
padding: 20px;
}
</style>
</head>
<body>
<p class="p1">1</p>
<p class="p2">2</p>
</body>
</html>
使用图片 base64 编码的优点和缺点
base64
编码是一种图片处理格式,通过特定的算法将图片编码成一长串字符串,在页面上显示的时候,可以用该字符串来代替图片的 url
属性。
优点:
- 减少一个图片的
HTTP
请求
- 减少一个图片的
缺点:
- 编码后的大小会比原文件的体积大 1/3,如果把大图片编码到
HTML/CSS
中,不仅会造成文件体积的增加,影响文件的加载速度,还会增加浏览器对HTML
或CSS
文件解析渲染的时间。 - 使用
base64
无法直接缓存,要缓存只能缓存包含base64
的文件,比如HTML
或者CSS
,这相比域直接缓存图片的效果要差很多。 - 兼容性的问题,
ie8
以前的浏览器不支持(ZF 外包的小伙伴懂)。
- 编码后的大小会比原文件的体积大 1/3,如果把大图片编码到
详细资料可以参考
《玩转图片 base64 编码》
《前端开发中,使用 base64 图片的弊端是什么?》
《小 tip:base64:URL 背景图片与 web 页面性能优化》
css 作用域隔离方法
- 命名空间,加不同的前缀
.aa_container_element {
}
.bb_container_element {
}
- module,例如 vue 的 scoped
<style scoped></style>
- css-in-js
export default () => (
<div>
<h1>Hello World</h1>
<style jsx>{`
h1 {
color: red;
}
`}</style>
</div>
);
- Shadow DOM,其实就是 web components,作用域隔离
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<script>
const persions = ["luffy", "zoro", "nami", "usoop", "sanji"];
customElements.define(
"ace-conponent",
class extends HTMLElement {
connectedCallback() {
const shadow = this.attachShadow({ mode: "open" });
shadow.innerHTML = `
`;
}
}
);
function persions_fn(list) {
return helper_fn(list);
}
function helper_fn(list = []) {
return list
.map((ele) => `<p>${ele}</p>`)
.join(",")
.replace(/,/g, "");
}
</script>
<ace-conponent name="ace-conponent"></ace-conponent>
</body>
</html>
常见的元素隐藏方式
- 使用
display:none;
隐藏元素,渲染树不会包含该渲染对象,因此该元素不会在页面中占据位置,也不会响应绑定的监听事件。 - 使用
visibility:hidden;
隐藏元素。元素在页面中仍占据空间,但是不会响应绑定的监听事件。 - 使用
opacity:0;
将元素的透明度设置为 0,以此来实现元素的隐藏。元素在页面中仍然占据空间,并且能够响应元素绑定的监听事件。 - 通过使用绝对定位将元素移除可视区域内,以此来实现元素的隐藏。
- 通过
z-index
负值,来使其他元素遮盖住该元素,以此来实现隐藏。 - 缩小尺寸 宽高 0
- 通过
transform:scale(0,0)
来将元素缩放为 0,以此来实现元素的隐藏。这种方法下,元素仍在页面中占据位置,但是不会响应绑定的监听事件。 clip-path: circle(0);
元素裁剪的方法来实现元素的隐藏,这种方法下,元素仍在页面中占据位置,但是不会响应绑定的监听事件。
多行文本溢出
.ellipsis-mute {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
CSS 优化、提高性能的方法有哪些
加载性能:
CSS
压缩:将写好的CSS
进行打包压缩,可以减少很多的体积。CSS
单一样式:当需要下边距和左边距的时候,很多时候选择margin:top 0 bottom 0
但margin-bottom:bottom;
margin-left:left;
执行的效率更高。- 减少使用
@import
,而建议使用link
,因为后者在页面加载时一起加载,前者是等待页面加载完成之后再进行加载。
选择器性能:
- 关键选择器(key selector)。选择器的最后面的部分为关键选择器(即用来匹配目标元素的部分)。
CSS
选择符是从右到左进行匹配的。当使用后代选择器的时候,浏览器会遍历所有子元素来确定是否是指定的元素等等; - 如果规则拥有
ID选择器
作为其关键选择器,则不要为规则增加标签。过滤掉无关的规则(这样样式系统就不会浪费时间去匹配它们了)。 - 避免使用通配符,如
*{}
计算次数会很大,只对需要用到的元素进行选择。 - 尽量少的去对标签进行选择,而是用
class
。 - 尽量少的去使用后代选择器,降低选择器的权重值。后代选择器的开销是最高的,尽量将选择器的深度降到最低,最高不要超过三层,更多的使用类来关联每一个标签元素。
- 了解哪些属性是可以通过继承而来的,然后避免对这些属性重复指定规则。
- 尽量扁平化
CSS
,把CSS
原子化。
- 关键选择器(key selector)。选择器的最后面的部分为关键选择器(即用来匹配目标元素的部分)。
渲染性能:
- 慎重使用高性能属性:浮动、定位。
- 尽量减少页面重排、重绘。
- 去除空规则:{}。空规则的产生原因一般来说是为了预留样式。去除这些空规则无疑能减少
CSS
文档体积。 - 属性值为
0
时,不加单位。 - 属性值为浮动小数
0.\*\*
,可以省略小数点之前的0
。 - 标准化各种浏览器前缀:带浏览器前缀的在前。标准属性在后。
CSS
雪碧图,同一页面相近部分的小图标,方便使用,减少页面的请求次数,但是同时图片本身会变大,使用时,优劣考虑清楚,再使用。- 正确使用
display
的属性,由于display
的作用,某些样式组合会无效,徒增样式体积的同时也影响解析性能。例如float
之后再设置inline-block
。 - 不滥用 web 字体。对于中文网站来说
WebFonts
可能很陌生,国外却很流行。WebFonts
通常体积庞大,而且一些浏览器在下载WebFonts
时会阻塞页面渲染损伤性能。
可维护性、健壮性:
- BEM 规范,将具有相同属性的样式抽离出来,整合并通过 class 在页面中进行使用,提高 css 的可维护性。
- 样式与内容分离:将 css 代码定义到外部 css 中。
BEM
BEM 和 SMACCS ⾮常类似,主要⽤来如何给项⽬命名。⼀个简单命名更容易让别⼈⼀起⼯作。⽐如选项卡导航是⼀个块(Block),这个块⾥的元素的是其中标签之⼀(Element),⽽当前选项卡是⼀个修饰状态(Modifier): block -代表了更⾼级别的抽象或组件
block__element -代表.block 的后代,⽤于形成⼀个完整的.block 的整体。
.block--modifier -代表.block 的不同状态或不同版本。
修饰符使⽤的是_,⼦模块使⽤__符号。(不⽤⼀个-的原因是 CSS 单词连接)
举个🌰
<ul class="menu">
<li class="menu__item"></li>
<li class="menu__item_state_current"></li>
<li class="menu__item"></li>
</ul>
清除浮动的⼏种⽅式,各⾃的优缺点
- ⽗级
div
定义height
- 结尾处加空
div
标签clear:both
- ⽗级
div
定义伪类:after
和zoom
- ⽗级
div
定义overflow:hidden
- ⽗级
div
也浮动,需要定义宽度 - 结尾处加
br
标签clear:both
- ⽐较好的是第 3 种⽅式,好多⽹站都这么⽤。
设置倍图
<img
srcset="images/team-photo.jpg 1x, images/team-photo-retina.jpg 2x, images/team-photo-full 2048w"
/>
background: image-set(
url(w128px.jpg) 1x,
url(w256px.jpg) 2x,
url(w512px.jpg) 3x
);