Blog icon indicating copy to clipboard operation
Blog copied to clipboard

CSS 世界 —— 流、元素于基本尺寸

Open shenxuxiang opened this issue 6 years ago • 0 comments

流、元素于基本尺寸

在 W3C 的 HTML4 规范中,已经明确把 HTML 元素划分为 “块级元素” 和 “内联元素”。

块级元素

常见的块级元素有 <div>、<p>、<li>、<ul>、<table> 等。需要注意的是 “块级元素” 和 displayblock 的元素不是一个概念。例如,<li> 元素默认的 displaylist-item

元素的 displaytable,但是它们都是 “块级元素”,因为它们都符合块级元素的基本特征,水平方向独占一行,多个块级元素之间换行显示

正是由于 “块级元素” 具有换行的特性,因此理论上可以配合 clear 属性清除浮动带来的影响

  .clear:after {
      display: table;
      clear: both;
      content: ‘’;
  }

由于 list-item 会添加一个项目符号 【·】,所以不经常使用

如何解释 display: inline-block

为了方便理解,可以认为每个元素都有两个盒子组成,"外在盒子" 和 "内在盒子",外在盒子负责元素是否可以在一行显示还是换行显示,内在盒子负责元素的宽高和内容的呈现。按照 display 属性值的不同,

  • 值为 block 的元素的盒子实际是由外在的 “块级盒子” 和内在的 “块级盒子” 组成
  • 值为 inline-block 的元素则由外在的 “内联盒子” 和内在的 “块级盒子” 组成
  • 值为 inline 的元素则内外都是由 “内联盒子” 组成

width 作用的具体细节

width: auto (默认值就是 auto,所以一般直接省略 width 这个属性,采用默认值),具有以下几种不同的表现

  • 充分利用可用空间:块级元素的宽度默认是 100% 于父元素的。

  • 收缩和包裹:如果元素设置了浮动或者绝对定位或者 display: inline-block/inline-table 后,宽度就等于其 “内容尺寸”,称之为 “包裹性”。

  • 超出父容器宽度限制:如果元素设置了明确的 width,否则正常情况下是不会超出父容器的宽度的,但凡事总有例外。内容很长的连续的英文字符和数字,或者内联元素被设置了 white-space: nowrap,这个时候元素的 width 就会超过父容器

内部尺寸和外部尺寸
  • 内部尺寸就是元素的尺寸由内部元素的内容决定,当元素 width 表现为 “包裹性” 时,我们可以称元素的尺寸是内部尺寸。
  • 外部尺寸就是元素的尺寸由外部的容器决定。
外部尺寸分为哪几种情况
  • 正常流宽度:上面所说的第一种充分利用可用空间,其实就是 CSS 世界中的 “流体特性”,自动填充满容器的大小(水平方向,垂直方向填充不是一种默认行为,具备必要的条件才可以)。注意这种水平方向的自动填充不是想象的那么简单,它是一种 margin\padding\border\content 自动分配水平空间的机制。
  <div class="nav">
    <a href="" class="nav-a">导航1</a>
    <a href="" class="nav-a">导航2</a>
    <a href="" class="nav-a">导航3</a>
  </div>
  .nav {
    background-color: #ccc;
    width: 300px;
    height: 90px;
  }
  .nav-a {
    display: block;
    height: 29px;
    width: 100%;
    border-bottom: 1px solid;
    padding: 0 10px;
  }
  • 格式化宽度:格式化宽度仅出现在 “绝对定位模型” 中,也就是出现在 position 属性为 absolutefixed 元素中。默认情况下,绝对定位元素的宽度表现为 “包裹性”,宽度由 “内部尺寸” 决定。但是。有一种情况下宽度是由 “外部尺寸” 决定的:对于非替换元素,当 left/right,或者 top/bottom 对立方位属性值同时存在时,元素的宽高表现为 “格式化宽高”,其宽高尺寸相对最近父元素的具有定位特性(position 属性值不是 static)的祖先元素计算。
  <div class="fixed">
    <div class="fixed-box"></div>
  </div>
  .fixed {
    position: relative;
    width: 200px;
    height: 200px;
    background: #999;
  }
  .fixed-box {
    position: absolute;
    left: 0;
    right: 0;
    height: 50px;
    margin-right: 50px;
    border: 10px solid green;
    background: #f80;
  }
内部尺寸和流体特性(有三种表现形式:包裹性、首选最小宽度、最大宽度)
  • 包裹性:当元素设置 float\绝对定位\inline-block 属性时,其宽度就表现为包裹性,但是具有 “包裹性” 的元素的宽度其实还是受到了父容器宽度的限制,始终小于等于父容器的 width,并自动换行显示。

但是,如果父容器的尺寸小于 “首选最小宽度” 的时候,就不适用了。看上面的这个 demo ,内部尺寸大于容器尺寸。

  <div style="width:5px; background: #666">我</div>

如何实现文字只有一行的时候居中对其,大于一行的时候左对齐:

  <div style="width: 300px; background: #ccc; text-align: center">
      <div style="display: inline-block; text-align: left;">说的话就发货发货是否会回复 i 的回</div>
  </div>
  • 首选最小宽度:在 CSS 世界中,图片和文字的权重要远大于布局,因此,CSS 设计者们不会让图文在 width: 0 时宽度变成 0 ,此时所表现的宽度就是 “首选最小宽度”。具体表现规则:

    ** 东亚文字(如汉子)最小宽度为单个汉子的宽度;

    ** 西方文字最小宽度由特定的连续的英文字符单元决定。并不是所有的英文字符都会组成连续单元,一般会终止于 空格、短横线、问号以及其他非英文字符等;

    ** 对于图片这样的替换元素,首选最小宽度就是该元素的内容的宽度。

  <div style="width:5px; background: #666"><span>我</span></div>
  <div style="width:5px; background: #666"><span>display:inline-block</span></div>
  • 最大宽度:就是元素内容在没有换行时的最大宽度。比如说元素设置了 white-space: nowrap;
  <div style="width: 300px; background: #999; white-space: nowrap">ABCjdsfhfhhfkdshjfhfkhfkhfhjfhfhfhkhfkhfkhfjkdhsfjkdhsfjkhfjkh</div>

