搜 索

关于CSS的几个坑

  • 268阅读
  • 2022年08月26日
  • 4评论
首页 / 技术积累 / 正文

CSS部分已经学完了,然后在课堂中也收集了很多关于CSS的小BUG,这些都是很经典的漏洞,我也花费了很长时间去完全搞懂,为了巩固一下自己的记忆,本文统一去了解其中的原理和解决办法并记录起来。

浮动文字环绕的问题

我们先来看一下问题,盒子1和盒子2都是200px,唯一不同的是盒子1设置了float:left,然后盒子2就跑上去了,这一步没问题,因为浮动元素会脱离正常文档流显示,也就是将元素从普通的布局排版中拿走,但是奇怪的是文字竟然单独留在了下方,不在盒子内。

1.png

查阅了官方资料时发现,使用float脱离文档流时,其他盒子会无视这个元素,但其他盒子内的文本依然会为这个元素让出位置,环绕在周围,这也是浮动最初的应用,只是因为后来我们用来同行显示,逐渐忘记这个环绕功能。

当然,只有浮动造成的脱离文档流文字会产生环绕的效果,使用定位造成脱离文档流的元素,其他盒子与其他盒子内的文本都会无视它。

margin塌陷与合并

造成的原因和原理: 这个和上面的文字环绕不太一样,本身就是css的bug,而且没办法避免,但是有解决办法,因为这里涉及margin的设计思想, margin可以理解为不允许多少范围内有非空元素

根据官方的设计思想,发现其实都属于margin合并的范围,其中子元素内部与父元素外部垂直方向的margin合并,这个叫塌陷。而兄弟元素之间的垂直方向重合叫合并。

margin塌陷

·对于两个嵌套关系的块元素,如果父元素没有上内边距及边框

·父元素的上外边距会与子元素的上外边距发生合并

·合并后的外边距为两者中的较大者

2.png

margin合并

·当上下相邻的两个块元素相遇时,如果上面的元素有下外边距margin-bottom

·下面的元素有上外边距margin-top,则他们之间的垂直间距不是margin-bottom与margin-top之和,而是取两个值中的较大者。

3.png

解决方案

margin合并不需要解决,如果需要,尽量只设置一个元素的外边距即可,比如设置了margin-bottom,那下方的就不需要设置margin-top了。

那margin塌陷该怎么解决?

使用BFC(Block Formatting Context),官方的说明如下。

一个BFC区域包含创建该上下文元素的所有子元素,但是不包括创建了新的BFC的子元素的内部元素,BFC是一块块独立的渲染区域,可以将BFC看成是元素的一种属性,拥有了这种属性的元素就会使他的子元素与世隔绝,不会影响到外部其他元素。

说人话就是BFC会改变当前盒子内部的渲染规则,并且不会影响其他元素,但只改变了一点点(据说千分之一都不到),但就是这一点点解决了塌陷问题。

那么,怎么去触发?

1、float属性不为none;

2、position为absolute或fixed;

3、display为inline-block,table-cell,table-caption,flex, inline-flex;

4、overflow不为visible;

以上方案没有最优,需要根据实际需求,请选择不会影响原本显示效果的方法。

margin-top会改变body位置?

先来看看效果,box的属性是高宽200px,然后设置了margin-top200px,其他没有设置任何属性,body就被挤下来了。

4.png

这个问题发生的原因是根据官方的规范指出,一个盒子如果没有上补白(padding-top)和上边框(border-top),那么这个盒子的上边距会和其内部文档流中的第一个子元素的上边距重叠。

因此,这种问题我们可以添加border-top或padding-top去解决,但是必须是有值的,如果为0一样不生效,不过一般不会有这种需求,了解即可。

媒体查询的BUG

这个很有意思,毕竟之前没遇到过,相信很多人也不知道,因为媒体查询一般我们不会设置固定值,一定是一个范围,那么,如果设置固定值会发生什么?

代码如下:

<!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>测试</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        .box {
            width: 200px;
            height: 200px;
            margin-top: 200px;
            background-color: rgb(127, 255, 212);
        }

        @media (width:320px) {
            .box {
                background-color: rgb(101, 101, 101);
            }
        }

        @media (width:375px) {
            .box {
                background-color: rgb(0, 0, 0);
            }
        }
    </style>
</head>

<body>
    <div class="box"></div>
</body>

</html>

然后我们把屏幕大小先调整至iphone5/SE的大小,发现效果是正常的

5.png

再将屏幕调整至iphone6/7/8的尺寸,发现就出现问题了,设置的是375应该是黑色,但是盒子并没有变黑,而是还原到原本的蓝绿色。

6.png

一开始这个问题也把老师搞懵逼了,直到后面才想起来这个是逻辑分辨率和物理分辨率计算导致的误差,从而导致页面没有达到完整的375px,所以代码不会执行,可以联想一下js中的精度问题0.2+0.1真的完全等于0.3吗?

于是我打开设置,把分辨率还原成百分百(因为出厂的时候我屏幕1920显示字体太小了,默认推荐是放大125%)。

7.png

再回来看效果,奇迹就出现了,盒子正常显示黑色!

8.png

最后

上述的几个BUG就是我之前学习CSS的时候疑惑的点了,因为怕忘记所以记录一下,也希望能帮助到面前的你,其实老师说的也没啥问题,在基础不完全的情况下去研究原理会让你怀疑人生,但是有些时候不了解原理可能真的不会写代码,毕竟编程不是死的。

评论区
werl 2022年8月31日 15:10
回复

感觉你脑袋很清晰!
哈哈哈~
我就没有那么聪明了,挺有用的啊~

DianC
1 条回复
DianC
DianC 2022年8月31日 15:44
回复

大佬谦虚了,只是学习遇到的小坑~

喵二 2022年8月26日 14:45
回复

学习一下

DianC
1 条回复
DianC
DianC 2022年8月26日 15:57
回复

欢迎q(≧▽≦q)

avatar