CSS 笔记
这篇文章记录一些 css 的基本概念
float
它脱离文档流,相对于它的包含块,放置自己的位置,包含块不是position!=static,这一点跟absolute fix的元素有点区别。包含块指的是它最近的块级祖先。
介绍一下几个属性 offsetTop, offsetLeft, offsetParent, offsetWidth, offsetHeight,
- offsetParent: mdn,最近的父级元素,同时该父级元素必须是 positioned 元素,也就是 position == relative,absolute,fixed 的最近父级元素。如果没有这样的元素,那么最近的td,th,table 会被返回,如果还没有,那么body 被返回。
这个元素是offsetTop, offsetLeft 的参考系。
<div class="offsetParent" style="position:relative;">
<div class="NOT offsetParent">
<div>Which element is my offsetParent?</div>
</div>
</div>
-
offsetLeft 它其实描述的是 borderbox 的左边 相对于 offsetparent 的 paddingbox 的左边的距离,
-
offsetTop 它描述的是 borderbox 的顶部距离 offsetparent 的 paddingbox 的顶部的距离
-
offsetWidth/offsetHeight,它描述的是 borderbox 的宽高。MDN
-
Element.getBoundingClientRect() 这个函数可以获取元素的相对于ViewPort的位置跟大小信息。
可以参考下面这幅图
clientWidth clientHeight MDN
它实际上值的是 paddingbox 的宽与高,但是要移除 scrollbar 的宽高。 对于 inline element 和没有 CSS 的元素,返回 0. 参考这副图
对于去除页面的抖动,有两篇文章张鑫旭 引用 2
总结一下: scrollbar 会占据容器的可用空间,原本 border-box 内部就是 pading-box, padding-box 内部是 contentbox.但是当 scrollbar 出现时,border-box 内部会有 padding-box + scrollbar。
分享一段 antd 里面的一个方法 getScrollBarSize()
,这个方法通过添加元素的方式来获取 scrollbar 的大小,得到后,再把添加的 dom 移除掉。
export default function getScrollBarSize(fresh) {
if (typeof document === "undefined") {
return 0;
}
if (fresh || cached === undefined) {
const inner = document.createElement("div");
inner.style.width = "100%";
inner.style.height = "200px";
const outer = document.createElement("div");
const outerStyle = outer.style;
outerStyle.position = "absolute";
outerStyle.top = 0;
outerStyle.left = 0;
outerStyle.pointerEvents = "none";
outerStyle.visibility = "hidden";
outerStyle.width = "200px";
outerStyle.height = "150px";
outerStyle.overflow = "hidden";
outer.appendChild(inner);
document.body.appendChild(outer);
const widthContained = inner.offsetWidth;
outer.style.overflow = "scroll";
let widthScroll = inner.offsetWidth;
if (widthContained === widthScroll) {
widthScroll = outer.clientWidth;
}
document.body.removeChild(outer);
cached = widthContained - widthScroll;
}
return cached;
}