CSS布局总结及实际应用中产生的问题
布局初步#
所谓布局,其实是指的将网页内容以一定的方式放到合适的位置上去。
布局的基本步骤:
1, 将“当前版面”以视觉上界限明显的方式进行划分若干个区块,划分只用两种方式:
a) 上下结构:此时,只要使用若干个盒子,自然就是上下结构,无需其他设置。
b) 左右结构:此时使用若干个盒子,并进行相应的浮动,通常的模式:
i. 2个盒子:一左一右
ii. 3个盒子:两左一右或两右一左,或一边倒。
iii. 更多盒子:通常一边倒。
浮动解释#
浮动就像水中的气泡,会“网上浮”
更形象的比喻:大家(所有标签)都在“地面上平铺着”,各自占据着一定的面积,浮动元素却“浮”到天花板上去了,其并占据大家通常的“地面面积”
浮动除了表现上不跟别的元素抢占地盘之外,其最主要的特性(也就是破坏效果)其实是:使其父盒子失去合理高度——父盒子已经包不住其这些浮动的内部盒子了!这在布局中基本上是不允许的!那么我们就必须使用补充的做法来实现合理包含——父盒子包住子盒子。
总结:布局需要左右排列,左右排列需要浮动,浮动需要修正其破坏效果——让父盒子合理包住其子盒子
复习文档流
文档流 首先我们先了解一个概念,文档流“Normal flow”是css中定位的一种默认情况,平时我们所说的BFC、IFC等都是“Normal flow”的情况下的规则。
常规情况下脱离文档流的是float,absolute,fixed。
英文文档解释的意思,当元素浮动的时候,会先遵循“Normal flow”的规则,然后尽可能的向俩边靠。
所以float并不是会脱离文档流,反而是依赖于文档流。position中的absolute和fixed的情况下,官方文档解释说会完全脱离“Normal flow”。
在“Normal flow”中,BFC规则中,文本会围绕在浮动元素旁边。出现了这种现象,可能国人就自定义了“文本流”这种东西。
总结:表面上看,float脱离了“文档流”,没有脱离“文本流”;position中的absolute和fixed全部脱离。这种解释也合情合理,是标准答案。
浮动和浮动的清除定位和定位的常用方法fixed和absolute:两者的效果在没有滚动条的时候是一样的区别:fixed是固定定位,absolute是绝对定位。Fixed块有滚动条之后不显示。 relative和absolute:absolute块脱离文档流,relative会保留定位块原来的位置 static是默认的定位
注意:absolute相对于父元素定位,父元素必须是absolute和relative定位 脱离文档流的定位:absolute,fixed,浮动
复习常用标签及盒模型#
HTML元素分类 HTML元素分类#
1 2 3 4 5 6 7 8 | 1,块级元素 block 如:div、p、h1-h6、li、ul、ol、dl 特点: ①独占一行显示; ②可以设置宽度、高度、行高和上下边距; ③不设宽度,则和父元素的宽度一致 2,行内元素 inline 如:a、span 特点: ①可以和其他行内元素在一行上显示 ②不可以设置宽度、高度、行高和上下边距 ③元素的宽度就是它包含的文字或图片的宽度 3,行内块元素 inline-block 如:img、input 特点: ①可以和其他行内块元素或行内元素在一行上显示 ②可以设置宽度、高度、行高和上下边距 不同类型元素可以相互转换: display:block; display:inline-block; |
盒模型#
在CSS看来,任何元素都是一个盒子。
CSS框模型:
1,基础知识点
①width和height不能应用于行内元素(行内非替换元素)②width、height默认值为auto;padding、border、margin默认宽度为0; margin可取值auto,padding和border不可以! 背景会延伸到内边距中,但不会延伸到外边距③margin、border、padding取值方式:四个值(上、右、下、左) top right bottom left三个值(上、左右、下)两个值(上下 、左右)一个值(上右下左)
2,margin
①不仅是左右margin,还有上下margin,其百分数取值都是相对于父元素的width计算的
②正常流中的块级元素垂直相邻外边距会合并
③对于行内非替换元素(行内元素):上下外边距无效果(因为它对行高没有任何影响?),左右外边距有效
④对于行内替换元素(行内块元素):上下外边距会影响行高,所以有效果,左右外边距也有效
⑤width、margin-left、margin-right这三个属性都设置非auto的某个值,此时,总会把margin-right强制为auto
⑥width:100px;margin-left:auto;margin-right:auto;这会将两个外边距设置为相等的长度,从而将元素居中
⑦将某个外边距及width设置为auto,该外边距会减为0;将width、margin-left、margin-right三个都设置为auto,则两个外边距都会重置为0,而width尽可能宽
⑧正常流中一个块级元素的margin-top或margin-bottom设置为auto,它会自动计算为0
⑨标准流中,第一个子元素的margin-top会作用在父元素身上原因:根据规范,一个盒子如果没有上补白(padding-top)和上边框(border-top),那么这个盒子的上边距会和其内部文档流中的第一个子元素的上边距重叠解决办法:给父元素加个padding-top或border-top或overflow:hidden⑩标准流元素、浮动元素可以相互占对方类的margin,但不可占其同类的margin;绝对定位与固定定位,谁的margin都可以占,即使是同类,然而,任意的元素也可以占它们的margin
3,border/padding
①对于行内非替换元素(行内元素):上下边框(或内边距)对行高没有任何影响,所以有可能覆盖上下内容;左右边框(或内边距)正常显示,相邻文本会在其旁边显示②对于行内替换元素(行内块元素):上下边框(或内边距)会影响行高,所以不会覆盖上下内容,左右边框(或内边距)也正常显示/* 属性类型写法举例 */margin: 10px;margin-top: 10px; padding: 10px;padding-top: 10px; border: 1px red solid;border-top: 1px red solid;border-top-width: 1px;border-width: 1px;border-style: solid;border-color: red;
4,行内块元素显示多余空白问题行内块元素的盒子之间会存在一定的空隙(4px);是由于盒子间的空白字符造成的解决办法:
①可以把代码首尾相连写在一起,不留空白字符(不能消除底部空白),不推荐使用
②设置其父元素 font-size:0;/* 要使高度不同,有内容的inline-block盒子以底部整齐排列 */
/* 方式一: */vertical-align: bottom;
/* 方式二: */overflow: hidden;
去除图片底部4px空白:
①给其父元素设置font-size:0; 或 line-height:0;
②给图片设置display:block; 或 vertical-align:bottom;
浮动CSS允许浮动任何元素#
float: left | right | none
①浮动元素会从文档的正常流中删除,不占原来的位置;即元素浮动后会脱离标准流
②一个元素浮动时,其他内容会“环绕”该元素(不仅对于浮动图像)
③要浮动一个非替换元素,则必须为该元素声明一个width
④元素浮动后就具有了行内块元素的特性,浮动元素会生成一个块级框浮动
规则(部分):
①浮动元素只能在其包含块内容区内浮动(除了设置负外边距和浮动元素比其包含块更宽)
②浮动元素互相贴靠,不会相互重叠
③浮动元素的顶端应当与其标记所在行框(源文档中)的顶端对齐
④行内框与浮动元素重叠时,其所有都在浮动元素“之上”显示;
块框与浮动元素重叠时,仅内容在浮动元素“之上”显示
边框和背景在浮动元素“之下”显示
浮动元素的包含块是其最近的块级祖先元素
定位position#
定位静态定位 static:默认值 元素标准流的显示方式相对定位
relative:相对其原位置定位,仍占原来的空间绝对定位
absolute:①不占原来的空间,元素框从文档流完全删除;②能将行内元素转化为行内块元素; ③相对于其包含块定位,其包含块为最近的position值不是static的祖先元素。
固定定位 fixed:①不占原来的空间,元素框从文档流完全删除;②能将行内元素转化为行内块元素; ③相对于其包含块定位,其包含块为视窗绝对定位元素的包含块为最近的position值不是static的祖先元素,祖先是块级元素,包含块则为由边框界定的区域;祖先是行内元素,包含块则为该祖先元素的内容边界定位需使用到偏移属性;
偏移属性:left right top bottom (可取正值也可取负值)
z-index:应用于定位元素,可以改变元素相互覆盖的顺序; 取值越高的元素离用户越近,并覆盖值低的元素;可以取所有整数,包括负数
浮动与两种定位分析与总结
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | <! DOCTYPE html> < html > < head > < meta charset="UTF-8"> < title >浮动与定位</ title > < style > .box { /* 相对定位 */ position: relative; /* 绝对定位 */ position: absolute; /* 固定定位 */ position: fixed; } </ style > < style > ul { margin: 0; padding: 0; list-style: none; } li { float: left; cursor: pointer; border-bottom: 2px solid orange; /*padding: 0 5px;*/ margin: 0 5px; } li:first-child { /*1.浮动与相对定位结合使用*/ /*盒子采用的是浮动布局为主, 相对定位可以辅助其子级绝对定位布局, 也可以在浮动布局基础上微调 */ /*position: relative;*/ /*采用相对定位布局, 在浮动布局基础上微调, 不影响兄弟盒子的布局*/ /*left: 10px;*/ /*采用盒模型布局, 在浮动布局基础上微调, 影响兄弟盒子的布局*/ /*margin-left: 10px;*/ } li { /*1.浮动与绝对定位结合使用*/ /*盒子采用绝对定位布局, 浮动布局失效 */ /*为什么: 因为两者都是脱离文档流, 绝对定位为完全脱离文档流*/ position: absolute; } li:last-child { left: 100px; } /*脱离文档流: 盒子的宽度可以由内容撑开*/ .ele { /*width: 100px;*/ height: 100px; background-color: pink; /*float: right;*/ position: absolute; right: 0; } </ style > </ head > < body > <!--布局: 1.盒模型布局 | 2.浮动布局 | 3.定位布局--> < ul > < li >列表项</ li > < li >列表项</ li > < li >列表项</ li > </ ul > < div class="ele">12345 67890</ div > </ body > </ html > |
分析脱离文本流产生的css层级问题
什么是CSS规则之层叠上下文
1 2 | 若两条规则具有相同的权值、起源及特殊性,那在样式表中最后出现的规则优先。 任何位于文档中的规则都比引入的规则优先 |
注意点
元素设置了position属性后,这个定位元素的z-index就会自动生效,此时它的z-index值就是默认的auto,也就是0。
层级不取小数
层级一样,后面的盒子比前面的盒子的层级高
浮动或者标准流的盒子,后面的盒子比前面的层级高
解决子级对象使用css float浮动 而父级div不能自适应高度,不能被父级内容撑开解决方法,父级div没有高度解决方法
最外层的父级DIV不能自适应高度-不能随对象撑开没有高度
当在对象内的盒子使用了float后,导致对象本身不能被撑开自适应高度,这个是由于浮动产生原因。
如何解决父div对象自适应高度,方法有三种
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <! DOCTYPE html> < html > < head > < meta charset="utf-8" /> < title >父div不自适应高度实例</ title > < style > .divcss5{ width:500px; border:1px solid #000; padding:10px} .divcss5-lf{ float:left; width:220px; height:100px; background:#000} .divcss5-rt{ float:right; width:230px; height:100px; background:#06F} </ style > </ head > < body > < div class="divcss5"> < div class="divcss5-lf"></ div > < div class="divcss5-rt"></ div > </ div > </ body > </ html > |
问题截图:
方法一:对父级设置固定高度#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <! DOCTYPE html> < html > < head > < meta charset="utf-8" /> < title >父div不自适应高度实例</ title > < style > .divcss5{width:500px;border:1px solid #000;padding:10px; height:100px} .divcss5-lf{ float:left; width:220px; height:100px; background:#000} .divcss5-rt{ float:right; width:230px; height:100px; background:#06F} </ style > </ head > < body > < div class="divcss5"> < div class="divcss5-lf"></ div > < div class="divcss5-rt"></ div > </ div > </ body > </ html > |
对父加高度100px 解决外层父div自适应高度截图
此方法缺点,父级是固定高度,而不随内容高度自适应高度,没高度。此方法针对能确定父div内的内容高度情况下使用。
使用css clear清除浮动#
对父级div标签闭合</div>前加一个clear清除浮动对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <! DOCTYPE html> < html > < head > < meta charset="utf-8" /> < title >父div不自适应高度实例</ title > < style > .divcss5{width:500px;border:1px solid #000;padding:10px} .divcss5-lf{ float:left; width:220px; height:100px; background:#000} .divcss5-rt{ float:right; width:230px; height:100px; background:#06F} .clear{ clear:both} </ style > </ head > < body > < div class="divcss5"> < div class="divcss5-lf"></ div > < div class="divcss5-rt"></ div > < div class="clear"></ div > </ div > </ body > </ html > |
使用clear:both清除父级内子对象产生浮动
此方法需要注意是clear:both加的位置,不是对父级直接加clear样式,而是在父级</div>前加带clear对象盒子
方法三:对父级样式加overflow样式#
此方法非常简单,也可以作为推荐解决父级不能被撑开自适应高度的方法,可以不增加div盒子对象,只需要对父级加一个overflow:hidden样式即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <! DOCTYPE html> < html > < head > < meta charset="utf-8" /> < title >父div不自适应高度实例</ title > < style > .divcss5{width:500px;border:1px solid #000;padding:10px;overflow:hidden} .divcss5-lf{ float:left; width:220px; height:100px; background:#000} .divcss5-rt{ float:right; width:230px; height:100px; background:#06F} </ style > </ head > < body > < div class="divcss5"> < div class="divcss5-lf"></ div > < div class="divcss5-rt"></ div > </ div > </ body > </ html > |
父div加overflow样式解决父自适应高度
推荐。此方法为非常简单解决子用float,父div不能自适应高度,不能随父内容多少而自适应高度没有高度,但是要注意一旦子元素的大小超过父容器的大小,就会出显示问题
方法四:浮动的父容器#
另一种思路是,索性将父容器也改成浮动定位,这样它就可以带着子元素一起浮动了
1 2 3 4 | < div style="float:left;"> < div style="float:left;width:45%;"></ div > < div style="float:right;width:45%;"></ div > </ div > |
这种方法不用修改HTML代码,但是缺点在于父容器变成浮动以后,会影响到后面元素的定位,而且有时候,父容器是定位死的,无法变成浮动
方法五:After伪类清除浮动(最推荐)#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <! DOCTYPE html> < html > < head > < meta charset="utf-8" /> < title >父div不自适应高度实例</ title > < style > .clearfix{width:500px;border:1px solid #000;padding:10px;} .divcss5-lf{ float:left; width:220px; height:100px; background:#000} .divcss5-rt{ float:right; width:230px; height:100px; background:#06F} .clearfix:after{ content:""; display:block; visibility:hidden; clear:both; height:0;} .clearfix{ /* 为了照顾ie6浏览器*/ zoom:1;} </ style > </ head > < body > < div class="clearfix"> < div class="divcss5-lf"></ div > < div class="divcss5-rt"></ div > </ div > </ body > </ html > |
最完整的清浮动操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /* slightly enhanced, universal clearfix hack */ .clearfix:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; } .clearfix { display: inline-block; } /* start commented backslash hack \*/ * html .clearfix { height: 1%; } .clearfix { display: block; } /* close commented backslash hack */ |
一个国外大佬的最牛清浮动https://perishablepress.com/lessons-learned-concerning-the-clearfix-css-hack/
1 2 3 4 5 6 7 8 9 10 11 12 | .clearfix:before,.clearfix:after{ content:""; display:table; } .clearfix:after{ clear:both; } .clearfix{ /*照顾ie6*/ zoom:1; } 使用: < div class="box clearfix"> |
After before伪类清除浮动是大部分大型网站常用的,比如新浪 淘宝 的清除浮动的效果
浮动产生负作用#
背景不能显示
由于浮动产生,如果对父级设置了(CSS background背景)CSS背景颜色或CSS背景图片,而父级不能被撑开,所以导致CSS背景不能显示。
边框不能撑开
如上图中,如果父级设置了CSS边框属性(css border),由于子级里使用了float属性,产生浮动,父级不能被撑开,导致边框不能随内容而被撑开。
margin padding设置值不能正确显示
由于浮动导致父级子级之间设置了css padding、css margin属性的值不能正确表达。特别是上下边的padding和margin不能正确显示
css布局技巧
单列布局水平居中#
水平居中的页面布局中最为常见的一种布局形式,多出现于标题,以及内容区域的组织形式,下面介绍四种实现水平居中的方法(注:下面各个实例中实现的是child元素的对齐操作,child元素的父容器是parent元素)
使用inline-block 和 text-align实现
1 2 | .parent{text-align: center;} .child{display: inline-block;} |
优点:兼容性好;
不足:需要同时设置子元素和父元素
使用margin:0 auto来实现
1 | .child{width:200px;margin:0 auto;} |
优点:兼容性好
缺点: 需要指定宽度
使用table实现
1 | .child{display:table;margin:0 auto;} |
优点:只需要对自身进行设置
不足:IE6,7需要调整结构
使用绝对定位实现
1 2 3 4 | .parent{position:relative;} /*或者实用margin-left的负值为盒子宽度的一半也可以实现,不过这样就必须知道盒子的宽度,但兼容性好*/ .child{position:absolute;left:50%;transform:translate(-50%);} 不足:兼容性差,IE9及以上可用 |
垂直居中#
vertical-align
CSS中的有些元素也是这样,他们有的只对牛奶感兴趣,有的只喜欢吃坚果和果冻,而讨厌牛奶。而vertical-align呢,是个比较挑食的家伙,它只喜欢吃果冻,从小吃果冻长大,没有了果冻,它就会闹脾气,对你不理不睬。我称之为“果冻依赖型元素”,又称之为“inline-block依赖型元素”,也就是说,只有一个元素属于inline或是inline-block(table-cell也可以理解为inline-block水平)水平,其身上的vertical-align属性才会起作用。
我对css-vertical-align的一些理解与认识
在使用vertical-align的时候,由于对齐的基线是用行高的基线作为标记,故需要设置line-height或设置display:table-cell;
/*第一种方法*/
.parent{display:table-cell;vertical-align:middle;height:20px;}
/*第二种方法*/
.parent{display:inline-block;vertical-align:middle;line-height:20px;}
使用绝对定位
.parent{position:relative;}
.child{positon:absolute;top:50%;transform:translate(0,-50%);}
水平垂直全部居中
利用vertical-align,text-align,inline-block实现
.parent{display:table-cell;vertical-align:middle;text-align:center;}.child{display:inline-block;}
利用绝对定位实现
.parent{position:relative;}.child{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);}
多列布局#
左列定宽,右列自适应#
该布局方式非常常见,适用于定宽的一侧常为导航,自适应的一侧为内容的布局
利用float+margin实现
1 2 3 | .left{float:left;width:100px;} .right{margin-left;margin-left:100px;} |
注:IE6会有3px的bug
利用float+margin(fix)实现#
1 2 3 4 5 6 7 8 9 10 11 | < div class="parent"> < div class="left"></ div > < div class="right-fix"> < div class="right"></ div > </ div > </ div > |
1 2 3 4 5 | .left{width:100px;float:left;} .right-fix{width:100%;margin-left:-100px;float:right;} .right{margin-left:100px;} |
使用float+overflow实现
1 | .left{width:100px;float:left;}.right{overflow:hidden;} |
overflow:hidden,触发bfc模式,浮动无法影响,隔离其他元素,IE6不支持,左侧left设置margin-left当作left与right之间的边距,右侧利用overflow:hidden 进行形成bfc模式
如果我们需要将两列设置为等高,可以用下述方法将“背景”设置为等高,其实并不是内容的等高
1 | .left{width:100px;float:left;}.right{overflow:hidden;}.parent{overflow:hidden;}.left,.right{padding-bottom:9999px;margin-bottom:-9999px;} |
使用table实现
1 | .parent{display:table;table-layout:fixed;width:100%;}.left{width:100px;}.right,.left{display:table-cell;} |
右列定宽,左列自适应#
实用float+margin实现
1 | .parent{background:red;height:100px;margin:0 auto;}.left{background:green;margin-right:-100px;width:100%;float:left;}.right{float:right;width:100px;background:blue;} |
使用table实现
1 | .parent{display:table;table-layout:fixed;width:100%;}.left{display:table-cell;}.right{width:100px;display:table-cell;} |
两列定宽,一列自适应#
基本html结构为父容器为parent,自容器为left,center,right.其中,left,center定宽,right自适应
利用float+margin实现
1 | .left,.center{float:left:width:200px;}.right{margin-left:400px;} |
利用float+overflow实现
1 | .left,.center{float:left:width:200px;}.right{overflow:hidden;} |
利用table实现
1 | .parent{display:table;table-layout:fixed;width:100%;}.left,.center,.right{display:table-cell;}.left,.center{width:200px;} |
两侧定宽,中栏自适应#
利用float+margin实现
1 | .left{width:100px;float:left;}.center{float:left;width:100%;margin-right:-200px;}.right{width:100px;float:right;} |
利用table实现
1 | .parent{width:100%;display:table;table-layout:fixed}.left,.center,.right{display:table-cell;}.left{width:100px;}.right{width:100px;} |
一列不定宽,一列自适应#
利用float+overflow实现
1 | .left{float:left;}.right{overflow:hidden;} |
利用table实现
1 | .parent{display:table;table-layout:fixed;width:100%;}.left{width:0.1%;}.left,.right{display:table-cell;} |
多列等分布局#
多列等分布局常出现在内容中,多数为功能的,同阶级内容的并排显示等。
html结构如下所示
1 | < div class="parent"> < div class="column">1</ div > < div class="column">1</ div > < div class="column">1</ div > < div class="column">1</ div ></ div > |
实用float实现
1 | .parent{margin-left:-20px}/*假设列之间的间距为20px*/.column{float:left;width:25%;padding-left:20px;box-sizing:border-box;} |
利用table实现
1 | .parent-fix{margin-left:-20px;}.parent{display:table;table-layout:fixed;width:100%;}.column{display:table-cell;padding-left:20px;} |
九宫格布局#
使用table实现
1 2 3 4 5 | < div class="parent"> < div class="row">< div class="item"></ div >< div class="item"></ div >< div class="item"></ div ></ div > < div class="row">< div class="item"></ div >< div class="item"></ div >< div class="item"></ div ></ div > < div class="row">< div class="item"></ div >< div class="item"></ div >< div class="item"></ div ></ div > </ div > |
1 2 3 | .parent{display:table;table-layout:fixed;width:100%;} .row{display:table-row;} .item{display:table-cell;width:33.3%;height:200px;} |
全屏布局#
利用绝对定位实现
1 2 3 4 5 6 7 8 9 10 11 | < div class="parent"> < div class="top">top</ div > < div class="left">left</ div > < div class="right">right</ div > < div class="bottom">bottom</ div > </ div > |
1 2 3 4 5 6 7 8 9 | html,body,parent{height:100%;overflow:hidden;} .top{position:absolute:top:0;left:0;right:0;height:100px;} .left{position:absolute;top:100px;left:0;bottom:50px;width:200px;} .right{position:absolute;overflow:auto;left:200px;right:0;top:100px;bottom:50px;} .bottom{position:absolute;left:0;right:0;bottom:0;height:50px;} |
vw与vh的使用
响应式布局的单位我们第一时间会想到通过rem单位来实现适配,但是它还需要内嵌一段脚本去动态计算跟元素大小。
比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | (function (doc, win) { let docEl = doc.documentElement let resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize' let recalc = function () { var clientWidth = docEl.clientWidth if (!clientWidth) return docEl.style.fontSize = 14 * (clientWidth / 320) + 'px' } if (!doc.addEventListener) return win.addEventListener(resizeEvt, recalc, false) doc.addEventListener('DOMContentLoaded', recalc, false) })(document, window) |
那有没有一个单位不需要JS和CSS耦合在一起的单位?答案是有的,那就是vw/vh
vw = view width
vh = view height
这两个单位是CSS3引入的,以上称为视口单位允许我们更接近浏览器窗口定义大小。
视口单位(Viewport units)
什么是视口
A:Peter-Paul Koch(”PPK大神”)提出视口的解释是:在桌面端,视口指的是在桌面端,指的是浏览器的可视区域;而在移动端,它涉及3个视口:Layout Viewport(布局视口),Visual Viewport(视觉视口),Ideal Viewport(理想视口)。
视口单位中的“视口”,桌面端指的是浏览器的可视区域;移动端指的就是Viewport中的Layout Viewport。
vh/vw与%区别
单位 | 解释 |
---|---|
vw | 1vw = 视口宽度的1% |
vh | 1vh = 视口高度的1% |
vmin | 选取vw和vh中最小的那个 |
vmax | 选取vw和vh中最大的那个 |
1 | 比如:浏览器视口尺寸为370px,那么 1vw = 370px * 1% = 6.5px(浏览器会四舍五入向下取7) |
vh/vw与%区别在于
单位 | 依赖于 |
---|---|
% | 元素的祖先元素 |
vh/vw | 视口的尺寸 |
兼容性问题
在移动端 iOS 8 以上以及 Android 4.4 以上获得支持,并且在微信 x5 内核中也得到完美的全面支持。
仅使用vw作为CSS单位#
使用 vw 单位作为唯一应用的一种 CSS 单位的这种做法下
1.根据设计稿的尺寸转换为vw单位(SASS函数编译)
1 2 3 4 5 | //iPhone 6尺寸作为设计稿基准 $vm_base: 375; @function vm($px) { @return ($px / 375) * 100vw; } |
2.无论是文本还是布局高宽、间距等都使用 vw
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | < div class="mod_nav"> < nav class="mod_nav_list" v-for="n in 5"> < a href="#" class="mod_nav_list_item"> < span class="mod_nav_list_item_logo"> < img src="http://jdc.jd.com/img/80"> </ span > < p class="mod_nav_list_item_name">导航入口</ p > </ a > </ nav > </ div > .mod_nav { background: #fff; &_list { display: flex; padding: vm(15) vm(10) vm(10); &_item { flex: 1; text-align: center; font-size: vm(10); &_logo { display: block; margin: 0 auto; width: vm(40); height: vm(40); img { display: block; margin: 0 auto; max-width: 100%; } } &_name { margin-top: vm(2); } } } } |
会得到这样的效果
不同的手机型号都可以正常显示,这一点非常棒
最优做法——搭配vw和rem#
使用vm作为css单位代码量确实减少很多,但是你会发现它是利用视口单位实现,依赖于视口大小而自动缩放,失去了最大最小宽度的限制。
所以,我们需要结合rem单位来实现布局,而rem正好可以动态改变根元素大小,做法是:
-
给根元素大小设置vw–动态改变大小。
-
限制根元素font-size的最大最小值,配合bosy加上最大最小宽度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | // rem 单位换算:定为 75px 只是方便运算,750px-75px、640-64px、1080px-108px,如此类推 $vm_fontsize: 75; // iPhone 6尺寸的根元素大小基准值 @function rem($px) { @return ($px / $vm_fontsize ) * 1rem; } // 根元素大小使用 vw 单位 $vm_design: 750; html { font-size: ($vm_fontsize / ($vm_design / 2)) * 100vw; // 同时,通过Media Queries 限制根元素最大最小值 @media screen and (max-width: 320px) { font-size: 64px; } @media screen and (min-width: 540px) { font-size: 108px; } } // body 也增加最大最小宽度限制,避免默认100%宽度的 block 元素跟随 body 而过大过小 body { max-width: 540px; min-width: 320px; } |
width、height中auto与100%与固定值的区别
(1)width、height使用固定值是一定会显示的,但是除非是小型项目或是特殊情况,最好不要使用固定值。不利于响应式开发,当从移动端看页面就会非常不美观
(2)不设置width、height时默认为auto,当position不同时显示效果不同,浮动可能会导致其不显示,需要清除浮动。
width:auto表示宽度是可变动的,这个div的所有部分(content+margin+padding+border)相加为父元素的width大小。
height:auto表示高度可变动的,如果div设置了auto但是却没有显示有下面几种可能: ①cotent里没有能将其height支撑的子元素 ②由于定位和浮动导致其不显示,清除浮动或修改定位
(3)width、height强制将子元素充满父元素的content。width:100%子元素的width值为父元素的width值,加margin时不改变子元素width值大小,而是溢出父元素。height:100%不显示的原因可能为没有设置父元素的height,可以通过将父元素的height设为固定值或是将父元素及父元素的父元素设置height:100%显示。auto与子元素有关,100%与父元素有关
height:100%的案例分析#
这里需要得知100%是以父元素为标准,div的父元素为body,body的父元素为html。
1.没有子元素,使用*{margin:0;padding:0}
依然是默认页面的width,height为0
2.没有使用*{margin:0;padding:0}且没有子元素,width、height为100%
由于浏览器默认样式,如果不使用*{margin:0;padding:0}body就会有默认边距
3.将父元素body及html的height设为100%
(1) 只将body的height设为100%,height依然为0
(2) 将html的height设为100%
(3)html、body的height设为100%,div的width、height改为auto。
如果html、body的height设为100%,但是div的height为auto,依然是无法显示出背景的
html、css、js文件加载顺序及执行情况
HTML页面加载和解析流程
1 2 3 4 5 6 7 8 9 10 11 | 用户输入网址(假设是个html页面,并且是第一次访问),浏览器向服务器发出请求,服务器返回html文件。 浏览器开始载入html代码,发现< head >标签内有一个< link >标签引用外部CSS文件。 浏览器又发出CSS文件的请求,服务器返回这个CSS文件。 浏览器继续载入html中< body >部分的代码,并且CSS文件已经拿到手了,可以开始渲染页面了。 浏览器在代码中发现一个< img >标签引用了一张图片,向服务器发出请求。此时浏览器不会等到图片下载完,而是继续渲染后面的代码。 服务器返回图片文件,由于图片占用了一定面积,影响了后面段落的排布,因此浏览器需要回过头来重新渲染这部分代码。 浏览器发现了一个包含一行Javascript代码的< script >标签,赶快运行它。 Javascript脚本执行了这条语句,它命令浏览器隐藏掉代码中的某个< style >(style.display=”none”)。杯具啊,突然就少了这么一个元素,浏览器不得不重新渲染这部分代码。 终于等到了</ html >的到来,浏览器泪流满面…… 等等,还没完,用户点了一下界面中的“换肤”按钮,Javascript让浏览器换了一下<link>标签的CSS路径。 浏览器召集了在座的各位< div >< span >< ul >< li >们,“大伙儿收拾收拾行李,咱得重新来过……”,浏览器向服务器请求了新的CSS文件,重新渲染页面。 |
总结:
1.总的来说就是按照html文档的顺序加载
2.还有就是最好将无论内部或是外部JS文件放到所有html内容之后,这样会令用户感觉页面加载速度变快了,否则如果将所有外部文件(包括css和JS)引用都放到<head>中,意味着必须等到全部的JS代码都被下载解析和执行完毕后,才能开始呈现页面的内容(当浏览器遇到<body>),这样会导致呈现页面时出现明显的延迟,二延迟期间的浏览器窗口将是一片空白。
补充
1 2 3 4 5 6 | < head lang="en"> < meta charset="utf-8"> < title ></ title > < link rel="stylesheet" href="css/*.css"> < script src="js/*.js></ script > </ head > |
DOM文档的加载顺序是由上而下的顺序加载;
1、DOM加载到link标签
css文件的加载是与DOM的加载并行的,也就是说,css在加载时Dom还在继续加载构建,而过程中遇到的css样式或者img,则会向服务器发送一个请求,待资源返回后,将其添加到dom中的相对应位置中;
2、DOM加载到script标签
由于js文件不会与DOM并行加载,因此需要等待js整个文件加载完之后才能继续DOM的加载,倘若js脚本文件过大,则可能导致浏览器页面显示滞后,出现“假死”状态,这种效应称之为“阻塞效应”;会导致出现非常不好的用户体验;
而这个特性也是为什么在js文件中开头需要$(document).ready(function(){})或者(function(){})或者window.onload,即是让DOM文档加载完成之后才执行js文件,这样才不会出现查找不到DOM节点等问题;
js阻塞其他资源的加载的原因是:浏览器为了防止js修改DOM树,需要重新构建DOM树的情况出现;
3、解决方法
前提,js是外部脚本;
在script标签中添加 defer=“ture”,则会让js与DOM并行加载,待页面加载完成后再执行js文件,这样则不存在阻塞;
在scirpt标签中添加 async=“ture”,这个属性告诉浏览器该js文件是异步加载执行的,也就是不依赖于其他js和css,也就是说无法保证js文件的加载顺序,但是同样有与DOM并行加载的效果;
同时使用defer和async属性时,defer属性会失效;
可以将scirpt标签放在body标签之后,这样就不会出现加载的冲突了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架