CSS三种布局模型及布局的一些注意事项

流动模型(Flow) /标准流

  • 流动(Flow)模型是默认的网页布局模式。也就是说网页在默认状态下的 HTML 网页元素都是根据流动模型来分布网页内容的。流动布局模型具有2个比较典型的特征:
  1. 第一点,块状元素都会在所处的包含元素内自上而下按顺序垂直延伸分布,因为在默认状态下,块状元素的宽度都为100%。实际上,块状元素都会以行的形式占据位置。
  2. 第二点,在流动模型下,行内元素都会在所处的包含元素内从左到右水平分布显示.
  3. 每个元素都是一个和模型,包括:边距,边框,填充,和实际内容。 盒模型
盒模型组成部分说明
Margin(外边距)外边距是透明的(不可见)。可以设置四个方向的距离
Border(边框)围绕在内边距和内容外的边框。可以设置是个方向的宽度/高度,样式,颜色
Padding(内边距/填充)内容周围的区域,内边距是透明的(不可见)。可以设置四个方向的距离
Content(内容)盒子的内容,显示文本和图像。设置width,height都是设置内容的宽高
  • 注意一般要就计算可见区域的宽高不包含margin的,因为margin不可见;宽度=width+padding-left+padding-right+border-left+border-right;高度=height+padding-top+padding-bottom+border-top+border-bottom;

  • 注意:标准流使我们网页布局中最稳定的一种结构

浮动模型 (Float)

  • 任何元素在默认情况下是不能浮动的,但可以用 CSS 定义为浮动;
  • float常跟属性值left、right、none;float:none 不使用浮动,float:left 靠左浮动,float:right 靠右浮动,float:none不浮动;是脱离标准流的第一种方式;
  • 我们要浮动的目的:就是可以把多个块级元素放到想要的一行上。
  • 示例:
    div {
    	padding: 1px solid red;
    	background-color: yellow;
    }
    .left {
    	float: left;
    	width: 100px;
    	height: 100px;
    	background-color: red;
    }
    .right {
    	float: right;
    	width: 100px;
    	height: 100px;
    	background-color: blue;
    }
    
    <div>这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是呵呵哒<div class="left">左浮动1</div>一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签<div class="right">右浮动1</div>
    这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签
    <div class="left">左浮动2</div>
    <span class="right">右浮动2</span>
    这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签
    这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签这是一个块级标签
    </div>
    <br>
    <div>
    块级标签
    </div>
    <div class="left">左浮动3</div>
    <span class="right">右浮动3</span>
    
    浮动示例
  • 可以看出float会使得元素变成行内块级元素(inline-block);但是一般的行内块级元素会有文字特性(如果标签之间有空格包括换行会有空格),但是float不会参数空格;
  • 如果连续多个标签使用float,如果设置的是left会按从左往右排列;如果设置的是right,会按从右往左排列.
  • 浮动元素的定位还是基于正常的文档流,然后从文档流中抽出并尽可能远的移动至左侧或者右侧,文字内容会围绕在浮动元素周围。它只是改变了文档流的显示,而没有脱离文档流,理解了这一点,就很容易弄明白什么时候用定位,什么时候用浮动了。

层模型(Layer)