盒模型

盒模型包含哪些部分:margin\padding\border\content

width 属性作用在 content 部分,不含 marginpaddingborder 部分。通常我们可以设置 box-sizing 属性,来改变 wdit 作用的部分。

box-sizing 属性有三个属性值:border-box | content-box | padding-box (Firefox 曾今支持过,现在不支持了)

height 作用的具体细节

height: auto

相比于 width: auto 要简单很多。一般情况下元素设置 height: auto 后,其高度受子元素 height 的影响。有一个地方需要说明一下,就是,height: auto 也有 “外部尺寸” 特性。仅存在于 “绝对定位模型” 中,称之为 “格式化高度”。

  <div class="fixed">
    <div class="fixed-box-1"></div>
  </div>
  .fixed {
    position: relative;
    width: 200px;
    height: 200px;
    background: #999;
  }
  .fixed-box-1 {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 100px;
    height: auto;
    border: 10px solid green;
    background: #f80;
  }

注意:默认情况下块级元素的 height 的默认值就是 auto

height: 100%

对于 width 属性,就算父元素 widthauto ,其百分比值也是支持的;但是,对于 height 属性,如果父元素 height 为 auto, 只要元素在文档中,其百分比值就完全被忽略。看看下面的 demo

  <div>
    <div style="height: 50px; background: #666;">1111</div>
    <div style="height: 100%; background: #f80;">2222</div>
  </div>
如何让元素支持 height: 100% 效果??
  • 显示的设置父元素的高度
  <div style="height: 100px;">
    <div style="height: 50px; background: #666;">1111</div>
    <div style="height: 100%; background: #f80;">2222</div>
  </div>
  • 该元素使用绝对定位
  <div style="position: relative;">
    <div style="height: 50px; background: #666;">1111</div>
    <div style="height: 100%; background: #f80; position: absolute;">2222</div>
  </div>

注意:使用绝对定位后的元素,其 height 百分比的值是相对于 “包含块” 的 padding box 进行计算的,而不是 content box

  • 当父元素被设置绝对定位具有格式化高度的时候,子元素的高度也可以使用百分比值;
任意高度元素的展开收起动画技术

有一种情况,元素的 height 不是固定的一个数值,而是根据内容高度的变化而自适应,这个时候 height 就是默认值 auto。那么就不能通过 transitio 设置 height 的过渡动效。

  <div class="transf">
    <div style="height: 200px; background: #999" class="transf-con">max-height</div>
  </div>
  .transf {
    /*height: 100px;*/
    max-height: 100px;
    width: 100px;
    /*transition: height 1s ease;*/
    transition: max-height 1s ease;
    overflow: hidden;
  }
  .transf:hover {
    /*height: auto;*/
    max-height: 220px;
  }

展开后的 max-height 值,我们只需要设定为保证比展开内容高度大的值就可以。max-height 值比 height 计算值大的时候,元素的高度就是 height 属性的计算高度。

注意: 虽然 max-height 值设置的越大越安全,但是对于我们这里的动效来说,如果 max-height 值太大,动效展开就无法达到预期的效果,总是比预期的要快,同时动画收起的时候有明显的 “延迟”。所以,一般建议 max-height 使用足够安全的最小值就可以了,即使我们的效果和预期不一样,但是也不会太大,用户一般情况下是无法察觉的。

内联元素

这里不做详细的介绍,下面说说什么是 “内联盒子” 和 “行框盒子”

内联盒子

“内联盒子” 不会让内容成块显示,而是排成一行,这里的 “内联盒子” 实际指的就是元素的 “外在盒子”,用来决定元素是内联还是块级,该盒子可以分为 “内联盒子” 和 “匿名内联盒子”。简单的说其实就是,当 “外在盒子” 决定元素是在一行显示的时候,那么这个元素就是 “内联盒子”。比如说设置了 display: inline-block 属性的元素就是一个内联盒子。

什么是匿名内联盒子呢?
  <div style="color: red">
    <span style="color: black">sfjjfhfjh</span>
    会务费和返回份盒饭好烦好烦
    <span style="color: black">fhhdfhfhfh</span>
  </div>

上面红色汉子的部分就是 “匿名内联盒子”

注意: 并不是所有文字的部分都是 “匿名内联盒子”。这个要看这段文字前后的标签类型,如果标签类型是块级元素,那么它就属于 “匿名块级盒子”。

行框盒子

如果当前行是由 “内联盒子” 所组成的,那么这一行就可以被称之为 “行框盒子”

幽灵空白节点

“幽灵空白节点” 是内联盒模型中非常重要的一个概念,具体指的是:HTML5 文档声明中,内联元素的所有解析和渲染表现就如同每个行框盒子的前面有一个 “空白节点” 一样。这个空白节点透明、不占据任何宽度、看不见也无法通过脚本获取,就像幽灵一般。但是,它又确实存在,表现如同文本节点一样。

注意: 这里有一个前提条件。就是,文档声明必须是 HTML5 文档声明()

  <div style="background: #ccc;">
    <img src="https://demo.cssworld.cn/images/common/l/1.jpg" alt="" width="100">
  </div>

上面的这个 demo 显示 父元素的底部和图片的底部有间隙,这是为什么呢?。

shenxuxiang avatar Oct 28 '19 07:10 shenxuxiang