CSS是一团糟。在1995年首次引入,它的意思是风格的基本文本文件。不是网站。不是应用程序 文本文件。从那以后,它已经走过了很长的一段路。可能有点太长了。
许多事情并不像多列布局,响应式网页设计等等,这就是为什么它已经成为一种充斥着黑客和小故障的语言,就像一些带有一些扩展的奇怪的蒸汽机。
在光明的一面,这是什么使CSS乐趣(或有点)!这也是为什么我们有工作。因为我个人确信生成高效的,跨浏览器和面向未来的CSS是不可能的,并且可能不会很快。
照片学分
无论如何,我不是在这里谈论我的信念,而是关于CSS。今天,我们将对CSS常见问题进行总结,以了解如何对CSS进行故障排除。
其中,我选择了一些非常常见而又烦人的问题:
- 浮动清理,一场古老的战斗
- 如何打内联块间距?
- 理解绝对定位
- 何时将宽度/高度设置为100%?
- 如何不搞乱Z指数?
- 什么是保证金崩溃?
浮动清理,一场古老的战斗
我认为这应该是最常见的扫管笏?CSS的时刻。它像山丘一样古老,因此我百分之百肯定每个曾经编码CSS的人都陷入陷阱。
基本上,当一个元素只包含浮动元素时,会自行崩溃。这是因为这样一个事实,即漂浮的元素被从流中抽出来,所以包装的行为就好像他根本没有孩子。
有很多方法可以解决这个问题。早在天,我们用来添加一个空div
与clear: both
在容器的底部。然后,我们更换了div
一个hr
标签。好多了
然后,尼古拉斯·加拉格尔(Nicolas Gallagher)带着一种新的方式来清理父母的花车,而根本不用接触标记。经过大量的讨论和测试,使其达到所需的最低字符数,使其工作,这里是最新版本:
.clearfix:after { content: ""; display: table; clear: both;}
其实我撒谎,这不是最新的版本,但它绝对是最短的。如果您必须支持IE 6/7,则可能需要添加以下内容:
.clearfix { *zoom: 1;}/ *在这里,以防止其他浏览器阅读和应用这个规则。* /
你可能应该做的是.clearfix
在你的项目中创建一个类,你可以通过简单地将它作为一个类来添加到标记中。这是处理浮游物的最简单和最干净的方式。
如何打内联块间距?
让我们继续在同一行上定位元素,这次不是通过浮动它们,而是将它们设置为内嵌块。display: inline-block
一直没有得到充分的利用,但是我们终于弄清楚它是如何工作的,为什么它很酷。如今,越来越多的前端开发人员在可以选择的情况下摆脱内联块的浮动。
我认为内联块的主要观点是我们不必处理浮动清除和浮动元素时可能遇到的其他问题。基本上,将元素的显示设置为内联块将其变为混合动物:半内联,半块。他们可以调整大小,他们可以有利润率,但他们的默认宽度取决于内容,而不是完整的父宽度(等规格)。因此,它们不是垂直堆叠而是水平堆叠。
在那里你说“到底是什么问题?”。问题是因为它们是半内联的,它们彼此之间以空白字符的宽度相互隔开。使用常规字体的默认16px基线,即4px。在大多数情况下,它大约是字体大小的25%。无论如何,这可能是恼人的布局元素。假设您有一个宽度为600px的父级,并且有三个200px宽的内嵌块子元素。如果你不打这个4像素的空间,他们将不适合一行(200 * 3 + 4 * 2 = 608)。
值得庆幸的是,有几种方法可以摆脱这些烦人的空间,每个空间都有自己的长处和短处。说实话,目前还没有完美的解决方案。让我们一个一个看看他们!
标记方面:删除空格
请考虑以下标记结构,对应于我之前描述的几行测试用例。
<div> <!-- 600px --> <div>I'm a child!</div> <!-- inline-block 200px --> <div>I'm a child!</div> <!-- inline-block 200px --> <div>I'm a child!</div> <!-- inline-block 200px --></div>
正如我前面所说,这不会适合一行,因为每个元素(在我们的例子中是一个换行符和2个空格)之间有一个或多个空格字符。解决这个问题的第一种方法是简单地删除空格。
<div> <div>I'm a child!</div><div>I'm a child!</div><div>I'm a child!</div></div>
这绝对有效,但它使标记非常难以阅读。也许我们可以重新组织我们的标签,而不是把它们全部放在同一行,这样它们仍然是可读的:
<div> <div> I'm a child!</div><div> I'm a child!</div><div> I'm a child!</div></div>
或者如果你喜欢时髦,你也可以去
<div> <div>I'm a child!</div ><div>I'm a child!</div ><div>I'm a child!</div> </div>
这是正确的,它完全有效!不过,我不会推荐这个,因为这是一种反直觉。我们已经被教导要在HTML标签中避免无用的空格,即使它本身没有问题,也会使代码变得丑陋。让我们试试别的。
标记方面:评论空间
怎么评论空间,而不是删除它们?
<div> <!-- 600px --> <div>I'm a child!</div><!-- --><div>I'm a child!</div><!-- --><div>I'm a child!</div> </div>
嘿,好多了!代码是可读的,它工作正常。即使看起来很奇怪,你也可能会习惯这样的事情。我个人使用这种方法,当我必须消除内联块元素之间的差距。
然而,有人会说这不是完美的,因为这是一个标记方面的解决方案,这种布局问题应该只是CSS和CSS的问题。真正。这导致我们的CSS端解决方案。
CSS端:字母间距
该letter-spacing
属性用于定义字母之间的空格。这个技巧背后的想法是减少字母之间的空白,以“覆盖空白”,然后重置儿童的字母间距,使文本看起来很正常。
.parent { letter-spacing:- 0.3em ;}.child { letter-spacing:normal ;}
Griddle使用了这种技术,这是一个来自Nicolas Gallagher的基于Sass的网格系统,所以你可以说这是一个非常严重的问题。不过,我真的不喜欢我们依靠魔术数字的事实。加上一些字体,你可能不得不比-0.3em
like -0.31em
或者稍微低一些-0.32em
。调整到你的情况。
CSS方面:负边际
另外一个与前一个非常相似的方法是使用负边距。主要的问题是在Internet Explorer 6和Internet Explorer 7中不能使用负边距。此外,我们必须删除第一个元素的左边距,以使我们的孩子完全适应容器。
.child { margin-left: -0.25em;}.child:first-of-type { margin-left: 0;}
如果你不必支持Internet Explorer 6和7,或者有这些浏览器的条件样式表,我认为这是一个非常安全的解决方案。我可能会去这个。
CSS方面:字体大小
最后但并非最不重要的,你可以尝试设置父字体大小为0,使空白字符0px宽,然后恢复它的孩子。
.parent { font-size: 0;}.child { font-size: 16px;}
它似乎工作很好,但实际上有几个缺点,如:
em
由于父级的字体大小为0px,因此无法设置字体大小,- 在Jellybean之前版本的Android Stock Browser中不会删除空格(如Matt Stow所示),
- 使用
@font-face
,文本可以失去Safari 5中的antialising(如道格斯图尔特所示), - 一些浏览器不允许使用0px的字体大小,就像中文Chrome一样,它会自动将其设置为12px。
所以,绝对不是最好的解决方案。正如我刚才所说,我可能会采取评论的方式。如果您觉得这个过于复杂,您可能会回到浮动元素,或使用flexbox更好。
理解绝对定位
定位是棘手的,一直是。大多数初学者在页面上定位元素时都很困难。他们经常(错误)使用position
财产。该属性定义的元素是如何能够与偏移来移动(top
,right
,bottom
和left
)。它接受四个值:
static
:默认值,偏移量不起作用relative
:偏移移动可视层,但不移动元素本身absolute
:偏移量在其上下文中移动元素(首先,不是静态的祖先)fixed
:偏移将元素放置在视口中,而不管它们在DOM中的位置是什么
使用时出现真正的问题position: absolute
。你可能已经遇到过这个问题了:你定义了一个绝对模式的元素,因为你希望它在父元素的右上角(就像一个模式的某个小关键)。
.element { position:absolute ; 顶部:0 ; 左:0 ;}
...它在窗口的左上角。而且你像“到底是什么?”。其实,这是预期的行为(不是由你,而是由浏览器)。这里的关键字是上下文。
上面的代码基本上告诉“我希望我的元素顶部根据其上下文定位在左上角”。那么上下文是什么?它是第一个不是静态的祖先。它可以是直接的父母。或父母的父母。或父母的父母的父母。只要它是第一个不是静态的。
这对于一个初学者来说是一个很难理解的概念,但是一旦你得到了这个,你可以用绝对定位来做任何事情,而不用大声喊叫,因为一切都是一团糟。
这里是一个快速演示,以说明我们刚才看到的。两位家长,每一个与孩子绝对定位top: 0
和right: 0
。在左边,父母有position: relative
(正确的行为)。在右侧,父母是静态的(失败)。
何时将宽度/高度设置为100%?
身高:100%
我们首先处理那些不那么棘手的问题。何时使用height: 100%
?其实我们很多人至少问过一次的问题是:“我应该怎样让我的页面至少达到屏幕的高度?”。对?对?
要回答这个问题,理解什么height: 100%
意思是重要的:父元素的全高。这并不神奇地意味着“窗口的高度”。所以,如果你想要你的主容器有窗口的高度,设置height: 100%
是不够的。
为什么?因为你的容器(body
)的父元素有一个默认的高度auto
,这意味着它的大小根据它的内容。然后,你可以尝试添加height: 100%
到body元素来看...这还不够。
为什么?因为body(html
)的父元素的默认高度是auto
,这意味着它的大小根据其内容(你的想法)。现在,如果你尝试添加height: 100%
到HTML元素?有用!
为什么?实际上,根元素(仍然html
)并不是页面的最上面的包含块,有“视口”。简单来说就是浏览器窗口。所以如果你设置height: 100%
html元素,你会要求它和浏览器窗口一样高。就如此容易。
用一小段代码来总结我们的故事:
html,body,.container { height:100% ;}
完成。如果您有兴趣对视口进行更深入的解释,我强烈建议您阅读PPK的这篇文章。
如果父母有min-height
和没有height
?
Roger Johansson最近发现,height: 100%
当父元素没有分配高度,而是分配高度时,会出现问题。我不会深究文章,但总结,您可能需要添加一个1px的高度的父元素,所以孩子可以一直扩展到最小高度。
.parent { min-height:300px ; height:1px ; / *必须使孩子100%的最低高度* / }.child { height:100% ;}
更多的话题可以在Roger Johansson的文章中找到。
宽度:100%
现在,我们来处理width: 100%
。首先,快速提醒一下:至于高度属性,设置width: 100%
与请求元素与父元素一样宽。这里不足为奇
现在让我告诉你一个小秘密。宽度是一个非常不恰当的名字。该width
属性不指定元素的总宽度,但是其内容宽度完全不同。
在向width: 100%
元素添加填充和边框时,不再填充其父元素的宽度。不,它溢出。由于填充和边界。因为width
应该被称为内容宽度。请考虑下面的演示,看看我的意思。
父母的宽度是25em
。子元素的宽度为100%
(其父宽度),但也有1em(左侧1em,右侧1em,水平2em)和0.5em(左侧0.5em,右侧0.5em,水平1em)的边界将其宽度推到25em(100%)+ 2em + 1em = 28em。Eeerrr,休斯顿我们有一个问题。
有四种方法可以解决这个问题。第一个,也是最好的一个是避免设置,width: 100%
因为在这种情况下是无用的。子元素是一个块级元素,可自动扩展到其父级的宽度(不存在上述问题)。不幸的是,如果我们正在处理一个内嵌块的孩子,我们不能简单地做到这一点,导致我们下一个修补程序。
我们可以避免使用width: 100%
和使用所需的宽度。在我们的例子中,25 - (2 + 1)= 22em。不用说这个解决方案很糟糕,因为我们必须手动计算宽度。我们需要一个更好的方法!
第三个是用来calc()
做自动计算:width: calc(100% - 3em)
。它仍然很糟糕。首先,我们还要计算水平填充+垂直边界的结果。其次,calc()
没有世界上最好的支持(没有IE 8,没有Safari 5,没有Opera 12,没有Android的股票浏览器)。
第四个想法是使用box-sizing: border-box
。基本上,它改变了盒子模型,所以width属性实际上被设置为元素的总宽度,包括边框和填充。最好的消息是浏览器的支持是非常好的(IE 7和Opera 9除外)。而对于不受支持的浏览器,我们仍然可以使用polyfill。
长话短说:不要使用,width: 100%
除非你使用border-box
盒式模型。
如何不搞乱Z指数?
页面中的所有框都位于三维空间中:除了它们的垂直和水平定位之外,元素沿着Z轴放置。起初,这看起来很简单:具有较高z-索引的元素出现在具有较低z-索引的元素之上。
不幸的是,事情比这更复杂。因为你看,z-index是完全搞砸了。我很确定这是CSS历史上最棘手的CSS属性。因为我确信z-index问题是做CSS时可能遇到的最频繁和烦人的问题。希望我们会尝试启发解决方案。
首先要做的事情 该z-index
属性对静态元素没有影响。为了能够移动Z轴上的元素,您必须定义它relative
,absolute
或者fixed
。所以首先要做的就是确保你的元素有一个位置,甚至在考虑应用之前z-index
。
现在,关于z-index的知识就是DOM中的所有元素都不放在同一个图层上。这意味着将元素索引到非常高的值可能不足以使其出现在前景上。这被称为堆叠上下文。
简单来说,堆叠上下文是一种基于单个HTML元素的组,其中所有子元素共享相同的堆叠顺序(即相同的Z轴)。改变这些元素的Z值可能会使它们以你想要的方式相互重叠。在相同的堆栈上下文中,以下是从CSS规范中显示元素的方法:
- 1. 构成堆叠上下文的元素的背景和边界
- 2. 孩子堆叠负面的堆栈水平(最负的第一)
- 3. 在线的,非在线的,非定位的后代
- 4. 未定位的浮游物
- 5. 包含行内表和行内块的流入式,内联式,非定位后代
- 6. 子级堆栈0的堆栈上下文和堆栈级别0的定位后裔
- 7. 孩子堆叠积极的堆栈级别(最不积极的第一)
当事情变得丑陋
好的,这些是z-index属性的基础。知道这些东西会为你节省很多麻烦,这是肯定的。不幸的是,这还不够。这本来太简单了!
事情是,每个堆叠环境都有自己的Z标度。基本上,堆叠上下文1中的元素A和堆叠上下文2中的元素B不能通过Z索引进行交互。这意味着,如果元素A是堆叠顺序底部的堆叠上下文的一部分,则无法在堆叠顺序中较高的不同堆叠环境中使元素B出现在元素B的前面,即使是非常高Z指数值。
我觉得我们可以做一个关键字z-index: 99999999
,就像z-index: face-punch
看到了很多可笑的z-index值后.-自己。
别急,还有就是甚至更糟。的html
元件形成根部堆叠环境。然后,每个定位(非静态)框与Z索引值以外auto
创建一个新的堆叠上下文。没什么新鲜的。现在,这是事情变得丑陋的地方:一些完全不相关的CSS属性创建新的堆叠上下文。喜欢opacity
。而你就像...
这是正确的,该opacity
属性创建一个新的堆叠上下文。所以做的transform
和perspective
属性。这绝对没有意义,对吗?基本上,如果你有一个完全随机的元素,其透明度低于1,或者与none
变换不同,那么你正在寻找潜在的问题。
不幸的是,每一个Z指数的问题都有自己的背景(无双关意),因此很难为所有这些情况提供一个防弹的建议。最后,我们可以得出几点结论:
- 在应用z-index之前,一定要确定你的元素有一个定义的位置
- 停止5位数Z指数,这是绝对没有意义的; 在大多数情况下,类似的东西
z-index: 10
已经足够了 - 确保要重新排序的元素是同一个堆栈上下文的一部分
- 如果您仍然有问题,请确保您沿途没有变形或不透明的元素
关于主题,我强烈建议你阅读Philip Walton提供的关于Z-index的内容,以及W3C 的官方CSS规范。很多要学习。
战斗边缘崩溃?
我认为这是CSS的故障之一,我花了最多的时间来包扎我的头。我想你可以从某种意义上说,这和z-index是一样的。无论如何,当两个元素的顶部和底部的边缘陷入两者的最大边缘时,边缘塌陷是。对于那些有数学大脑的人来说,两个街区之间的垂直边界是margin = max(block1.marginBottom, block2.marginTop)
。
幸运的是,这通常是期望的行为。这可能是为什么它的工作原理(如CSS规范中所预期和描述的那样)。但是,有时您不希望垂直边缘崩溃。要理解如何解决这个问题,我们首先必须明白为什么发生这种情况。在三种不同的情况下可能发生保证金崩溃。
相邻的兄弟姐妹
当两个相邻的兄弟姐妹有垂直的边缘,他们倒塌在第一个元素的底部和第二个元素的顶部之间的最大边缘。这可以通过几种方法来防止:
clear: left; float: left;
在兄弟姐妹(right
作品)display: inline-block
在兄弟姐妹(inline-table
作品)
以下JSFiddle显示了这些修复程序的操作。
家长和第一/最后一个孩子
通常情况下,父母的顶级利润率和第一个孩子的顶级利润率都将跌至两者的最大利润率。同样,父母的底部边际崩溃与最后一个孩子的底部边缘。这种现象也被称为“祖先的崩溃”。有多种解决方案来对抗这种行为。他们大多数是由以下属性之一添加到父元素:
overflow: hidden
(或其他任何东西auto
)padding: 1px
(或大于0的任何值); 一些浏览器甚至支持子像素值)border: 1px solid transparent
(或任何边界)display: inline-block
(inline-table
也是)float: left
(right
也是)
以下JSFiddle显示了这些修复程序的运行情况:
空块
当一个空的块没有边界,也没有填充,也没有高度时,它的顶部和底部边界合并为一个。然后,它也可以匹配以上两种情况之一,再次与父母/兄弟姐妹的边缘折叠。但是,空元素通常是一个糟糕的主意,所以我想这不是你经常会遇到的情况。
最后的话
哇,这很密集,不是吗?而不幸的是,这只是在错误,黑客和毛刺问题的冰山的顶端。这些是做一些CSS时可能遇到的最常见的问题,但是比浏览器不一致,厂商前缀混乱,选择器特殊性,级联和继承等等还要多。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.