*层类型:层布局模型就像是图像软件PhotoShop中非常流行的图层编辑功能一样,每个图层能够精确定位操作.(简单来说层模型会使得一些非父子元素重叠)

  • 层模型有三种形式:
    1、相对定位(position: relative)
    2、绝对定位(position: absolute)
    3、固定定位(position: fixed)

  • 相对定位: 如果想为元素设置层模型中的相对定位,需要设置position:relative(表示相对定位),它通过eft、right、top、bottom属性确定元素在正常文档流中的偏移位置相对于以前的位置移动,偏移前的位置保留不动。在使用相对定位时,就算元素被偏移了,但是他仍然占据着它没偏移前的空间。示例如下
    设置相对定位之前:

    .f {
    	width: 50%;
    	margin-left: 25%;
    	background-color: yellow;
    }
    .f div {
    	width: 100px;
    	height: 100px;
    	background-color: red;
    	border: 3px solid blue;
    }
    
    <div class="f">
    	<div>1</div>
    	<span>这是一个行内标签</span>
    	<div class="s">2</div>
    	<div>3</div>
    </div>
    

    设置相对定位之前
    设置相对定位之后

    	.f {
    	width: 50%;
    	margin-left: 25%;
    	background-color: yellow;
    	/*height: 100px;*/
    }
    .f div {
    	width: 100px;
    	height: 100px;
    	background-color: red;
    	border: 3px solid blue;
    }
    /*给.s设置相对定位*/
    .f .s {
    	position: relative;	
    	left: 90px;
    	top: -50px;
    }
    

    设置相对定位之后
    可以看出设置相对定位之后,2标签之前的位置大小没动,相对之前的位置网上移动50px,向右移动90px;b并且将1和span标签覆盖了一部分;但并不影响其他标签布局;

  • 绝对定位:如果想为元素设置层模型中的绝对定位,需要设置position:absolute(表示绝对定位)将元素从文档流中拖出来,然后使用left、right、top、bottom属性相对于其最接近的一个具有定位属性的父包含块进行绝对定位如果不存在这样的包含块(就是它前面的div并没有设置定位的属性),则相对于body元素,即相对于浏览器窗口被设置了绝对定位的元素,在文档流中是不占据空间的如果某元素设置了绝对定位,那么它在文档流中的位置会被删除;(也就说绝对定位属性不保留文档流中的原来位置);我们可以通过z-index来设置它们的堆叠顺序 。

    绝对定位使元素脱离文档流,因此不占据空间 ,普通文档流中元素的布局就当绝对定位的元素不存在时一样,仍然在文档流中的其他元素将忽略该元素并填补他原先的空间。因为绝对定位的框与文档流无关,所以它们可以覆盖页面上的其他元素。  
    示例1:(html文件同上,下面主要修改了css文件);

    .f {
    	width: 50%;
    	margin-left: 25%;
    	background-color: yellow;
    }
    .f div {
    	width: 100px;
    	height: 100px;
    	background-color: red;
    	border: 3px solid blue;
    }
    .f .s {
    	position: absolute;
    	left: 100px;
    	top: 20px;
    }
    

    在这里插入图片描述
    可以看出2已经脱离的文档流,对body进行了绝对定位(因为没有设置其直接父标签的定位属性,也就是说直接父标签不具有定位功能),是相对于body的左边距离为100px,顶部为20px;并且脱离原来的文档流,之前的位置也不再保留.
    示例2:设置父标签可以定位;

    .f {
    	width: 50%;
    	margin-left: 25%;
    	background-color: yellow;
    	position: relative;
    }
    .f div {
    	width: 100px;
    	height: 100px;
    	background-color: red;
    	border: 3px solid blue;
    }
    .f .s {
    	position: absolute;
    	left: 100px;
    	top: 20px;
    }
    

    父标签有定位属性
    可以看出虽然父标签设置的是相对定位,但是说明父标签有定位功能了(可以理解设置了一个定位参照物);所以是相对于父标签的顶部为20px,左边为100px.

  • 固定定位:如果想为元素设置层模型中的固定定位,需要设置position:fixed(表示固定定位),`它的相对移动的坐标是视图(屏幕内的网页窗口)本身。由于视图本身是固定的,它不会随浏览器窗口的滚动条滚动而变化,除非你在屏幕中移动浏览器窗口的屏幕位置,或改变浏览器窗口的显示大小,因此固定定位的元素会始终位于浏览器窗口内视图的某个位置,不会受文档流动影响。(也就是说他的参照物就是浏览器窗口body).

    示例:html代码不变

    .f {
    	width: 50%;
    	margin-left: 25%;
    	background-color: yellow;
    	position: relative;
    	
    }
    .f div {
    	width: 100px;
    	height: 100px;
    	background-color: red;
    	border: 3px solid blue;
    }
    .f .s {
    	position: fixed;
    	left: 100px;
    	top: 20px;
    }
    

固定定位
可以看出虽然设置了父标签的定位属性,但对固定定位来说并没设么影响;他始终是相对于网页定位的;

  • 总结一下:
    relative相对定位是相对于自己进行定位,也就是自己是参照物,既然作为参照物体所以原始的位置大小需要得到保留;
    fixed固定定位是相对一真个网页定位,虽然网页的大小可以改变,但是它相对网页的水平和垂直方向的距离是固定的;参照物是别人所以就不需要保留自己原来位置;
    absolute绝对定位,相对于前两种定位参照物是固定的,决对定位更加灵活,因为可以指定参照物,只要是父类标签都可以指定为参照物,如果所有父标签都不设置定位就是body为参照物(这时类似于固定定位);
    relative相对定位fixed固定定位的标签都会在屏幕最上方;absolute绝对定位默认也是在最上方,但是绝对定位可以通过设置z-index的值来确定上下顺序,值越大就越在最上方;

z-index

  • 利用z-index,可以改变元素相互覆盖的顺序。
    z-index是针对网页显示中的一个特殊属性。因为显示器是显示的图案是一个二维平面,拥有x轴和y轴来表示位置属性。为了表示三维立体的概念如显示元素的上下层的叠加顺序引入了z-index属性来表示z轴的区别。表示一个元素在叠加顺序上的上下立体关系。
    z-index值较大的元素将叠加在z-index值较小的元素之上。对于未指定此属性的定位对象,z-index 值为正数的对象会在其之上,而 z-index 值为负数的对象在其之下。
  • z-index属性适用于定位元素(position属性值为 relative 或 absolute 或 fixed的对象),用来确定定位元素在垂直于显示屏方向(称为Z轴)上的层叠顺序,也就是说如果元素是没有定位的,对其设置的z-index会是无效的
  • 示例
    .f {
    	width: 50%;
    	margin-left: 25%;
    	background-color: yellow;
    	position: relative;
    }
    .f div {
    	width: 100px;
    	height: 100px;
    	background-color: red;
    	border: 3px solid blue;
    }
    .f .s {
    	position: absolute;
    	left: 90px;
    	top: 20px;
    }
    .f .s1 {
    	position: relative;
    	z-index:1; 
    }
    
    ```html
    <div class="f">
      	<div class="s1">1</div>
      	<span>这是一个行内标签</span>
      	<div class="s">2</div>
      	<div>3</div>
      </div>
    ```
    
    在这里插入图片描述
    可以看出只有.f .s1中设置了定位position: relative;并且设置z-index:1;,1标签才会在最上面,二者缺一不可.

定位 position

  • position属性指定了元素的定位类型。

  • position 属性的五个值:

    描述
    static静态定位,HTML元素的默认值,即没有定位,遵循正常的文档流对象。静态定位的元素不会受到 top, bottom, left, right影响。
    relative相对对位
    fixed固定定位
    absolute绝对定位
    sticky粘性定位,基于用户的滚动位置来定位。依赖于用户的滚动,在 position:relative 与 position:fixed 定位之间切换。它的行为就像 position:relative; 而当页面滚动超出目标区域时,它的表现就像 position:fixed;,它会固定在目标位置。元素定位表现为在跨越特定阈值前为相对定位,之后为固定定位。这个特定阈值指的是 top, right, bottom 或 left 之一,换言之,指定 top, right, bottom 或 left 四个阈值其中之一,才可使粘性定位生效。否则其行为与相对定位相同。
    inherit继承定位:规定应该从父元素继承 position属性的值
    initial最初定位,类似于static;不同的是initial 关键字可用于任何 HTML 元素上的任何 CSS 属性,不是postion特有的;如:background-color: yellow initial;就是默认的背景颜色,黄色不生效.
    unset未设置的定位,如果该属性的默认属性是 继承属性(例如字体相关的默认属性基本都是继承),该值等同于 inherit;如果该属性的默认属性 不是继承属性(例如pisition的默认属性为static),该值等同于 initial
    • static静态定位就是没有定位,很好理解,中间3个上面层模型讲过,这里举例说明一下sticky粘粘定位;
    .sticky {
    	  position: sticky;
    	  top: 0;
    	  padding: 5px;
    	  background-color: #cae8ca;
    	  border: 2px solid #4CAF50;
    	  font-size: 50px;
    	}
    	
    	p {
    		font-size: 30px;
    	}
    
    <div class="sticky">我是粘性定位第1组</div>
    <div style="padding-bottom:1000px">
      <p>滚动我</p>
      <p>来回滚动我</p>
      <p>滚动我</p>
      <p>来回滚动我</p>
      <p>滚动我</p>
      <p>来回滚动我</p>
    </div>
    <div class="sticky">我是粘性定位第2组!</div>
    <div style="padding-bottom:1000px">
      <p>滚动我</p>
      <p>来回滚动我</p>
      <p>滚动我</p>
      <p>来回滚动我</p>
      <p>滚动我</p>
      <p>来回滚动我</p>
    </div>
    <div class="sticky">我是粘性定位第3组!</div>
    <div style="padding-bottom:1000px">
      <p>滚动我</p>
      <p>来回滚动我</p>
      <p>滚动我</p>
      <p>来回滚动我</p>
      <p>滚动我</p>
      <p>来回滚动我</p>
    </div>
    <div class="sticky">我是粘性定位第4组!</div>
    <div style="padding-bottom:1000px">
      <p>滚动我</p>
      <p>来回滚动我</p>
      <p>滚动我</p>
      <p>来回滚动我</p>
      <p>滚动我</p>
      <p>来回滚动我</p>
    </div>
    

    粘粘属性
    可以看出粘粘定位属性,在移动端还是挺常见的,类似于iOS分组的UITableView;

    • 继承定位示例
    .f {
    	width: 50%;
    	margin-left: 25%;
    	background-color: yellow;
    	position: relative;
    }
    .f div {
    	width: 100px;
    	height: 100px;
    	background-color: red;
    	border: 3px solid blue;
    }
    .f .s {
    	position: inherit;
    	left: 90px;
    	top: 20px;
    }
    
    <div class="f">
    	<div class="s1">1</div>
    	<span>这是一个行内标签</span>
    	<div class="s">2</div>
    	<div>3</div>
    </div>
    

    继承定位
    可以看出2继承了父类的相对定位.

元素的影藏

  • 元素影藏有两个属性可以设置,display: none;visibility: hidden;;
  • display: none;:元素影藏的同时,元素不再占有原来的位置和空间,会影响其他元素的布局;
  • visibility: hidden;:元素影藏的同时,元素还占有原来的位置和空间,不会影响其他元素的布局;
  • 两者都是影藏元素,元素本身还在;显示的话display: block;,display: inline;,display: inline-block;,display: table;等;visibility: visible;.

margin塌陷,margin合并

margin塌陷
  • margin塌陷:父子嵌套的元素,垂直方向的margin会粘合到一起,选最大的值。
    正常情况下,父级元素应该相对浏览器进行定位,子级相对父级定位.
    但由于margin的塌陷,父级相对浏览器定位.而子级没有相对父级定位,子级相对父级,就像坍塌了一样.(子元素和父元素之间没有了margin).

    body {
    	background-color: green;
    }
    .wrapper{
    	 width:200px;
    	 height:200px;
         margin-top:30px;
         margin-left: 100px;
         background-color:red;
     }
     .box{
     	width:100px;
        height:100px;
        margin-top: 100px;
        margin-left: 100px;
        background-color:#eee;
        opacity:0.8;
     }
     .box2{
     	width:50px;
        height:50px;
        margin-top: 50px;
        margin-left: 50px;
        background-color:black;
        opacity:0.8;
     }
    
    <div class="wrapper">
        <div class="box">
        	<div class="box2"></div>
        </div>
    </div>
    

    margin塌陷
    可以看出wrappermargin-top是100px(取了3个div的最大margin-top值),boxbox2margin-top不见了;

  • margin塌陷解决方法:

    1. 给父级设置上边框上内边距(不建议使用,因为毕竟添加了1px,改变了原有的设计)
    .wrapper{
      	 width:200px;
      	 height:200px;
           margin-top:30px;
           margin-left: 100px;
           background-color:red;
           /*添加上边框*/
           border-top:1px solid black;
       }
       .box{
       	width:100px;
          height:100px;
          margin-top: 100px;
          margin-left: 100px;
          background-color:#eee;
          opacity:0.8;
          /*添加上内边距*/
          padding-top:1px;
       }
    

    margin塌陷解决方法1
    2.触发bfc(block format context块级格式上下文),改变父级的渲染规则,改变父级的渲染规则有以下四种方法,给父级盒子添加:

    position:absolute;
    display:inline-block;
    float:left/right;
    overflow:hidden;

    上面4个属性设置一个都可以触发bfc,但也会引发新的问题,我们需要根据需求来设置相关属性;

margin合并
  • margin合并:兄弟元素,垂直方向margin会合并到一起(这里说的合并到一起并不是相加,而是取了最大值,理论上应该是相加的),选最大的值;
    body {
    	background-color: green;
    }
    
    div {
    	width: 100px;
    	height: 100px;
    	margin-left: 100px;
    	background-color: red;
    }
    .b1 {
    	margin-bottom: 100px;
    }
    .b2 {
    	margin-top: 50px;
    }
    
    <div class="b1"></div>
    <div class="b2"></div>
    
    margin合并
    可以给给两个都加一层父级再加bfc解决;但是一般不这么解决(毕竟改变了布局结构),直接设置上面的div的margin-bottom: 150px;或者下面div的margin-top: 150px;即可.

清除浮动

  • Float浮动流可以让标签从左往右排列或从右往左排列;

  • 注意点:
    1、浮动流中没有居中对齐, 也就是没有float:center这个取值
    2、在浮动流中是不可以使用margin: 0 auto;

  • 浮动元素在哪停止?
    1、当碰到父级元素的边界
    2、当碰到前面有浮动元素(紧贴在前一个浮动元素的后面)
    3、碰到前面没有浮动的元素,在该元素后面停止(注意:没有浮动的元素需为块元素)

  • 注意:如果浮动元素的父元素设置了padding值,那么浮动元素不会占用父元素的padding区域.

  • 浮动元素字围现象:浮动元素不会挡住没有浮动元素中的文字, 没有浮动的文字会自动给浮动的元素让位置,这个就是浮动元素字围现象;

  • 浮动流会带来一些问题,下面举例说明

    未设置浮动流前

    body {
    	background-color: green;
    }
    .wrapper {
     	margin-top: 100px;
    	border: 10px solid #fff;
    	background-color: yellow;
    }
    .box {
    	width: 100px;
    	height: 100px;
    	background-color: red;
    	border: 1px solid blue;
    	opacity: 0.7;
    }
    .content {
    	height: 300px;
    	background-color: #0ff;
    }
    
    	 <div class="wrapper">
     	<div class="box">1</div>
     	<div class="box">2</div>
     	<div class="box">3</div>
     	<div class="box">4</div>
     </div>
     <div class="content">
     	<h1 style="text-align: center;">标题1</h1>
     	<p>一些内容</p>
     </div>
    

    在这里插入图片描述
    给box标签设置向左浮动

    	.box {
    	float: left;
    	width: 100px;
    	height: 100px;
    	background-color: red;
    	border: 1px solid blue;
    	opacity: 0.7;
    }
    

    在这里插入图片描述
    可以看出因为标准流已被改,浮动的标签都浮动在上面,父标签的内容为空,并没有展示出背景颜色,下面的元素都会网上移,但这有时候不是我们想要的效果;那么我们需要在浮动之后要清除浮动流,切换回标准流.

  • 清除浮动流:( 因为浮动会影响标准流。所以我要根据不同情况来清除浮动。)

  1. 方法一:在最后一个浮动的盒子的后面,新添加一个空的标签。然后他可以清除浮动。(在标签结尾处加空div标签 clear:both)(优点: 通俗好理解,缺点: 增加了太多的标签)

    <div class="wrapper">
    	<div class="box">1</div>
    	<div class="box">2</div>
    	<div class="box">3</div>
    	<div class="box">4</div>
    	<p class="clear"></p>
    	</div>
    	<div class="content">
    	<h1 style="text-align: center;">标题1</h1>
    	<p>一些内容</p>
    </div>
    
    .clear {
    	clear: both;	
    }
    

清除浮动后
可以看出在wrapper的最后一个子浮动的元素添加一个空的p元是,并在该元素的css的样式中清除两边的浮动;这样就能解决浮动的问题;但是添加了新的便签改变了原来的布局,所以不建议使用.
2. Overflow清除浮动:浮动的大盒子(父级标签)再样式里面加: overflow:hidden;为了照顾ie6,我们再加上 zoom:1;(优点: 代码书写方便,缺点: 如果这个父盒子,里面还有定位,就会引起麻烦.)

 .wrapper {
			margin-top: 100px;
			border: 10px solid #fff;
			background-color: yellow;
			overflow: hidden;
			zoom:1;
		}
  1. 父级div定义 伪类:after 和 zoom
.wrapper:after{
	content:"";
	display:block;
	clear:both;
	visibility: hidden;
	height: 0;
}

.wrapper {
	margin-top: 100px;
	border: 10px solid #fff;
	background-color: yellow;
}

元素生成伪类的作用和效果相当于方法1中的原理,但是IE8以上和非IE浏览器才支持:after,zoom(IE转有属性)可解决ie6,ie7浮动问题 优点:浏览器支持好、不容易出现怪问题,写法是固定的,不理解也可以直接复制使用;主流网站推荐使用的方法.

标签嵌套规则

  • 内联标签只能嵌套内联标签;
  • 块级标签可以嵌套任意标签;
  • p标签里面不能嵌套div标签;
  • a标签里面不能嵌套a标签;
  • 设置浮动(float: left;/float: right;)和绝对定位(position: absolute;)的标签,会在内部将标签转为内联块级标签(inline-block).
  • 文本类标签(inlineinline-block)都会有文字特性,如空格问题,对齐问题(文字默认是底部对齐).
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值