004 基本视觉格式化

287 阅读9分钟

基本视觉格式化

基本框

  • 每个元素都会生成一个或多个基本框,称为元素框。margin,border,padding,content。

  • 内容的背景也会应用到内边距

  • 外边距通常透明,可以看到父元素的背景。

  • 内边距不能是负值,外边距

  • 边框没有设置颜色,将设置为内容元素的前景色。

  • body有外边距,默认为8px

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <style>
        div {
          border: 50px red solid;
          width: 0;
          height: 0;
          border-bottom-width: 0;
          border-color: red rgba(0, 0, 0, 0) rgba(0, 0, 0, 0) rgba(0, 0, 0, 0);
        }
      </style>
    </head>
    <body>
      <div></div>
    </body>
    </html>
    
    

包含块

  • 每个元素都相对于其包含块摆放。初始包含块viewport。对于正常文本流的一个元素,包含块由最近的块级祖先框、表单元格或行内祖先框(inline-box)的内容边界(content box)构成。

  • div>a>div 第三个div的祖先框是第一个div。

  • 正常流(Normal flow),文本从左向右、从上向下显示。Document flow是错误叫法。没有定位,浮动,不是flex元素,这个元素在正常流里。

  • 根元素。html。

块级元素

  • 一般的,一个元素的width被定义为从左内边界到右内边界的距离(content box)。box-sizing:content-box/border-box。

水平格式化

  • width影响的是内容区的宽度。

  • 正常流中块级元素框的水平部分总和就等于父元素的width(content)。

水平属性

  • margin-left,margin-right,padding-left,padding-right,border-left,border-right。width。这七个属性值加在一起必须是元素包含块的宽度。
  • 只有width和margin-left,margin-right三个值可以设置为auto。

使用auto

  • 零个auto: 过分受限,重置右margin (dir:rtl)会重置左边的margin
  • 三个auto:相当于左右margin都为0
  • 两个auto
    • 两个margin为auto,width为长度单位.两边的auto会计算成一样的正的值,导致元素居中。如果无法让两边的auto都为正,则left为0,right为负。无法让两个auto为0,左0右负。
    • width为auto,一个margin为auto相当于为auto的margin为0
  • 一个auto:计算得出此auto的值。当direction为ltr时,margin-left没法计算成负值。但是可以指定成负值。

负外边距

  • 通过指定负外边距获得更宽的子元素
  • 左外边距为负,不仅段落会超出div的边框,还会超出浏览器窗口本身边界。

百分数

  • 相对于包含块content-box。

  • 边框的宽度不能是百分数,只能是长度。

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <style>
        div {
          width: 100px;
          height: 100px;
          background-color: red;
          margin-left: 100px;
        }
        div:hover {
          margin-left: -20px;
          margin-right: -20px;
        }
      </style>
    </head>
    <body>
      <div></div>
    </body>
    </html>
    
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <style>
        div {
          height: 100px;
          background-color: red;
        }
    
        div:hover {
          margin-left: -20px;
          margin-right: -20px;
        }
    
        section {
          width: 100px;
          height: 100px;
          margin: auto;
          xborder: 1px solid;
    
        }
      </style>
    </head>
    
    <body>
      <section>
        <div></div>
      </section>
    </body>
    
    </html>
    
    

替换元素

  • 当替换元素为display:block时。非替换元素所有规则同时适用于替换元素。只有一个例外,width是auto,元素的宽度是内容的固有宽度。可以指定一个值覆盖这个规则。如果一个替换元素的width不等于其固有宽度,那么height值也会成比例变化。
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    .a {
      display: block;
      width: calc(100% - 60px);
      /* -左右两侧要有空格 */
      box-sizing: border-box;
      border: 5px solid;
      padding: 30px;
      margin: 30px;
    }

    .b {
      display: block;
      width: 100%;
      box-sizing: border-box;
      border: 5px solid;
      padding: 30px;
    }

    nav {
      margin: 30px;
    }

    .c {
      display: block;
      width: 100%;
      padding: 30px;
    }

    header {
      border: 5px solid;
      padding: 30px;
      margin: 30px;
    }
  </style>
</head>

<body>
  <iframe class="a" src="https://www.baidu.com/" frameborder="0"></iframe>
  <nav><iframe class="b" src="https://www.baidu.com/" frameborder="0"></iframe></nav>
  <header><iframe class="c" src="https://www.baidu.com/" frameborder="0"></iframe></header>
</body>

</html>

垂直格式化

  • 可以对任意块级元素设置显示高度。
  • 设高度小于显示内容所需的高度 overflow:auto|scroll
  • 包含块只有一个子元素的时候,这七个属性的值必须等于元素包含块的height。-
  • height和margin-top,margin-bottom可以设置为auto。
  • 正常流中块元素margin-top,margin-bottom设置为auto,他们会设置为0。

百分数高度

  • height是相对于包含块高度的百分数
<div style="height: 6em;">
  <p style="height:50%;">
     Half as tall
  </p>
