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,块级元素 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:应用于定位元素,可以改变元素相互覆盖的顺序; 取值越高的元素离用户越近,并覆盖值低的元素;可以取所有整数,包括负数

分析脱离文本流产生的css层级问题

什么是CSS规则之层叠上下文

若两条规则具有相同的权值、起源及特殊性,那在样式表中最后出现的规则优先。
任何位于文档中的规则都比引入的规则优先 

注意点

元素设置了position属性后,这个定位元素的z-index就会自动生效,此时它的z-index值就是默认的auto,也就是0。

层级不取小数

层级一样,后面的盒子比前面的盒子的层级高

浮动或者标准流的盒子,后面的盒子比前面的层级高

解决子级对象使用css float浮动 而父级div不能自适应高度,不能被父级内容撑开解决方法,父级div没有高度解决方法

最外层的父级DIV不能自适应高度-不能随对象撑开没有高度

当在对象内的盒子使用了float后,导致对象本身不能被撑开自适应高度,这个是由于浮动产生原因。

如何解决父div对象自适应高度,方法有三种

<!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>  

问题截图:

方法一:对父级设置固定高度

<!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清除浮动对象

<!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样式即可

<!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不能自适应高度,不能随父内容多少而自适应高度没有高度,但是要注意一旦子元素的大小超过父容器的大小,就会出显示问题

方法四:浮动的父容器

另一种思路是,索性将父容器也改成浮动定位,这样它就可以带着子元素一起浮动了

<div style="float:left;">
<div style="float:left;width:45%;"></div>
<div style="float:right;width:45%;"></div>
</div>

这种方法不用修改HTML代码,但是缺点在于父容器变成浮动以后,会影响到后面元素的定位,而且有时候,父容器是定位死的,无法变成浮动

方法五:After伪类清除浮动(最推荐)

<!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> 

最完整的清浮动操作

/* 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/

.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不能正确显示

vw与vh的使用

响应式布局的单位我们第一时间会想到通过rem单位来实现适配,但是它还需要内嵌一段脚本去动态计算跟元素大小。 
比如:

(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中最大的那个
比如:浏览器视口尺寸为370px,那么 1vw = 370px * 1% = 6.5px(浏览器会四舍五入向下取7)

vh/vw与%区别在于

单位 依赖于
% 元素的祖先元素
vh/vw 视口的尺寸

兼容性问题

在移动端 iOS 8 以上以及 Android 4.4 以上获得支持,并且在微信 x5 内核中也得到完美的全面支持。

仅使用vw作为CSS单位

使用 vw 单位作为唯一应用的一种 CSS 单位的这种做法下

1.根据设计稿的尺寸转换为vw单位(SASS函数编译)

//iPhone 6尺寸作为设计稿基准
$vm_base: 375;
@function vm($px) {
   @return ($px / 375) * 100vw;
}

2.无论是文本还是布局高宽、间距等都使用 vw

<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正好可以动态改变根元素大小,做法是:

  1. 给根元素大小设置vw–动态改变大小。

  2. 限制根元素font-size的最大最小值,配合bosy加上最大最小宽度。

// 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:100%是相对你上层的标签而言,基本上跟你上层便签一样的宽度,但是width:auto是根据你这个标签里面的元素的宽度来自动调节本身的宽度 

html、css、js文件加载顺序及执行情况

HTML页面加载和解析流程 

用户输入网址(假设是个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>),这样会导致呈现页面时出现明显的延迟,二延迟期间的浏览器窗口将是一片空白。

补充

<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标签之后,这样就不会出现加载的冲突了。

猜你喜欢

转载自www.cnblogs.com/596014054-yangdongsheng/p/10131033.html