煮豆燃豆萁,
豆在釜中泣。
本是同根生,
相煎何太急?
盒模型是CSS的核心概念,描述了元素如何显示,以及在一定程度上如何相互作用、相互影响。页面中的所有元素都被看作一个矩形盒子,这个盒子包含元素的内容、内边距、边框和外边距。
内边距是内容周围的空间,当给元素填充背景时会作用到元素的内容区域和内边距区域。边框会在内边距外且紧挨着内边距。边框的外侧是外边距,外边距是围绕在盒子可见部分之外的透明区域,用于控制元素之间的距离。
默认情况下,width和height是指盒子的内容区域的大小,如果此时给盒子添加内边距或边框,那么会导致整个盒子变大。现在给类名为"content-box"的盒子设置宽度、高度都为"80px"、内边距为"5px"、边框为"5px solid black",此时可以打开调试工具查看该盒子的大小,会发现该盒子实际是一个长度为"100px"的正方形,并不是"80px"。
实际上还有另外一种盒模型,它的width和height的计算方式和当前的盒子不同。完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
总体:100*100(80+5x2+5x2)
默认盒模型的width和height只会作用于盒子的内容区,而通过"box-sizing"属性可以改变计算盒子大小的方式。“box-sizing"的默认值为"content-box”,即上一题看到的那样,把值只作用于内容区。现在给类名为"border-box"的盒子设置"box-sizing"属性为"border-box",此时width和height的值不仅会作用于内容区,并且还会包括内边距和边框。
很多人将"border-box"称为怪异盒模型,其实并不怪异。因为现实中的盒子就是这样测量的。比如快递盒,当用安全气囊包裹易碎物品时,填充物就可以视为"padding",无论填充物有多厚,也不会影响盒子的整体大小。
现在再给类名为"border-box"的盒子设置宽度、高度都为"100px"、内边距为"5px"、边框为"5px solid black",此时通过调试工具会发现盒子的实际大小并没有因为添加了内边距或边框而被撑大。"border-box"在布局中可以让开发者减少不必要的烦恼,如添加内边距、边框之后盒子大小发生变化影响到整体布局的效果。完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
总:100*100
常规块盒子有一种机制叫外边距折叠,即垂直方向上的两个外边距相遇时,会折叠成一个外边距,且折叠之后的外边距高度为两者之中较大的那一个。现在给类名为"top"、“bottom"两个盒子都设置宽度、高度且都为"100px”、都设置外边距且都为"10px",可以添加任意颜色便于区分两个盒子。此时通过调试工具可以发现两个盒子之间的距离为"10px",并不是"20px",说明已经发生了外边距折叠。
外边距折叠好像很奇怪,实际上却很有用。当一个页面包含了多个段落,如果没有外边距折叠,从第二个段落开始,所有段落的间距都是最上方段落的上外边距的两倍,有了外边距折叠,段落间距才会相等。
如果想要清除两个盒子之间的外边距折叠,可以给目标盒子设置以下属性:
浮动盒子可以向左、右移动,直到它的外边沿接触父级的外边沿或另一个浮动盒子的外边沿。浮动盒子会脱离常规文档流,所以文档流中的元素几乎认为浮动盒子不存在。
现在给"body"标签设置宽度为300px,再给类名为"left"、“center”、"right"的盒子(左、中、右盒子)皆设置宽度、高度且都为100px,三个盒子的颜色可以自定义以便于观测。继续给中间盒子设置"float: left"属性,此时中间盒子已经是一个浮动盒子,不再占据流中的位置空间,右盒子上升到了浮动盒子的区域并且被浮动盒子覆盖住了。现在再给左、右盒子皆设置"float: left"属性,此时三个盒子水平排列在一行上。重设左盒子的宽度、高度皆为120px,可以观察到因为"body"盒子较窄,所以右盒子被迫换行并且因为左盒子的高度超过了中间盒子,右盒子被卡在了中间盒子下方。
以上为浮动盒子的特性。完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
通过前面的学习了解到,浮动元素会脱离文档流,因此不会影响其他元素。但,在之前介绍浮动盒子时提到了"文档流中的元素几乎认为浮动盒子不存在",实际上被浮动盒子覆盖的区域中的文本内容会识别到浮动盒子并且绕开浮动盒子。
现在给类名为"media"的盒子设置"float: left"属性,让该盒子成为浮动盒子,背景色可以自定义便于观察。此时可以观察到盒子下方的文字内容跑到了盒子右侧。通过调试工具可以发现,两个"p"标签被浮动元素所覆盖,并且内部的文字识别到了浮动元素从而绕开了浮动元素。如果给"section"元素添加边框,就会发现"section"这个父级盒子的高度只有两个"p"标签那么高,并没有将浮动元素的高度计算进去,这样会让布局很困难。
clear属性的值有"left"、“right”、“both"和"none”,用于指定盒子的那一侧不应该紧挨着浮动盒子。现在再给类名为"clear-left"的"p"标签设置"clear: left"属性,现在可以发现"universe"文本到了浮动盒子的下方并且"section"盒子的高度也发生了变化,该高度包含了浮动盒子的高度。
完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
hello
universe
在流中的元素定位属性值默认都为"static",即没有定位。此时元素会忽略"top"、“bottom”、“left”、“right"和"z-index"定位属性。
现在给"section"盒子设置"left: 10px”,这时会发现定位属性无效。完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
当一个元素的定位属性设置为"inherit"时,表示从父元素继承定位属性。现在虽然类名为"inner"的里盒子设置了"left: 10px"属性,但是这是无效的,因为该盒子的定位属性值为"static"。现在给里盒子添加"position: inherit"属性,表示从类名为"outer"的父级外盒子继承定位属性,现在发现里盒子的"left: 10px"属性依然没有生效,因为外盒子的定位值依然是"static"。最后再给外盒子添加"position: relative"属性,此时会发现里盒子向右移动了10px,定位属性"left"生效了。
完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
绝对定位会把元素拿出文档流,不会再占据原来的空间。绝对定位元素的父级是距离该元素最近的定位祖先,也就是"position"属性不为"static"的最近任意祖先。如果没有这个定位祖先,那么绝对定位元素就相对于文档的根元素"html"进行定位。
当前类名为"outer"、“middle”、“inner"的盒子(外、中、里盒子)嵌套在一起,现在给三个盒子均设置左内边距10px,再自定义盒子背景颜色以便于观察。再给里盒子设置绝对定位属性"position: absolute”,会发现里盒子的位置并没有发生改变,因为绝对定位的默认位置是当前绝对定位盒子在流中的位置。继续给里盒子设置"left: 0px"属性,观察到里盒子是根据最外层盒子定位的,直接绕过了中间盒子,这是由于中间盒子的定位属性为默认的"static",此时再给中间盒子设置定位属性"position: absolute",会发现里盒子现在是根据中间盒子重新定位的。
完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
绝对定位非常适合创建弹出层、提示和对话框等覆盖于其他内容之上的组件。比如有一篇文章,可以给文章添加一些行内的评注,最好以气泡图的样式显示在文章外部的空白区域中。
绝对定位的元素默认会待在自己还在流中时的地方,现在给"aside"盒子设置绝对定位属性"position: absolute",此时"aside"盒子从流中出来并且覆盖住了下方的元素,现在可以将它向左移动一些,把它定位到文章内容的左边。“article"盒子的左外边距为10rem,想让"aside"评注放在左边空白处的中间,需要进行计算,这里省略计算步骤。现在只需要将评注组件向左移动9rem即可。现在给评注组件设置"margin-left: -9rem”,在CSS中,负边距是完全有效的,负左外边距可以将元素往左拉,其他有趣的效果这里不做赘述。此时观察效果,评注在"相煎何太急?"内容的左边,可以很醒目的告诉读者该句的意思。
emsp;完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
煮豆燃豆萁,
豆在釜中泣。
本是同根生,
相煎何太急?
z-index属性设置元素的堆叠顺序,拥有更高堆叠顺序的元素总是会处于堆叠顺序较低的元素的上面。z-index可以设置为负数,且该属性只能作用于定位元素。
现在给"img"图片标签添加"position: absolute"、"left: 0px"和"top: 0px"属性,此时会发现图片被定绝对定位在了页面的左上角,并且遮挡住了下方的内容。现在继续给图片标签添加"z-index: -1"属性,现在图片堆叠在了字体内容的下方。
完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
The countdown to Christmas starts here.
由于图像的 z-index 是 -1,因此它在文本的后面出现。
相对定位的元素仍然会待在原来的地方,即不会从流中出来。此后可以通过"top"、“right”、“bottom"和"left"属性使元素相对于初始位置进行移动。现在给类名为"center"的盒子设置相对定位属性"position: relative”、设置"left: 50px"、设置"top: 50px",再自定义背景颜色以便于观察。此时可以观察到中间盒子在原始的位置上向右、向下均移动了50px的距离,并且保留了原来的空间。
完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
固定定位是由绝对定位衍生出来的,不同之处在于,固定定位元素的父级始终是视口。因此固定定位可以用来创建始终停留在窗口相同位置的元素。比如:固定侧栏、固定顶栏等。这样方便用户,不必再费事寻找栏目。
现在给"nav"盒子设置固定定位属性"position: fixed"、设置"top: 0"、设置自定义宽度、背景颜色。此时滑动滚轮,可以发现"nav"盒子始终固定在页面的最上方。但是,数字1却被覆盖了。由于固定定位的盒子不在流中,所以遮盖住了下方的元素。此时再给"section"盒子设置上外边距为1rem,此时1数字正常出现了。固定定位需要注意下方是否有元素被遮挡。
完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
1
2
固定定位不仅可以用于导航栏目,还可以用于控制中心、广告、重要提示内容等。本节使用固定定位实现一个广告牌功能,关闭按钮和该按钮的功能已给出,当点击按钮时,广告牌会消失。现在给类名为"advert"的盒子设置固定定位属性"position: fixed"、设置"right: 0"、设置"bottom: 0",此时广告牌的位置被固定在了视口的右下方。现在还需要将关闭按钮定位在广告牌的右上方,继续给类名为"x"的按钮盒子设置绝对定位属性"position: absolute"、设置"right: 0",观察按钮的位置,已经被定位在了广告牌的右上方。一个简易的广告牌就设计完成了。
完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
广告文案
Flexbox,也就是Flexible Box Layout模块,是CSS提供的用于布局的一套新属性。这套属性包含针对容器、容器直接子元素(弹性项)的两类属性。Flexbox可以控制弹性项的这几个方面:
Flexbox支持对弹性项的灵活控制。Flex的意思为可伸缩,这体现在以下三个属性中:
通过之前的学习,现在来实现一组标签,表示星球的种类。当前的"li"标签都是行内盒子,虽然看似实现了标签效果,但是每一行的宽度却没有保持一致,当进行缩放时,布局会特别的混乱。现在使用Flex布局将当前的布局方式进行优化,首先删除"li"标签的"display: inline-block"属性,给"ul"添加"display: flex"使该元素称为弹性容器。再给容器添加"flex-wrap: wrap"属性表示换行,否则所有标签会在第一行排列。此时标签已经分行排列了,但,每一行的宽度看起来依然是不同的,这时候需要通过给弹性项添加属性,通过之前讲过的"flex"属性入手。继续给所有的"li"标签添加"flex: 1 0 auto"属性,auto代表在计算剩余空间时需要减去每个标签自身的宽度而不是之前讲的0%那样忽略了自身的宽度。此时标签功能基本上是完成了,但是注意,最后一行可能因为页面的缩放导致只有一个标签却占满了一整行。那么继续给所有的"li"标签设置"max-width: 10rem"即可,此时最后一行标签虽然少但是看起来依旧很和谐。
完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
使用Flexbox的order属性,可以完全摆脱项目在源码中顺序的约束。默认情况下,每个项目的order值都为0,意味着按照他们在源代码中的顺序进行排列。可以观看右边的代码效果,从设计上说,把图片放在最前面可以抓住读者的眼球,是比较好的设计方式,但是对于浏览器而言,拿到标题并且直接将标题呈现给读者的代价一定比获取一张照片并渲染出来小得多。所以可以考虑折中的方式,先渲染标题但是优先显示图片。
现在给"img"图片标签设置"order: -1"属性,此时观察效果会发现图片的排列在标题之上,其他内容的相对位置不会变,它们的order值仍然是0。order的值不一定要连续,并且正负都可以。
完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
countdown
The countdown to Christmas starts here.
Grid,即网格布局。它将页面划分为一个个网格,可以任意组合不同的形态,做出理想的布局效果。Grid布局与Flexbox布局的区别在于,Flexbox是根据轴线对弹性项进行排列,而Grid布局是将容器划分为行和列,产生单元格,然后再对单元格进行操作。
采用网格布局的区域称为容器。容器内部采用网格定位的每个子元素称为容器项,也是单元格。划分网格的线称为网格线,比如,3x3的网格有4条水平网格线和4条垂直网格线。
现在给section盒子设置"display: grid"属性,将该盒子变成一个容器。现在需要通过给该容器划分行和列来生成单元格,给容器设置"grid-template-rows: 100px"和"grid-template-columns: repeat(2, 1fr)“两条属性以生成一个Nx2的网格,且每个容器项的宽度比为1:1、第一行的高度为100px(注意:实际上行高度可以不用设置,会根据每个容器项自动撑开,但如果设置了,就要考虑清除需要多少行,当前的行值100px仅为第一行,如果需要前三行都为100px,需要设置为"grid-template-rows: 100px 100px 100px”)。repeat方法可以简化属性值的书写,为了方便表示比例关系,网格布局提供了fr关键字,该关键字和flex-grow颇为相似。实际上如果想固定大小,完全可以将单位全部设置为固定的px值。现在继续给容器添加"grid-gap: 10px"属性,该属性为"grid-row-gap"和"grid-column-gap"两个属性的简写,分别代表行间距和列间距。
进入下一节的学习吧。
1
2
3
4
5
6
7
8
9
网格布局允许指定区域,一个区域由单个或多个单元格组成。根据上一节学习的内容,请将"section"设置为网格布局容器,并且生成一个3x3的网格,该网格容器项的宽度、高度都为100px。再给容器添加"grid-template-areas: ‘a b c’‘d e f’‘g h i’“属性,表示3x3的网格区域划分从左到右、从上到下依次为a、b、c、d、e、f、g、h、i。现在给第一个"article"标签设置"grid-area: e"属性,此时可以看到数字1已经被移动到了最中间的区域,即区域"e”。
进入下一节的学习吧。
1
2
3
4
5
6
7
8
9
单列布局是将头部、内容区、底部在页面上垂直排列,是非常实用的一种布局方式。主要对三个区域的宽度进行统一,然后通过设置自动外边距进行居中。
现在给"header"、“section”、“footer"三个盒子统一设置"margin: 10px auto”、“width: 360px”、“border: 1px solid black"属性。此时因为内容区有内容而头部和底部没有内容所以只有内容区的高度被撑开,一般头部和底部的内容是根据自己的需求固定大小的,所以现在再给头部和底部统一设置高度,即"height: 32px”。
完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
自适应的双列布局利用浮动、外边和触发父级BFC即可实现,这种方法主要是因为BFC的高度计算会包含其内的浮动元素的高度,父盒子会被撑开。
现在给类名为"container"的父盒子添加"overflow: hidden"属性,使该父盒子成为BFC。继续给类名为"left"的盒子设置"float: left"和"width: 100px"属性,使该盒子成为浮动元素并且需要一个固定的宽度。最后再给类名为"right"的盒子设置左外边距"margin-left: 100px"属性,该属性值需要和左浮动的盒子宽度一致。此时父盒子的高度会根据左边浮动元素、右边内容区中高度较高的一方进行计算,并且右边内容区的宽度自适应,最好是根据需要,配合最大或最小宽度进行设置。
完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
通过绝对定位实现的双列布局看起来会比较僵硬,因为父盒子首先需要设置定位属性并且父盒子的高度无法被子盒子撑开,如果子盒子的高度是自适应的,那么父盒子的高度也就无法确定从而设置了,但优点是设置属性比浮动来得更直观。
现在给类名为"container"的父盒子添加"position: relative"属性,为了保证子盒子绝对定位时不会根据html元素定位。继续给类名为"left"的盒子添加"position: absolute"、“left: 0"和"width: 100px"三条属性,使该盒子定位到父盒子的最左边并且赋予宽度,但高度是根据内容自适应的。最后给类名为"right"的盒子添加"position: absolute”、“left: 100px"和"right: 0px”,因为该盒子没有给定宽度,设置"left"和"right"定位属性会使内容区保留在这个范围内,同样实现了自适应。
完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
通过Flexbox可以快速实现双列布局,主要通过"flex: 1"这条弹性项属性给内容区申请到父盒子的所有剩余空间,并且可以给弹性项设置"position"属性调整弹性项内部的子盒子细节。
现在给类名为"container"的父盒子添加"display: flex"属性,使该盒子成为弹性盒容器。继续给类名为"left"的弹性项盒子添加"width: 100px"属性。最后给类名为"right"的弹性项盒子添加"flex: 1"属性。由于弹性项盒子默认占满弹性容器盒子的所有高度,所以两个弹性项盒子的高度也是自适应。右边的内容区宽度会占满弹性容器盒子的剩余空间,所以宽度也是自适应的。
完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
使用Grid网格布局实现双列布局的要点在于列数为2,且首列的宽度根据需要自行设置,第二列使用片段"fr"属性进行自适应即可。行数不需要指定,每行会根据内容高度进行自适应缩放。
现在给类名为"container"的盒子添加"display: grid"属性,使该盒子成为容器。再给该容器添加"grid-template-columns: 100px 1fr"属性,表示第一列宽度始终为100px,第二列的宽度为剩余的所有空间。此时可以看到整个容器的高度因为首列的内容被撑开了,并且右边内容区实现了自适应。
进入下一节的学习吧。
使用浮动实现三列布局的注意点是浮动元素需要写在内容元素之前,否则布局是混乱的。这种方式实现三列布局是优点是简单、兼容性好,但缺点是需要清除浮动,否则父盒子的高度无法撑开,可能会导致其他页面元素的布局混乱。
首先给类名为"container"的盒子添加"overflow: hidden"属性,该属性可以使盒子成为BFC,处理浮动元素父盒子高度塌陷的问题。再给类名为"left"的盒子添加"float: left"和"width: 100px"两条属性,首先往左浮动,宽度这里设置100px。继续给类名为"right"的盒子添加"float: right"和"width: 100px"两条属性,往右浮动。最后给类名为"center"的盒子设置外边距"margin: 0px 100px",该属性上下外边距为0px,左右外边距为两边浮动元素的宽度100px,这样保证了中间的内容区域不会被两边的浮动元素覆盖住。注意,HTML文档中两个浮动元素的顺序在内容元素之前。
完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
使用绝对定位实现三列布局,实际上是和之前使用绝对定位实现双列布局同一个原理。主要思路是,两边通过绝对定位定位到父盒子的左、右边框上,再根据实际的需要设置两边盒子的宽度,高度是根据内容自适应的。中间内容区通过定位属性左、右自适应宽度。
现在给类名为"container"的盒子添加"position: relative",该属性使子元素可以相对该盒子做定位。继续给类名为"left"的盒子添加"position: absolute"、“left: 0px"和"width: 100px"三条属性。继续给类名为"right"的盒子添加"position: absolute”、“right: 0px"和"width: 100px"三条属性。最后给类名为"center"的盒子添加"position: absolute”、"left: 100px"和"right: 100px"三条属性,表示自适应区域为距离左边100px至距离右边100px。此时可以看到三个盒子的高度不同,根据内容高度撑开,实际中可以按需设置高度值。
完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
相比于浮动和定位,使用Flexbox布局实现三列布局要更好,因为弹性容器的高度会根据最高的弹性项进行修正,不会出现明显的台阶式效果。Flexbox实现三列布局的特点为简单、使用、强大,核心思路为设置中间内容盒子的"flex: 1"属性,让中间内容区的宽度自适应,独自占据弹性容器的全部剩余空间。
现在给类名为"container"的盒子添加"display: flex"属性,使该盒子成为弹性容器。再给类名为"left"和"right"的盒子添加"width: 100px"属性,最后给类名为"center"的盒子添加"flex: 1"属性,使该盒子占据容器盒子的全部剩余空间。此时会发现即使三个子盒子的内容高度不同,但容器和子会根据最高的子元素进行修正,并且没有出现浮动和定位中的台阶式效果。
完成以上所讲的步骤即可通过测试,进入下一节的学习吧。
使用grid网格布局实现三列布局,和之前所讲的gird实现双列布局是同样的思想,只是把列数变为了3,高度依然不设置,通过容器项的内容高度自适应撑开整体高度。
现在给类名为"container"的盒子添加"display: grid"属性,使该盒子成为网格布局容器。再给该容器添加"grid-template-columns: 100px auto 100px"属性,表示该容器一共有3列,且宽度分别为100px、自适应、100px。不需要设置行属性,当有多个元素时容器会自适应的往下顺次排列。此时观察容器的高度,是根据容器项中高度最高的那一项决定的,也不会产生台阶式效果。
进入下一节的学习吧。
不像Flexbox或Grid布局可以控制元素显示的次序,圣杯布局是通过浮动元素和外边距属性实现三列布局,但最重要的一点是,在文档中需要将优先渲染的内容写在最前方,但显示时看起来却好像是按照显示次序书写的一样。
首先给类名为"container"的盒子添加"overflow: hidden"和"padding: 0px 100px"属性,以为了防止容器盒子高度塌陷和给之后的左、右浮动元素预留位置。现在继续给类名为"left"的盒子添加以下属性:
双飞翼布局是在圣杯布局上做了优化,解决了圣杯布局中布局发生错乱的问题。核心思路是在圣杯布局的基础上,再在内容区添加一层新的盒子,该盒子通过外边距将内容与两边的浮动元素分隔开,实际上中心盒子是没有"padding"属性的。
首先给类名为"container"的盒子添加"overflow: hidden"属性,解决子浮动元素导致的高度塌陷问题。然后继续给类名为"left"的盒子添加"float: left"、“margin-left: -100%“和"width: 100px”。再给类名为"center"的盒子添加"float: left"和"width: 100%“属性,该盒子并没有像圣杯布局时添加"padding"属性那样。继续给类名为"right"的盒子添加"float: left”、“width: 100px"和"margin-left: -100px”。最后给类名为"main"的盒子添加"margin: 0px 100px”,该属性为双飞翼布局的核心点,使用外边距将内容封锁在两边浮动元素的中间。
完成以上所讲的步骤即可通过测试。感谢您,再见。
这里对文章进行总结:
以上就是nk前端篇-CSS布局CSS的内容,本文介绍了css布局相关写法,在此记录,而更多关于前端题目会后续继续整理。
【前端】nk前端篇-零基础FED
【前端】nk前端篇-CSS布局CSS
【前端】nk前端篇-JS能力测评js(1)
【前端】nk前端篇-JS能力测评js(2)