</div>
<!-- 继承的是父元素的计算值 6*父元素字大小 p内字大小改变不影响高度 -->
  • margin-top和margin-bottom,padding-top,padding-bottom的百分比是相对于父元素的**==宽度==**

    因为height改变,总高度改变,,占比又会改变。

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <style>
        div {
          border: 5px solid;
        }
    
        p {
          margin: 0;
          background-color: red;
          padding-top: 25%;
          padding-bottom: 25%;
        }
      </style>
    </head>
    
    <body>
      <div>
        <p></p>
        <!-- 2:1矩形 -->
      </div>
    </body>
    
    </html>
    
    
  • 如果没有显式声明包含块的height,百分数高度会重置为auto。

  • ==body没有设置高度,直接子元素用百分比无效==

height设置为auto

  • 如果块级正常流元素设置为height :auto,显示其高度将恰好足以包含其内联内容。高度为auto,会在段落上加一个边框,并认为没有内边距。

  • 如果块级正常流元素的高度为auto,没有边框和内边距,而且第一个和最后一个是块级子元素。默认高度将是从最高块级子元素的外边框边界到最低块级子元素外边框边界之间的距离。(border)

  • 如果块级元素有上内边距或下内边距,或者有上下边框,其高度则是从其最高子元素的上外边距边界到最低子元素的下外边距边界之间的距离。(上下内边距还要加上padding的高度 )

合并垂直外边距

  • 垂直相邻(直接在一起,没有padding,没有border)外边距会合并,这种行为只适用于外边距。==(垂直方向,常规流,块元素)==。较小的一个会被较大的一个合并。

负外边距

  • 上下都有负margin, 合并,保留绝对值较大的。

  • 正负margin会有抵消情况

  • 多个margin重合,找绝对值最大的正和负抵消

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <style>
        main {
          margin-left: 30px;
          margin-top: 20px;
          background-color: red;
          margin-bottom: -20px;
        }
    
        li {
          margin-bottom: 15px;
          margin-top: -15px;
          background-color: tan;
        }
    
        ul {
          background-color: pink;
          margin-top: -35px;
        }
    
        div {
          margin-left: 50px;
          margin-top: 30px;
        }
    
        p {
          margin: 0px;
        }
      </style>
    </head>
    
    <body>
      <main>
        <p>Lorem ipsum dolor sit amet.</p>
      </main>
    
      <div>
        <ul>
          <li>aaa</li>
          <li>bbb</li>
          <li>ccc</li>
        </ul>
      </div>
    </body>
    <!--li没有出ul因为产生了margin合并-->
    </html>
    
    
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <style>
        p {
          margin-top: -50px;
          margin-bottom: 0;
          margin-left: 10px;
          border: 1px solid magenta;
        }
      </style>
    </head>
    
    <body>
      <div style="width:420px;background-color:silver;padding: 10px;
      margin-top: 50px;border: 1px solid #000;">
        <p class="neg"> A paragraph.</p>A div.
      </div>
    </body>
    <!--没产生margin合并 div跟着p出去了-->
    </html>
    
    
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <style>
        body {
          margin: 50px;
        }
    
        div {
          background-color: red;
          border: solid #000;
          border-bottom: none;
        }
    
        p {
          background-color: olive;
          margin-left: 10px;
          margin-top: -51px;
          margin-bottom: 200px;
        }
      </style>
    </head>
    
    <body>
      <div>
        <p>Lorem ipsum dolor sit amet.</p>
      </div>
      fjkaldjflkasjk
    </body>
    
    </html>
    
    

  • 下负外边距,开始位置不变,结束位置提前。

列表项

    li {
      background-color: red;
      /* list-style-position: inside/outside 点的位置 */
      list-style: none;
      /* 去掉点 */
    }
  • 如果标志在列表项内部,相邻li表现的和块级元素一样。

  • 如果标志在内容之外,他会放在与内容做边界有一定距离的位置。

  • margin-bottom负很大

ul与li

  • ul没有padding,没有border的时候

  • ul没有padding,没有border的时候,margin为负

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    * {
      background-color: rgba(0, 0, 0, 0.1);
    }
    li {
      margin: 10px;
    }
    ul {
      margin: 0;
    }
    li:last-child {
      margin-bottom: -100px;
    }
  </style>
</head>
<body>
  <ul>
    <li>Lirem.</li>
    <li>Eum!</li>
    <li>Ipsum.</li>
  </ul>
  Lorem ipsum dolor sit amet.
</body>
</html>

  • 有border‘情况下,margin-left|top为负,margin-bottom|right为正,蓝色为marginbox,也是父元素包裹的。

  • li负值过大,会倒叙排列

ul{
  margin:0;
  padding:0;
  list-style:none;
}
<nav>hello world 请调整当前浏览器窗口大小查看效果</nav>
  <style>
    nav {
      background-color: black;
      color: white;
      padding-left: calc(50% - 300px);
      min-width: 600px;
    }
  </style>
  • BFC//block format context 特定元素触发的布局状态。它不会与自己的子元素margin重叠,自身形成了一个布局单元(布局此素内部时,不应考虑其外部,理解为完全隔离,类似iframe)。overflow:hidden。