1 概述1.1 CSS 世界的“世界观”2 需提前了解的术语和概念3 流、元素与基本尺寸3.1 块级元素(block-level element)3.1.1 为什么 list-item 元素会出现项目符号3.2 宽高作用的细节3.2.1 width: auto 不同场景下的表现3.2.1.1 外部尺寸与流体特性3.2.1.2 内部尺寸与流体特性3.2.2 width 值3.2.3 CSS 流体布局下的宽度分离原则3.2.4 改变width/height 作用细节的 box-sizing3.2.5 关于 height:auto3.2.6 关于 height:100%3.3 min-width/max-width/min-height/max-height3.3.3 超越!important, 超越最大3.3.4 任意高度元素的展开收起动画技术3.4 内联元素3.4.2 内联盒模型3.4.2.1 内容区域(content area)3.4.2.2 内联盒子(inline box)3.4.2.3 行框盒子(line box)3.4.2.4 包含块—包含盒子(containing box)3.4.3 幽灵空白节点(strut)4 盒尺寸四大家族4.1 深入理解 content4.1.1 content 与替换元素基于伪元素的图片内容生成技术匿名替换元素4.1.2 content 内容生成技术4.1.2.1 content 辅助元素生成4.1.2.2 content 字符内容生成4.1.2.3 content 图片生成4.1.2.4 content attr 属性值内容生成4.1.2.5 深入理解 content 计数器4.2 温和的 padding 属性标签元素内置的 padding三道杠双层圆点4.3 激进的 margin 值margin 实现多流体布局效果两栏自适应:两端对齐:等高布局:margin 合并应用场景计算规则margin: auto实现右对齐水平居中:margin: auto水平垂直方向居中margin 无效情形解析4.4 功勋卓越的 border 属性border-widthborder-styleborder-colorborder-color: transparant5 内联元素与流5.1 字母 X 与 CSS 世界的基线5.2 内联元素的基石 line-height5.3 vertical-alignvertical-align: top/bottomvertical-align: middlevertical-align: text-topvertical-align: text-bottom6 流的破坏与保护6.1 魔鬼属性 float6.2 float 的天然克星 clear6.3 CSS 世界的结界——BFC6.4 最佳结界 overflow6.5 float 的兄弟 position: absoluteCSS权威指南 第3版.pdf 1 概述 1.1 CSS 世界的“世界观”流:引导元素排列和定位的一条看不见的“水流”流体布局:利用元素“流”的特性实现的各类布局效果CSS2.1 兼容 IE8+“流”的特性对 并不适用,一些 CSS 属性的表现,如单元格的 vertical-align ,也和普通元素不一样2 需提前了解的术语和概念泛关键字:所有 CSS 属性都可以使用的关键字百分号%不是长度单位,是一个完整的值相对长度单位: 相对字体长度:em、ex、rem、ch相对视区长度单位:vh、vw、vmin、vmax绝对长度单位:px、pt、cm、mm、pc变量:currentColor功能符:rgba(0,0,0,.5)、url(‘lulu.png’)、attr(‘href’)、scale(-1)焦点元素:像、 这样的元素,当我们使用键盘进行 Tab 键切换的时候,是可以被 focus 的,表现为虚框或者外发光非焦点元素:指没有设置 tabindex 属性的 、等普通元素。 Firefox 认为 :active 发生在 mousedown 之后 3 流、元素与基本尺寸 3.1 块级元素(block-level element)display: block | table | list-item块级元素具有换行特性,因此都可以配合 clear 属性来清除浮动IE 浏览器不支持伪元素的 display 值为 list-item 3.1.1 为什么 list-item 元素会出现项目符号之所以 list-item 元素会出现项目符号是因为生成了一个附加的盒子,学名“标记盒子”(marker box), 专门用来放圆点、数字这些项目符号。IE 浏览器下伪元素不支持 list-item 或许就是无法创建这个“标记盒子”导致的 每个元素都有两个盒子:外在的“外在盒子”:负责元素是可以一行显示,还是只能换行显示内在的“容器盒子(内在盒子)”:负责宽高、内容呈现什么的 例如inline-block:由外在的“内联盒子”和内在的“块级容器盒子”组成,因此既能和图文一行显示,又能直接设置宽高。inline-table:由外在的“内联盒子”和内在的“table盒子”组成,因此既能和图文一行显示,又能显示成表格。 3.2 宽高作用的细节流体特性主要体现在水平方向上宽高作用于内在盒子(容器盒子)即流体特性也就是作用于容器盒子的 3.2.1 width: auto 不同场景下的表现 充分利用可用空间(fill-available): 块级元素的宽度默认是100%于父级容器的收缩与包裹(shrink-to-fit): 浮动、绝对定位、inline-block 元素 或 table 元素收缩到最小(min-content):table-layout 为 auto 的表格中超出容器限制(max-content):除非有明确的宽度限制或者内联元素设置了 white-space:nowrap 外部尺寸(Intrinsic Sizing): (fill-available) 尺寸由外部元素决定 内部尺寸(Extrinsic Sizing): 其他三种,尺寸由内部元素决定 3.2.1.1 外部尺寸与流体特性3.2.1.1.1 正常流宽度block 元素天生具备流特性,块级元素一旦设置了高度,流动性就丢失了**借助block 元素流动性无宽度布局**:并不是看上去的宽度100% 显示这么简单,而是一种 margin | border | padding | content 内容区域自动分配水平空间的机制 3.2.1.1.2 格式化宽度格式化宽度:绝对定位元素的非替换元素宽度大小相对于最近的具有定位特性(positon != static)的祖先元素计算 3.2.1.2 内部尺寸与流体特性内部尺寸:假如这个元素里面没有内容,宽度就是0 3.2.1.2.1 shrink-to-fit自适应性:元素尺寸由内部元素决定,但永远小于“包含块”容器的尺寸(除非容器尺寸小于元素的”首选最小宽度“) 应用场景:文字少的时候居中显示,文字超过一行的时候居左显示 <div class="box"> <input id="conMore" class="content">文字内容</input> </div> .box { text-align: center; background-color: #cd0000; width: 500px; } .content { display: inline-block; text-align: left; background-color: yellow; } 3.2.1.2.2 min-content当 (shrink-to-fit) 的元素的宽度设为0时:东亚文字最小宽度为每个汉字的宽度西方文字最小宽度由特定的连续的英文字符单元决定。(word-break:break-all 可以设置由字符决定)图片这样的替换元素的最小宽度就是该元素内容本身的宽度 应用场景:利用连续英文单词不换行(首选最小宽度)的特性勾勒图形 <span class="ao"></span> <span class="tu"></span> .ao, .tu { display: inline-block; width: 0; font-size: 14px; line-height: 18px; margin: 35px; /*color: #fff;*/ } .ao:before, .tu:before { outline: 2px solid #cd0000; font-family: Consolas, Monaca, monospace; } .ao:before { content: "love你love" } .tu:before { content: "你love我" } .tu { direction: rtl; } 3.2.1.2.2 max-content当 (shrink-to-fit) 的元素 设置 white-space: nowrap如果内部没有块级元素或者块级元素没有设定宽度值,则“最大宽度”实际上是最大的连续内联盒子的宽度 应用场景:自定义滚动: 借助原生的滚动,scrollLeft/scrollTop 值变化,优点是简单,不足是效果呆板根据内部元素的尺寸和容器的关系,通过修改内部元素的位置实现滚动效果,优点是效果可以很绽放。iScroll 模拟水平滚动,只能使用“最大宽度”,这样滚动到底的时候才是真的到底 https://github.com/cubiq/iscroll <div id="wrap" class="wrap"> <ul> <li><img src="./images/1.jpeg" alt="1"></li> <li><img src="./images/1.jpeg" alt="2"></li> <li><img src="./images/1.jpeg" alt="3"></li> <li><img src="./images/1.jpeg" alt="4"></li> <li><img src="./images/1.jpeg" alt="5"></li> </ul></div> .wrap { width: 300px; height: 200px; position: relative; overflow: hidden; } .wrap > ul { position: absolute; white-space: nowrap; } .wrap li { display: inline-block; } new IScroll('#wrap', { scrollbars: true, scrollX: true, scrollY: false, }) 3.2.2 width 值width 的值作用于 content box 3.2.3 CSS 流体布局下的宽度分离原则嵌套一层标签,父元素定宽,子元素width: auto子元素的 content box 宽度是100px .father { width: 100px;}.son { border: 1px solid;} 过深的嵌套会增加页面渲染和维护成本 3.2.4 改变width/height 作用细节的 box-sizing盒尺寸(box-dimension): box-sizing改变 width 作用的细节默认是content boxborder box: content-box 和 padding 以及 border 一起自动分配 width 值margin 的背景永远是透明的Flex 布局: IE10+ 解决替换元素宽度自适应问题: input, textarea, img, video, object { box-sizing: border-box;} 3.2.5 关于 height:auto子元素高度的和 3.2.6 关于 height:100%对于普通文档流中的元素,百分比高度值要想起作用,其父级必须有一个可以生效的高度值。因此让元素支持 height:100%: 设定显式的高度值使用绝对定位 绝对定位元素的百分比:计算是相对于 padding box 的,就是会把 padding 大小值计算在内非绝对定位元素的百分比:相对于 content box 计算的 html, body { height: 100%;} div { height: 100%; position: absolute;} 应用场景:图片上下切图布局示意 3.3 min-width/max-width/min-height/max-heightIE7+ 初始值: max-*: nonemin-*: 0 | auto 3.3.3 超越!important, 超越最大min-width > max-width > !important > style > css 3.3.4 任意高度元素的展开收起动画技术<input id="check" type="checkbox"><p>个人觉得,...</p><div class="element"> <p>display:table-cell其他...</p></div><label for="check" class="check-in">更多↓</label><label for="check" class="check-out">收起↑</label> .element { max-height: 0; overflow: hidden; transition: max-height .25s;}:checked ~ .element { max-height: 666px;} 如果 max-height 值太大,在收起的时候可能会有”效果延迟“的问题,因此建议使用足够安全的最小值,这样,收起时即使有延迟,也会因为时间很短,很难被用户察觉,并不会影响体验。 3.4 内联元素display:inline | inline-block | inline-table: inline-block: inline 可以和文字在一行显示 3.4.2 内联盒模型 3.4.2.1 内容区域(content area)本质上是一个字符盒子(character box)em-box,可看作是中文字符占据 1em 高度区域;可以把文本选中的背景色区域作为内容区域,注意chrome浏览器下,::selection和图文混排或者有垂直padding的时候,范围会明显过大 3.4.2.2 内联盒子(inline box)实际指的就是元素的“外在盒子”,用来决定元素是内联还是块级 3.4.2.3 行框盒子(line box)每一行就是一个“行框盒子”,每个“行框盒子”又是由一个一个“内联盒子”组成的 3.4.2.4 包含块—包含盒子(containing box)由一行行的“行框盒子”组成 3.4.3 幽灵空白节点(strut)是个假想盒,存在于每个“行框盒子”前面,同时具有该元素的字体和行高属性的0宽度的内联盒 div { background-color: #cd0000;}span { display: inline-block;}<div><span></span><div> 4 盒尺寸四大家族 4.1 深入理解 content 4.1.1 content 与替换元素替换元素:通过修改某个属性值呈现的内容就可以被替换的元素 内容可替换内容的外观不受页面上的 CSS 的影响有自己的尺寸 : 300*150:0 CSS 属性上有自己的一套表现规则:如vertical-align非替换元素是指X的下边缘,替换元素是元素的下边缘不支持::before|::after伪元素 替换元素的默认display值 元素 Chrome | IE Firefox inline inline inline inline inline inline inline-block inline-block inline-block inline range|file inline-block inline-block hidden none none inline-block inline-block inline-block inline 元素 white-space 表现 <input type=”button” value=”按钮“> pre 当文字足够多不会自动换行 按钮 normal 当文字足够多会自动换行 替换元素的尺寸计算规则: 固有尺寸:替换内容原本的尺寸;表单元素默认的font-size/padding/margin等属性全部使用px作为单位是因为这样可以保证固有尺寸是固定大小,不会受外界CSS的影响HTML尺寸:只能通过HTML原生属性改变,的width和height属性,的size属性,的cols 和 rows 属性等CSS尺寸:指可以通过CSS的width和height或者max-width/min-width和max-height/min-height设置的尺寸,对应盒尺寸中的 content box CSS 尺寸 > HTML 尺寸 > 固有尺寸 如果“固有尺寸”含有固有的宽高比例,同时仅设置了宽度或仅设置了高度,则元素依然按照固有的宽高比例显示如果上面的条件都不符合,则最终宽度表现为300*150,宽高比2:1内联替换元素和块级替换元素使用上面同一套尺寸计算规则,这也是为什么替换元素设置display:block, 宽度却没有100%容器的原因 例外:img的默认尺寸并非300*150,不同浏览器会有不同的表现 Chrome IE Firefox 尺寸 0 X 0 28 X 30 0 X 22 首屏以下的图片通过滚屏加载的方式异步加载: <img> img { visibility: hidden; } img[src] { visibility: visible; } 图片资源的固有尺寸是无法改变的建议在CSS重置的时候加上: img { display: inline-block } 替换元素变成非替换元素:如图片删除 src 属性如果图片没有替换内容(不添加 src 属性),图片就是一个普通的内联标签,chrome 还需要不为空的 alt 属性值;IE下当src属性缺失时,会使用默认的占位内容,因此还是替换元素的表现。 非替换元素变成替换元素:添加 content 属性** 基于伪元素的图片内容生成技术 兼容性:IE不支持对于<img>元素使用::before 和 ::after 伪元素进行内容生成以及样式构建不能有 src 属性不能使用 content 属性生成图片(针对 chrome)需要有alt属性并有值(针对chrome)Firefox下::before 伪元素的content值会被无视,::after无此问题,应该与Firefox 自己占用了 ::before 伪元素的 content 属性有关chrome 中所有的元素都支持 content属性,而其他浏览器仅在::before/::after伪元素中才有支持 注意:content 属性改变的仅仅是视觉呈现 应用场景:hover 图片变成另外一张图片 通过 CSS 的 content 属性直接替换的替换内容借助 background-image两个 元素显隐控制实现 <img src="laugh.png"> img:hover { content: url(laugh-tear.png) } 匿名替换元素content 属性生成的对象 生成的文本无法选中、无法复制,好像设置了 user-select: none 声明一般无法被屏幕阅读设备读取,也无法被搜索引擎抓取,对可访问性和SEO很不友好所有只能用来生成一些无关紧要的内容,如装饰性图形或序号之类的不能左右 :empty 伪类content 动态生成值(计数器)无法获取 window.getComputedStyle(dom, "::after").content 4.1.2 content 内容生成技术 4.1.2.1 content 辅助元素生成清浮动 .clear:after { content: ''; display: table; clear: both; } 辅助实现“两端对齐”以及“垂直居中/上边缘/下边缘对齐”效果 <div class="box"> <i class="bar"></i> <i class="bar"></i> <i class="bar"></i> <i class="bar"></i> </div> .box { width: 256px; height: 256px; text-align: justify; /*两端对齐的关键*/ } .box:before { content: ''; display: inline-block; height: 100%; } .box:after { content: ''; display: inline-block; width: 100%; } .bar { display: inline-block; width: 20px; height: 256px; background: red; } 4.1.2.2 content 字符内容生成让‘…‘动起来 正在加载中<dot>...</dot> dot { display: inline-block; height: 1em; line-height: 1; text-align: left; vertical-align: -.25em; overflow: hidden; } dot::before { display: block; content: '...\A..\A.'; /*\A是换行符*/ white-space: pre-wrap; animation: dot 3s infinite step-start both; } @keyframes dot { 33% { transform: translateY(-2em);} 66% { transform: translateY(-1em);} } 4.1.2.3 content 图片生成div:before { content: url(1.jpg); /*不支持CSS3渐变背景图*/ } 4.1.2.4 content attr 属性值内容生成img::after { content: attr(alt) } attr 中的属性值名称不能有引号,否则浏览器会认为是无效的声明 4.1.2.5 深入理解 content 计数器 CSS 计数器效果:使用 CSS 代码实现随着元素数目增多,数值也跟着变大的效果 counter-reset :命名1 + 初始值(默认0) + 命名2 + 初始值(默认0) none: 取消重置inherit: 继承重置 counter-increment :counter-reset 的所有关键字 及 变化值(默认1) 普照规则:普照源 (counter-reset) 唯一,每普照(counter-increment)一次,普照源增加一次计数值 counter(name,style):输出计数值 style 支持的关键字值就是 list-style-type 支持的值支持级联,一个content 属性值可以有多个 counter() 方法 counters(name, string): string 参数是字符串(需要引号包围,是必需参数),表示子序号的连接字符串一个容器里的普照源(counter-reset)是唯一的显示 content 计数值的那个DOM元素在文档流中的位置一定要在 (counter-increment)元素的后面,否则是没有计数效果的 .reset { padding-left: 20px; counter-reset: wangxiaoer; } .counter:before { content: counters(wangxiaoer, '-') '. '; counter-increment: wangxiaoer; } .reset ~ .counter { color: #cd0000; } <div class="reset"> <div class="counter">我是王小二</div> <div class="reset"> <div class="counter">我是王小二的大儿子</div> <div class="counter">我是王小二的二儿子</div> <div class="reset"> <div class="counter">我是王小二的二儿子的大孙子</div> <div class="counter">我是王小二的二儿子的二孙子</div> <div class="counter">我是王小二的二儿子的小孙子</div> </div> <div class="counter">我是王小二的三儿子</div> </div> <div class="counter">我是王小三</div> <div class="counter">我是王小四</div> <div class="reset"> <div class="counter">我是王小四的大儿子</div> </div> </div> 4.2 温和的 padding 属性内联元素没有可视宽度和可视高度的说法(clientHeight 和 clientWidth 永远是 0),垂直方向的行为表现完全受 line-height 和 vertical-align 的影响,视觉上并没有改变和上一行下一行内容的间距,感觉就会是垂直 padding 没有起作用。其实只是垂直方向发生了层叠,但是不会影响布局。 层叠现象: 视觉层叠,不影响外部尺寸:父容器 overflow: auto ,层叠区域超出父容器的时候,没有滚动条出现,则是纯视觉的;如 box-shadow、outline会影响外部尺寸:父容器 overflow: auto ,出现滚动条,则会影响尺寸、影响布局。如 padding 应用场景:在不影响当前布局的情况下,添加链接的点击区域大小 artical a { padding: .25em 0; } 应用场景:锚点定位;块级元素设置padding 会影响布局,但是内联元素不会 对于非替换元素的内联元素,不仅 padding 不会加入行盒高度的计算,margin 和 border 也都是如此,都是不计算高度,但实际上在内联盒周围发生了渲染。 padding 的属性值** 不支持负值百分比值无论是水平还是垂直方向均是相对于宽度计算的 <div class="box"> <img src="cover.jpg"> </div> .box { padding: 10% 50%; position: relative; } .box > img { position: absolute; width: 100%; height: 100%; left: 0; top: 0; } 标签元素内置的 padding ol/ul 列表内置 padding-left,但是单位是 px 不是 em很多表单元素都内置 padding 所有浏览器 内置 padding部分浏览器 下拉内置padding,如 Firefox、IE8 及以上版本浏览器可以设置 padding所有浏览器 单复选框无内置 padding 的 padding 与高度计算不同浏览器下千差万别,因此通常我们用模拟,但在表单中,按钮是自带交互行为的,可以通过结合进行实现: <button id="btn"><button> <label for="btn">按钮<label> button { position: absolute; clip: rect(0 0 0 0); } label { display: inline-block; line-height: 20px; padding: 10px; } 三道杠.icon-menu { display: inline-block; width: 140px; height: 10px; padding: 35px 0; border-top: 10px solid; border-bottom: 10px solid; background-color: currentColor; background-clip: content-box; } 双层圆点.icon-dot { display: inline-block; width: 100px; height: 100px; padding: 10px; border: 10px solid; border-radius: 50%; background-color: currentColor; background-clip: content-box; } 4.3 激进的 margin 值 元素尺寸:即元素偏移尺寸offsetWidth 和 offsetHeight,包括 padding、border 的值,即 border box 元素内部尺寸:即元素可视尺寸 clientWidth 和 clientHeight,包括 padding 但不包括 border,即 padding box元素外部尺寸:包括 padding、border、margin,即 margin box;该尺寸大小有可能是负数,可理解为“元素占据的空间尺寸” 对于块状元素而言: 元素设定了 width 值或者保持“包裹性”的时候,margin 就无法改变元素尺寸;只有元素是“充分利用可用空间”时,margin 才可以改变元素的可视尺寸; 对于普通流体元素,margin 只能改变元素水平方向尺寸对于具有拉伸特性的绝对定位元素,则水平或垂直方向 magin 都会改变可视尺寸 对于纯内联元素垂直方向的 margin 既不会影响外部尺寸,也不会影响内部尺寸,由于内联元素宽度表现为“包裹性”,也不会影响内部尺寸 margin 的百分比值无论水平还是垂直方向都是相对于宽度计算的 margin 实现多流体布局效果 两栏自适应:<div className="box"> <div className="inner-left"></div> <div className="inner-right"></div> </div> .box { overflow: hidden; background: #000; height: 800px; } .inner-left { background: red; float: left; width: 140px; height: 100%; } .inner-right { margin-left: 140px; background: yellow; height: 100%; } 两端对齐:<ul> <li></li> <li></li> <li></li> </ul> ul { margin-right: -20px; background: #000; height: 100px; } ul > li { float: left; width: 100px; margin-right: 20px; list-style: none; background: red; height: 100%; } 等高布局:<div className="box"> <div className="left" contentEditable>正方</div> <div className="right" contentEditable>反方</div> </div> .box { overflow: hidden; } .left, .right { margin-bottom: -9999px; padding-bottom: 9999px; width: 50%; float: left; color: #fff; } .left { background: #000; } .right { background: red; } margin 合并块级元素的上外边距(margin-top) 与 下外边距(margin-bottom)有时会合并为单个外边距 块级元素,不包括浮动和绝对定位元素,尽管浮动和绝对定位可以让元素块状化只发生在垂直方向上 应用场景 相邻兄弟元素 margin 合并父级和第一个/最后一个子元素 对于margin-top 合并的解决方案 父元素设置为块状格式化上下文元素父元素设置 border-top 值父元素设置 padding-top 值父元素和第一个子元素之间添加内联元素进行分隔 对于margin-top 合并的解决方案 父元素设置为块状格式化上下文元素父元素设置 border-bottom 值父元素设置 padding-bottom 值父元素和第一个子元素之间添加内联元素进行分隔父元素设置 height、min-height 或 max-height 空块级元素的 margin 合并 设置垂直方向的 border设置垂直方向的 padding里面添加内联元素(直接 space 键空格是没用的)设置 height 或者 min-height // 解决方案 .container { overflow: hidden; } 计算规则 正正取大值正负值相加负负最负值 默认全部都是由垂直方向的margin值的,且单位是em 相邻元素 margin 合并机制可以保证元素上下间距一致父子 margin 合并的意义在于:在页面中任何地方嵌套或直接放入任何空都不会影响原来的块状布局自身 margin 合并的意义在于可以避免不小心遗落或生成的空标签影响排版和布局 margin: auto 如果一侧定值,一侧 auto,则 auto 为剩余空间大小如果两侧均是 auto,则平分剩余空间css 世界中的 margin 初始值是 0 实现右对齐 float: rightmargin-left: auto .father { width: 300px; } .son { width: 200px; margin-left: auto; } 水平居中:margin: auto.son { width: 200px; margin: auto; } 触发 margin:auto 计算有一个前提条件,就是 width 或 height 为 auto 时,即元素是具有对应方向的自动填充特性的 水平垂直方向居中.father { width: 300px; height:150px; position: relative; } .son { position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 200px; height: 100px; margin: auto; } margin 无效情形解析 display: inline 的非替换元素的垂直 margin 是无效的;内联替换元素的垂直 margin 有效,但是不会发生 margin 合并,比如图片表格中的 或者设置 display: table-cell or display: table-row 的元素的 margin 是无效的但是如果计算值是table-caption、table、inline-table 则可以通过 margin 控制外间距,甚至 :first-letter 伪元素也可以解析 marginmargin 合并的时候,更改 margin 值可能是没有效果的。以父子 margin 重叠为例,假设父元素设置有 margin-top: 50px, 则此时子元素设置 margin-top: 30px 就没有任何效果表现,除非大小比 50px 大,或者是负值绝对定位元素非定位方位的 margin 值 “无效”定高容器的子元素的 margin-bottom 或者宽度定死的子元素的 margin-right 的定位“失效”鞭长莫及导致的 margin 无效内联特性导致的 margin 无效 4.4 功勋卓越的 border 属性 border-widthborder-width、outline、box-shadow、text-shadow 等都是不支持百分比值的 border-width支持关键字: thin: 1pxmedium: 3px, 默认值thick: 4px border-stylenone: 默认值 solid: 实线dashed:虚线dotted: 虚点 IE 下是圆点chrome 下是虚点 double:两根线且为实线 当边框宽度为1px 和 2px 时,其表现和 border-style: solid 是一模一样的当边框宽度不小于 3px 时,才开始有双线边框的表现,包括 retina 屏幕,因为边框宽度是没有半像素的概念的 border-colorborder-color、outline、box-shadow、text-shadow等默认颜色就是 color 色值https://demo.cssworld.cn/4/4-1.php border-color: transparantIE7+ 支持应用场景: 右下方 background 定位增加点击区域大小三角等图形绘制借助 border 生成的梯形实现小圆角效果 https://demo.cssworld.cn/4/4-3.php 实现等高布局 5 内联元素与流 5.1 字母 X 与 CSS 世界的基线 line-height 的定义就是两基线的间距vertical-align 的默认值就是基线 middle 并不是绝对的垂直居中对齐,指的是基线往上 1/2 x-height 高度,可以近似理解为字母 X 交叉点的那个位置 ascender height: 上下线高度 cap height:大写字母高度median:中线baseline: 基线descender height:下行线高度 ex: 相对单位,指的是x-height,即小写字母 x 的高度,使用 ex 单位对齐不受字体和字号的影响内联元素默认是基线对齐的https://demo.cssworld.cn/5/1-1.php 5.2 内联元素的基石 line-height 对于非替换元素的纯内联元素,可视高度完全由 line-height 决定内联元素的高度由固定高度和不固定高度(行距)组成“行距“分散在当前文字的上方和下方,第一行文字的上方也是有”行距“的,只不过是”半行距“行距 =line-height - font-size内容区域(content area): 可以近似理解为浏览器下文本选中带背景色的区域内容区域高度受 font-family 和 font-size 双重影响,而 em-box 仅受 font-size 影响;当字体是宋体时,内容区域和 em-box 是等同的半行距取整处理:如果是文字上边距,则向下取整;如果是文字下边距,则向上取整;因为绝大多数的字体在内容区域中都是偏下的line-height 无法影响替换元素(图片)的高度line-height 对于块级元素是是没有任何作用的,平时改变line-height, 块级元素的高度跟着变化实际上是通过改变块级元素里面内联级别元素占据的高度实现的在 HTLML5 文档模式下,每一个”行框盒子”的前面都有一个宽度为0的“幽灵空白节点”,其内联特性表现和普通字符一模一样line-height 具有继承性让内联元素“近似垂直居中”可以通过设置 line-height 大小和高度一样基于行高实现的多行文字垂直居中效果,需要vertical-align属性帮助。 line-height: 1.5 : 所有的子元素继承的都是这个值,即倍数line-height: 150%; line-height: 1.5em : 所有的子元素继承的是最终的计算值,即具体的px行框盒子的高度是由高度最高的那个“内联盒子”决定的,所以容器块状元素的高度永远都是最大的那个line-height要避免“幽灵空白节点”的干扰,可以设置内联元素 display: inline-block , 创建一个独立的 “行框盒子” 5.3 vertical-align 线类:如 baseline(默认值)、top、middle、bottom文本类:如 text-top、text-bottom上标下标类:如 sub、super数值百分比类:如20px、2em、20% 等 baseline: 内联元素默认是沿着字母X的下边缘对齐的替换元素是使用元素本身的下边缘作为基线 vertical-align 的值:相对于基线,负值是往下偏移,正值是往上偏移;即 baseline 等同于 vertical-align: 0 百分比值: margin 和 padding 相对于宽度计算line-height 相对于 font-size 计算vertical-align 相对于 line-height 计算 vertical-align 属性只能作用于 display 值为: inlineinline-blockinline-tabletable-cell其他块级元素不支持 但是注意浮动和绝对定位会让元素块状化,会导致 vertical-align 不生效 vertical-align 的默认值: 文本内联元素:字符x的下边缘替换元素:替换元素的下边缘inline-block: 如果里面没有内联元素,或 overflow 不是 visible:margin底边缘有内联元素:最后一行内联元素的基线 清除图片产生的间隙的方法: 图片块状化:可以一口气干掉“幽灵空白节点”、line-height、vertical-align容器 line-height 足够小:只要半行间距小到字母 x 的下边缘位置或者再往上,自然就没有了撑开底部间隙高度空间了。比方说,容器设置 line-height: 0容器 font-size 足够小:此方法要想生效,需要容器的 line-height 属性值和当前 font-size 相关,如 line-height: 1.5 或者 line-height: 150% 之类;否则只会让下面的间隙变得更大,因为基线位置因字符x变小而往上升了图片设置其他 vertical-align 属性值:间隙产生原因之一就是基线对齐,所以我们设置 vertical-align 的值为 top、middle、bottom 中的任意一个 最佳图标实践: 图标高度和当前行高都是 20px图标标签里面永远有字符图标 CSS 不使用 overflow: hidden 保证基线为里面字符的基线,但是要让里面潜在的字符不可见 .box { line-height: 20px; } .icon { display: inline-block; width:20px; height:20px; white-space: nowrap; letter-spacing: -1em; text-indent: -999em; } .icon:before { content:'\3000'; } .icon-delete { background: url(delete.png) no-repeat center; } vertical-align: top/bottom 内联元素:元素底部和当前行框盒子的顶部对齐table-cell: 元素底 padding 边缘和表格行的顶部对齐 vertical-align: middle 内联元素:元素的垂直中心点和行框盒子基线往上 1/2 x-height 处对齐table-cell: 单元格填充盒子相对于外面的表格行居中对齐 vertical-align: text-top盒子的顶部和父级内容区域的顶部对齐 假设元素后面有一个和父元素 font-size\font-family 一模一样的文字内容,则 vertical-align: text-top 表示元素和这个文字的内容区域的上边缘对齐 vertical-align: text-bottom盒子的底部和父级内容区域的底部对齐 内容区域:文本选中的背景区域或者默认状态下的内联文本的背景色区域父级内容区域:在父级元素当前 font-size 和 font-family 下应有内容区域大小 6 流的破坏与保护 6.1 魔鬼属性 float浮动的本质就是为了实现文字环绕效果 float 的特性: 包裹性 包裹自适应性 块状化并格式化上下文:display 的计算值是 block 或 table破坏文档流 父级高度坍塌行框盒子区域限制 没有任何 margin 合并浮动元素和内联元素在一行显示 浮动锚点(float anchor):是 float 元素所在的“流”中的一个点,这个点本身并不浮动,就表现而言更像一个没有 margin 、border、和 padding 的空的内联元素。作用就是产生“行框盒子”浮动参考(float reference): 浮动元素对齐参考的实体,float 元素的浮动参考是“行框盒子” 6.2 float 的天然克星 clear 元素自身盒子的边不能和前面的浮动元素相邻,即对后面的元素不闻不问clear 属性只对块级元素才有效,而 ::after 等伪元素默认都是内联水平, 所以伪元素清除浮动影响需要设置display 属性值为块状元素clear: both 作用的本质是让自己不和 float 元素在一行显示,并不是真正意义上的清浮动,因此 float 元素一些不好的特性依然存在 如果 clear: both 元素前面的元素就是 float 元素,则 margin-top 负值即使设置成 -9999px ,也不见任何效果clear: both 后面的元素依旧可能会发生文字环绕的现象 clear: none | left | right | both none: 默认值,左右浮动来就来left:左侧抗浮动right:右侧抗浮动both:两侧抗浮动 6.3 CSS 世界的结界——BFC BFC(block formatting context):块级格式化上下文IFC(inline formatting context):内联格式化上下文 结界:通过一些特定的手段形成的封闭空间,里面的人出不去,外面的人进不来,具有极强的防御力 如果一个元素具有 BFC,内部子元素再怎么翻江倒海都不会影响外部的元素。所以,BFC 元素是不可能发生 margin 重叠的,因为 margin 重叠是会影响外面的元素的;BFC 元素也可以用来清除浮动的影响,因为如果不清除,子元素浮动则父元素高度坍塌,必然会影响后面元素布局和定位,这显然有违 BFC 元素的子元素不会影响外部元素的设定BFC 的结界特性最重要的用途不是去 margin 重叠或者是清除 float 影响,而是实现更健壮、更智能的自适应布局 触发BFC 根元素float 的值不为 none float: left 浮动元素本身 BFC 化,然而浮动元素有破坏性和包裹性,失去了元素本身的流体自适应性。因此无法用来实现自动填满容器的自适应布局。 overflow 的值为 auto、scroll、或 hidden overflow: hidden IE7+;BFC 本身还是一个普通元素,流体特性完好同时具备 BFC 的独立区域特性。唯一的问题是容器盒子外的元素可能会被隐藏掉,一定程度上限制了这种特性的大规模使用。不过溢出隐藏的交互场景比例不算高,因此可作为常用 BFC 布局属性使用。 display 的值为 table-cell、table-caption、inline-block 中的任何一个 display: inline-block IE6 | IE7;会让元素尺寸包裹收缩,即会影响原来的样式布局,不是 block 水平的流动特性;zoom: 1 也是类似的效果display: ``table-cell IE8+;会跟随内部元素的宽度显示,但宽度值设置得再大,实际宽度也不会超过表格容器的宽度;适用场景会比 overflow: hidden 更广泛 position 的值不为 relative、static positon: absolute 脱离文档流有些严重,和非定位元素很难玩到一块去 BFC 自适应布局:普通流体元素在设置了 overflow: hidden 后,会自动填满容器中除了浮动元素以外的剩余空间,形成自适应布局效果,而且这种自适应布局要比纯流体自适应更加智能。比方说,让图片的尺寸变小或变大,右侧自适应内容无须更改任何样式代码,都可以自动填满剩余的空间。 两套自适应解决方案:方案一:如果子元素要定位到父元素的外面可能会被隐藏 .bfc { overflow: hidden; } 方案二:无法直接让连续英文字符换行 .bfc { display: table-cell; width: 9999px; // 如果不需要兼容 IE7,则下面的样式可以省略 display: inline-block; *width: auto; } 连续英文字符无法换行的解决方案: .word-break { display: table; width: 100%; table-layout: fixed; word-break: break-all; } 6.4 最佳结界 overflow overflow: hidden 声明不会影响元素原先的 流体特性 或 宽度表现overflow 属性原本的作用是指定块容器元素的内容溢出时是否需要裁剪,即“剪裁”是其本职工作,“结界”只是其衍生出来的特性 当子元素内容超出容器宽度高度限制的时候,剪裁的边界是 border box 的内边缘,而非 padding box 的内边缘 实现元素剪裁同时四周留有间隙:使用透明边框,此时内间距 padding 属性是无能为力的 浏览器兼容性: chrome 滚动高度包含 padding-bottomIE 和 Firefox 滚动高度不包含 padding-bottom因此在实际开发中,要避免滚动容器设置 padding-bottom 值,除了样式表现不一致,还会导致 scrollHeight 的值不一样 overflow、overflow-x、overflow-y 的属性取值: visible: 默认值hidden:剪裁scroll:滚动条区域一直在auto:不足以滚动时没有滚动条,可以滚动时滚动条出现 永远不可能实现一个方向溢出剪裁或滚动,另一方向内容溢出 除非 overflow-x 和 overflow-y 的值均为 visible,否则 visible 会被当成 auto 来解析 IE8+默认 overflow: auto 的标签, 即默认可以产生滚动条的: PC 端,默认滚动条均来自 去除默认滚动条 html { overflow: hidden; } PC 端窗口滚动高度:document.documentElement.scrollTop移动端窗口滚动高度:document.body.scrollTopPC端:滚动条会占用容器的可用宽度或高度,IE7+、chrome、firefox 滚动条所占据的宽度均是 17px移动端:屏幕尺寸有限,滚动条一般都是悬浮模式,不会占据可用宽度 获取滚动栏占据的宽度: .box { width: 400px; overflow: scroll; } <div class="box"> <div id="in" class="in"></div> </div> console.log(400 - document.getElementById("in").clientWidth); 让页面滚动条不发生晃动: html { overflow-y: scroll; /* for IE8 */ } :root { overflow-y: auto; overflow-x: hidden; } :root body { position: absolute; } body { width: 100vw; overflow: hidden; } 自定义滚动条: ::-webkit-scrollbar { /* 血槽宽度 */ width: 8px; height: 8px; } ::-webkit-scrollbar-thumb { /* 拖动条 */ background-color: rgba(0, 0, 0, .3); border-radius: 6px; } ::-webkit-scrollbar-track { /* 背景槽 */ background-color: #ddd; border-radius: 6px; } 单行文字溢出点点点效果: .ell { text-overflow: ellipsis; white-space: nowrap; overflow: hidden; } 多行文字打点效果: .ell-rows-2 { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; } 锚点定位: 让页面定位到某个位置的点本质是通过改变容器滚动高度(scrollTop)或者宽度来实现scrollHeight: 视区高度 + 可滚动高度clientHeight: 视区高度 触发锚点定位 URL 地址中的锚链与锚点元素对应并有交互行为 让元素定位在浏览器窗体的上边缘<a href="javascript:">返回顶部</a> 可 focus 的锚点元素处于 focus 状态 让元素在浏览器窗体范围内显示即可,不一定是在上边缘document.querySelector('input').focus();“focus 锚点定位” 不依赖于 JS,是浏览器内置的无障碍访问行为 元素设置了 overflow: hidden , 同时高度溢出,滚动依然存在,仅仅滚动条不存在!_选项卡切换效果 div + ainput + label + JSoption + label + :checked 6.5 float 的兄弟 position: absolute 都兼具“块状化”、“包裹性”、“破坏性”等特性由于 absolute 血脉更纯,能力更霸道,因此,当 absolute 和 float 同时存在的时候,float 属性是无任何效果的absolute 的自适应性最大宽度往往不是由父元素决定的,本质上说,是由“包含块”的差异决定的 包含块(containing block): 元素用来计算和定位的一个框 根元素()被称为“初始包含块”,其尺寸等同于浏览器可视窗口的大小对于其他元素,如果该元素的 position 是 relative 或者 static,则“包含块”由其最近的 块容器 祖先盒的 content box 边界形成position: fixed ,则“包含块”是“初始包含块”position: absolute, 则“包含块”是由最近的 position 不为 static 的祖先元素建立的 0.7 倍 1.0 倍 1.2 倍 1.5 倍 2.0 倍 : 300*150:0 CSS 属性上有自己的一套表现规则:如vertical-align非替换元素是指X的下边缘,替换元素是元素的下边缘不支持::before|::after伪元素 替换元素的默认display值 元素 Chrome | IE Firefox inline inline inline inline inline inline inline-block inline-block inline-block inline range|file inline-block inline-block hidden none none inline-block inline-block inline-block inline 元素 white-space 表现 <input type=”button” value=”按钮“> pre 当文字足够多不会自动换行 按钮 normal 当文字足够多会自动换行 替换元素的尺寸计算规则: 固有尺寸:替换内容原本的尺寸;表单元素默认的font-size/padding/margin等属性全部使用px作为单位是因为这样可以保证固有尺寸是固定大小,不会受外界CSS的影响HTML尺寸:只能通过HTML原生属性改变,的width和height属性,的size属性,的cols 和 rows 属性等CSS尺寸:指可以通过CSS的width和height或者max-width/min-width和max-height/min-height设置的尺寸,对应盒尺寸中的 content box CSS 尺寸 > HTML 尺寸 > 固有尺寸 如果“固有尺寸”含有固有的宽高比例,同时仅设置了宽度或仅设置了高度,则元素依然按照固有的宽高比例显示如果上面的条件都不符合,则最终宽度表现为300*150,宽高比2:1内联替换元素和块级替换元素使用上面同一套尺寸计算规则,这也是为什么替换元素设置display:block, 宽度却没有100%容器的原因 例外:img的默认尺寸并非300*150,不同浏览器会有不同的表现 Chrome IE Firefox 尺寸 0 X 0 28 X 30 0 X 22 首屏以下的图片通过滚屏加载的方式异步加载: <img> img { visibility: hidden; } img[src] { visibility: visible; } 图片资源的固有尺寸是无法改变的建议在CSS重置的时候加上: img { display: inline-block } 替换元素变成非替换元素:如图片删除 src 属性如果图片没有替换内容(不添加 src 属性),图片就是一个普通的内联标签,chrome 还需要不为空的 alt 属性值;IE下当src属性缺失时,会使用默认的占位内容,因此还是替换元素的表现。 非替换元素变成替换元素:添加 content 属性** 基于伪元素的图片内容生成技术 兼容性:IE不支持对于<img>元素使用::before 和 ::after 伪元素进行内容生成以及样式构建不能有 src 属性不能使用 content 属性生成图片(针对 chrome)需要有alt属性并有值(针对chrome)Firefox下::before 伪元素的content值会被无视,::after无此问题,应该与Firefox 自己占用了 ::before 伪元素的 content 属性有关chrome 中所有的元素都支持 content属性,而其他浏览器仅在::before/::after伪元素中才有支持 注意:content 属性改变的仅仅是视觉呈现 应用场景:hover 图片变成另外一张图片 通过 CSS 的 content 属性直接替换的替换内容借助 background-image两个 元素显隐控制实现 <img src="laugh.png"> img:hover { content: url(laugh-tear.png) } 匿名替换元素content 属性生成的对象 生成的文本无法选中、无法复制,好像设置了 user-select: none 声明一般无法被屏幕阅读设备读取,也无法被搜索引擎抓取,对可访问性和SEO很不友好所有只能用来生成一些无关紧要的内容,如装饰性图形或序号之类的不能左右 :empty 伪类content 动态生成值(计数器)无法获取 window.getComputedStyle(dom, "::after").content 4.1.2 content 内容生成技术 4.1.2.1 content 辅助元素生成清浮动 .clear:after { content: ''; display: table; clear: both; } 辅助实现“两端对齐”以及“垂直居中/上边缘/下边缘对齐”效果 <div class="box"> <i class="bar"></i> <i class="bar"></i> <i class="bar"></i> <i class="bar"></i> </div> .box { width: 256px; height: 256px; text-align: justify; /*两端对齐的关键*/ } .box:before { content: ''; display: inline-block; height: 100%; } .box:after { content: ''; display: inline-block; width: 100%; } .bar { display: inline-block; width: 20px; height: 256px; background: red; } 4.1.2.2 content 字符内容生成让‘…‘动起来 正在加载中<dot>...</dot> dot { display: inline-block; height: 1em; line-height: 1; text-align: left; vertical-align: -.25em; overflow: hidden; } dot::before { display: block; content: '...\A..\A.'; /*\A是换行符*/ white-space: pre-wrap; animation: dot 3s infinite step-start both; } @keyframes dot { 33% { transform: translateY(-2em);} 66% { transform: translateY(-1em);} } 4.1.2.3 content 图片生成div:before { content: url(1.jpg); /*不支持CSS3渐变背景图*/ } 4.1.2.4 content attr 属性值内容生成img::after { content: attr(alt) } attr 中的属性值名称不能有引号,否则浏览器会认为是无效的声明 4.1.2.5 深入理解 content 计数器 CSS 计数器效果:使用 CSS 代码实现随着元素数目增多,数值也跟着变大的效果 counter-reset :命名1 + 初始值(默认0) + 命名2 + 初始值(默认0) none: 取消重置inherit: 继承重置 counter-increment :counter-reset 的所有关键字 及 变化值(默认1) 普照规则:普照源 (counter-reset) 唯一,每普照(counter-increment)一次,普照源增加一次计数值 counter(name,style):输出计数值 style 支持的关键字值就是 list-style-type 支持的值支持级联,一个content 属性值可以有多个 counter() 方法 counters(name, string): string 参数是字符串(需要引号包围,是必需参数),表示子序号的连接字符串一个容器里的普照源(counter-reset)是唯一的显示 content 计数值的那个DOM元素在文档流中的位置一定要在 (counter-increment)元素的后面,否则是没有计数效果的 .reset { padding-left: 20px; counter-reset: wangxiaoer; } .counter:before { content: counters(wangxiaoer, '-') '. '; counter-increment: wangxiaoer; } .reset ~ .counter { color: #cd0000; } <div class="reset"> <div class="counter">我是王小二</div> <div class="reset"> <div class="counter">我是王小二的大儿子</div> <div class="counter">我是王小二的二儿子</div> <div class="reset"> <div class="counter">我是王小二的二儿子的大孙子</div> <div class="counter">我是王小二的二儿子的二孙子</div> <div class="counter">我是王小二的二儿子的小孙子</div> </div> <div class="counter">我是王小二的三儿子</div> </div> <div class="counter">我是王小三</div> <div class="counter">我是王小四</div> <div class="reset"> <div class="counter">我是王小四的大儿子</div> </div> </div> 4.2 温和的 padding 属性内联元素没有可视宽度和可视高度的说法(clientHeight 和 clientWidth 永远是 0),垂直方向的行为表现完全受 line-height 和 vertical-align 的影响,视觉上并没有改变和上一行下一行内容的间距,感觉就会是垂直 padding 没有起作用。其实只是垂直方向发生了层叠,但是不会影响布局。 层叠现象: 视觉层叠,不影响外部尺寸:父容器 overflow: auto ,层叠区域超出父容器的时候,没有滚动条出现,则是纯视觉的;如 box-shadow、outline会影响外部尺寸:父容器 overflow: auto ,出现滚动条,则会影响尺寸、影响布局。如 padding 应用场景:在不影响当前布局的情况下,添加链接的点击区域大小 artical a { padding: .25em 0; } 应用场景:锚点定位;块级元素设置padding 会影响布局,但是内联元素不会 对于非替换元素的内联元素,不仅 padding 不会加入行盒高度的计算,margin 和 border 也都是如此,都是不计算高度,但实际上在内联盒周围发生了渲染。 padding 的属性值** 不支持负值百分比值无论是水平还是垂直方向均是相对于宽度计算的 <div class="box"> <img src="cover.jpg"> </div> .box { padding: 10% 50%; position: relative; } .box > img { position: absolute; width: 100%; height: 100%; left: 0; top: 0; } 标签元素内置的 padding ol/ul 列表内置 padding-left,但是单位是 px 不是 em很多表单元素都内置 padding 所有浏览器 内置 padding部分浏览器 下拉内置padding,如 Firefox、IE8 及以上版本浏览器可以设置 padding所有浏览器 单复选框无内置 padding 的 padding 与高度计算不同浏览器下千差万别,因此通常我们用模拟,但在表单中,按钮是自带交互行为的,可以通过结合进行实现: <button id="btn"><button> <label for="btn">按钮<label> button { position: absolute; clip: rect(0 0 0 0); } label { display: inline-block; line-height: 20px; padding: 10px; } 三道杠.icon-menu { display: inline-block; width: 140px; height: 10px; padding: 35px 0; border-top: 10px solid; border-bottom: 10px solid; background-color: currentColor; background-clip: content-box; } 双层圆点.icon-dot { display: inline-block; width: 100px; height: 100px; padding: 10px; border: 10px solid; border-radius: 50%; background-color: currentColor; background-clip: content-box; } 4.3 激进的 margin 值 元素尺寸:即元素偏移尺寸offsetWidth 和 offsetHeight,包括 padding、border 的值,即 border box 元素内部尺寸:即元素可视尺寸 clientWidth 和 clientHeight,包括 padding 但不包括 border,即 padding box元素外部尺寸:包括 padding、border、margin,即 margin box;该尺寸大小有可能是负数,可理解为“元素占据的空间尺寸” 对于块状元素而言: 元素设定了 width 值或者保持“包裹性”的时候,margin 就无法改变元素尺寸;只有元素是“充分利用可用空间”时,margin 才可以改变元素的可视尺寸; 对于普通流体元素,margin 只能改变元素水平方向尺寸对于具有拉伸特性的绝对定位元素,则水平或垂直方向 magin 都会改变可视尺寸 对于纯内联元素垂直方向的 margin 既不会影响外部尺寸,也不会影响内部尺寸,由于内联元素宽度表现为“包裹性”,也不会影响内部尺寸 margin 的百分比值无论水平还是垂直方向都是相对于宽度计算的 margin 实现多流体布局效果 两栏自适应:<div className="box"> <div className="inner-left"></div> <div className="inner-right"></div> </div> .box { overflow: hidden; background: #000; height: 800px; } .inner-left { background: red; float: left; width: 140px; height: 100%; } .inner-right { margin-left: 140px; background: yellow; height: 100%; } 两端对齐:<ul> <li></li> <li></li> <li></li> </ul> ul { margin-right: -20px; background: #000; height: 100px; } ul > li { float: left; width: 100px; margin-right: 20px; list-style: none; background: red; height: 100%; } 等高布局:<div className="box"> <div className="left" contentEditable>正方</div> <div className="right" contentEditable>反方</div> </div> .box { overflow: hidden; } .left, .right { margin-bottom: -9999px; padding-bottom: 9999px; width: 50%; float: left; color: #fff; } .left { background: #000; } .right { background: red; } margin 合并块级元素的上外边距(margin-top) 与 下外边距(margin-bottom)有时会合并为单个外边距 块级元素,不包括浮动和绝对定位元素,尽管浮动和绝对定位可以让元素块状化只发生在垂直方向上 应用场景 相邻兄弟元素 margin 合并父级和第一个/最后一个子元素 对于margin-top 合并的解决方案 父元素设置为块状格式化上下文元素父元素设置 border-top 值父元素设置 padding-top 值父元素和第一个子元素之间添加内联元素进行分隔 对于margin-top 合并的解决方案 父元素设置为块状格式化上下文元素父元素设置 border-bottom 值父元素设置 padding-bottom 值父元素和第一个子元素之间添加内联元素进行分隔父元素设置 height、min-height 或 max-height 空块级元素的 margin 合并 设置垂直方向的 border设置垂直方向的 padding里面添加内联元素(直接 space 键空格是没用的)设置 height 或者 min-height // 解决方案 .container { overflow: hidden; } 计算规则 正正取大值正负值相加负负最负值 默认全部都是由垂直方向的margin值的,且单位是em 相邻元素 margin 合并机制可以保证元素上下间距一致父子 margin 合并的意义在于:在页面中任何地方嵌套或直接放入任何空都不会影响原来的块状布局自身 margin 合并的意义在于可以避免不小心遗落或生成的空标签影响排版和布局 margin: auto 如果一侧定值,一侧 auto,则 auto 为剩余空间大小如果两侧均是 auto,则平分剩余空间css 世界中的 margin 初始值是 0 实现右对齐 float: rightmargin-left: auto .father { width: 300px; } .son { width: 200px; margin-left: auto; } 水平居中:margin: auto.son { width: 200px; margin: auto; } 触发 margin:auto 计算有一个前提条件,就是 width 或 height 为 auto 时,即元素是具有对应方向的自动填充特性的 水平垂直方向居中.father { width: 300px; height:150px; position: relative; } .son { position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 200px; height: 100px; margin: auto; } margin 无效情形解析 display: inline 的非替换元素的垂直 margin 是无效的;内联替换元素的垂直 margin 有效,但是不会发生 margin 合并,比如图片表格中的 或者设置 display: table-cell or display: table-row 的元素的 margin 是无效的但是如果计算值是table-caption、table、inline-table 则可以通过 margin 控制外间距,甚至 :first-letter 伪元素也可以解析 marginmargin 合并的时候,更改 margin 值可能是没有效果的。以父子 margin 重叠为例,假设父元素设置有 margin-top: 50px, 则此时子元素设置 margin-top: 30px 就没有任何效果表现,除非大小比 50px 大,或者是负值绝对定位元素非定位方位的 margin 值 “无效”定高容器的子元素的 margin-bottom 或者宽度定死的子元素的 margin-right 的定位“失效”鞭长莫及导致的 margin 无效内联特性导致的 margin 无效 4.4 功勋卓越的 border 属性 border-widthborder-width、outline、box-shadow、text-shadow 等都是不支持百分比值的 border-width支持关键字: thin: 1pxmedium: 3px, 默认值thick: 4px border-stylenone: 默认值 solid: 实线dashed:虚线dotted: 虚点 IE 下是圆点chrome 下是虚点 double:两根线且为实线 当边框宽度为1px 和 2px 时,其表现和 border-style: solid 是一模一样的当边框宽度不小于 3px 时,才开始有双线边框的表现,包括 retina 屏幕,因为边框宽度是没有半像素的概念的 border-colorborder-color、outline、box-shadow、text-shadow等默认颜色就是 color 色值https://demo.cssworld.cn/4/4-1.php border-color: transparantIE7+ 支持应用场景: 右下方 background 定位增加点击区域大小三角等图形绘制借助 border 生成的梯形实现小圆角效果 https://demo.cssworld.cn/4/4-3.php 实现等高布局 5 内联元素与流 5.1 字母 X 与 CSS 世界的基线 line-height 的定义就是两基线的间距vertical-align 的默认值就是基线 middle 并不是绝对的垂直居中对齐,指的是基线往上 1/2 x-height 高度,可以近似理解为字母 X 交叉点的那个位置 ascender height: 上下线高度 cap height:大写字母高度median:中线baseline: 基线descender height:下行线高度 ex: 相对单位,指的是x-height,即小写字母 x 的高度,使用 ex 单位对齐不受字体和字号的影响内联元素默认是基线对齐的https://demo.cssworld.cn/5/1-1.php 5.2 内联元素的基石 line-height 对于非替换元素的纯内联元素,可视高度完全由 line-height 决定内联元素的高度由固定高度和不固定高度(行距)组成“行距“分散在当前文字的上方和下方,第一行文字的上方也是有”行距“的,只不过是”半行距“行距 =line-height - font-size内容区域(content area): 可以近似理解为浏览器下文本选中带背景色的区域内容区域高度受 font-family 和 font-size 双重影响,而 em-box 仅受 font-size 影响;当字体是宋体时,内容区域和 em-box 是等同的半行距取整处理:如果是文字上边距,则向下取整;如果是文字下边距,则向上取整;因为绝大多数的字体在内容区域中都是偏下的line-height 无法影响替换元素(图片)的高度line-height 对于块级元素是是没有任何作用的,平时改变line-height, 块级元素的高度跟着变化实际上是通过改变块级元素里面内联级别元素占据的高度实现的在 HTLML5 文档模式下,每一个”行框盒子”的前面都有一个宽度为0的“幽灵空白节点”,其内联特性表现和普通字符一模一样line-height 具有继承性让内联元素“近似垂直居中”可以通过设置 line-height 大小和高度一样基于行高实现的多行文字垂直居中效果,需要vertical-align属性帮助。 line-height: 1.5 : 所有的子元素继承的都是这个值,即倍数line-height: 150%; line-height: 1.5em : 所有的子元素继承的是最终的计算值,即具体的px行框盒子的高度是由高度最高的那个“内联盒子”决定的,所以容器块状元素的高度永远都是最大的那个line-height要避免“幽灵空白节点”的干扰,可以设置内联元素 display: inline-block , 创建一个独立的 “行框盒子” 5.3 vertical-align 线类:如 baseline(默认值)、top、middle、bottom文本类:如 text-top、text-bottom上标下标类:如 sub、super数值百分比类:如20px、2em、20% 等 baseline: 内联元素默认是沿着字母X的下边缘对齐的替换元素是使用元素本身的下边缘作为基线 vertical-align 的值:相对于基线,负值是往下偏移,正值是往上偏移;即 baseline 等同于 vertical-align: 0 百分比值: margin 和 padding 相对于宽度计算line-height 相对于 font-size 计算vertical-align 相对于 line-height 计算 vertical-align 属性只能作用于 display 值为: inlineinline-blockinline-tabletable-cell其他块级元素不支持 但是注意浮动和绝对定位会让元素块状化,会导致 vertical-align 不生效 vertical-align 的默认值: 文本内联元素:字符x的下边缘替换元素:替换元素的下边缘inline-block: 如果里面没有内联元素,或 overflow 不是 visible:margin底边缘有内联元素:最后一行内联元素的基线 清除图片产生的间隙的方法: 图片块状化:可以一口气干掉“幽灵空白节点”、line-height、vertical-align容器 line-height 足够小:只要半行间距小到字母 x 的下边缘位置或者再往上,自然就没有了撑开底部间隙高度空间了。比方说,容器设置 line-height: 0容器 font-size 足够小:此方法要想生效,需要容器的 line-height 属性值和当前 font-size 相关,如 line-height: 1.5 或者 line-height: 150% 之类;否则只会让下面的间隙变得更大,因为基线位置因字符x变小而往上升了图片设置其他 vertical-align 属性值:间隙产生原因之一就是基线对齐,所以我们设置 vertical-align 的值为 top、middle、bottom 中的任意一个 最佳图标实践: 图标高度和当前行高都是 20px图标标签里面永远有字符图标 CSS 不使用 overflow: hidden 保证基线为里面字符的基线,但是要让里面潜在的字符不可见 .box { line-height: 20px; } .icon { display: inline-block; width:20px; height:20px; white-space: nowrap; letter-spacing: -1em; text-indent: -999em; } .icon:before { content:'\3000'; } .icon-delete { background: url(delete.png) no-repeat center; } vertical-align: top/bottom 内联元素:元素底部和当前行框盒子的顶部对齐table-cell: 元素底 padding 边缘和表格行的顶部对齐 vertical-align: middle 内联元素:元素的垂直中心点和行框盒子基线往上 1/2 x-height 处对齐table-cell: 单元格填充盒子相对于外面的表格行居中对齐 vertical-align: text-top盒子的顶部和父级内容区域的顶部对齐 假设元素后面有一个和父元素 font-size\font-family 一模一样的文字内容,则 vertical-align: text-top 表示元素和这个文字的内容区域的上边缘对齐 vertical-align: text-bottom盒子的底部和父级内容区域的底部对齐 内容区域:文本选中的背景区域或者默认状态下的内联文本的背景色区域父级内容区域:在父级元素当前 font-size 和 font-family 下应有内容区域大小 6 流的破坏与保护 6.1 魔鬼属性 float浮动的本质就是为了实现文字环绕效果 float 的特性: 包裹性 包裹自适应性 块状化并格式化上下文:display 的计算值是 block 或 table破坏文档流 父级高度坍塌行框盒子区域限制 没有任何 margin 合并浮动元素和内联元素在一行显示 浮动锚点(float anchor):是 float 元素所在的“流”中的一个点,这个点本身并不浮动,就表现而言更像一个没有 margin 、border、和 padding 的空的内联元素。作用就是产生“行框盒子”浮动参考(float reference): 浮动元素对齐参考的实体,float 元素的浮动参考是“行框盒子” 6.2 float 的天然克星 clear 元素自身盒子的边不能和前面的浮动元素相邻,即对后面的元素不闻不问clear 属性只对块级元素才有效,而 ::after 等伪元素默认都是内联水平, 所以伪元素清除浮动影响需要设置display 属性值为块状元素clear: both 作用的本质是让自己不和 float 元素在一行显示,并不是真正意义上的清浮动,因此 float 元素一些不好的特性依然存在 如果 clear: both 元素前面的元素就是 float 元素,则 margin-top 负值即使设置成 -9999px ,也不见任何效果clear: both 后面的元素依旧可能会发生文字环绕的现象 clear: none | left | right | both none: 默认值,左右浮动来就来left:左侧抗浮动right:右侧抗浮动both:两侧抗浮动 6.3 CSS 世界的结界——BFC BFC(block formatting context):块级格式化上下文IFC(inline formatting context):内联格式化上下文 结界:通过一些特定的手段形成的封闭空间,里面的人出不去,外面的人进不来,具有极强的防御力 如果一个元素具有 BFC,内部子元素再怎么翻江倒海都不会影响外部的元素。所以,BFC 元素是不可能发生 margin 重叠的,因为 margin 重叠是会影响外面的元素的;BFC 元素也可以用来清除浮动的影响,因为如果不清除,子元素浮动则父元素高度坍塌,必然会影响后面元素布局和定位,这显然有违 BFC 元素的子元素不会影响外部元素的设定BFC 的结界特性最重要的用途不是去 margin 重叠或者是清除 float 影响,而是实现更健壮、更智能的自适应布局 触发BFC 根元素float 的值不为 none float: left 浮动元素本身 BFC 化,然而浮动元素有破坏性和包裹性,失去了元素本身的流体自适应性。因此无法用来实现自动填满容器的自适应布局。 overflow 的值为 auto、scroll、或 hidden overflow: hidden IE7+;BFC 本身还是一个普通元素,流体特性完好同时具备 BFC 的独立区域特性。唯一的问题是容器盒子外的元素可能会被隐藏掉,一定程度上限制了这种特性的大规模使用。不过溢出隐藏的交互场景比例不算高,因此可作为常用 BFC 布局属性使用。 display 的值为 table-cell、table-caption、inline-block 中的任何一个 display: inline-block IE6 | IE7;会让元素尺寸包裹收缩,即会影响原来的样式布局,不是 block 水平的流动特性;zoom: 1 也是类似的效果display: ``table-cell IE8+;会跟随内部元素的宽度显示,但宽度值设置得再大,实际宽度也不会超过表格容器的宽度;适用场景会比 overflow: hidden 更广泛 position 的值不为 relative、static positon: absolute 脱离文档流有些严重,和非定位元素很难玩到一块去 BFC 自适应布局:普通流体元素在设置了 overflow: hidden 后,会自动填满容器中除了浮动元素以外的剩余空间,形成自适应布局效果,而且这种自适应布局要比纯流体自适应更加智能。比方说,让图片的尺寸变小或变大,右侧自适应内容无须更改任何样式代码,都可以自动填满剩余的空间。 两套自适应解决方案:方案一:如果子元素要定位到父元素的外面可能会被隐藏 .bfc { overflow: hidden; } 方案二:无法直接让连续英文字符换行 .bfc { display: table-cell; width: 9999px; // 如果不需要兼容 IE7,则下面的样式可以省略 display: inline-block; *width: auto; } 连续英文字符无法换行的解决方案: .word-break { display: table; width: 100%; table-layout: fixed; word-break: break-all; } 6.4 最佳结界 overflow overflow: hidden 声明不会影响元素原先的 流体特性 或 宽度表现overflow 属性原本的作用是指定块容器元素的内容溢出时是否需要裁剪,即“剪裁”是其本职工作,“结界”只是其衍生出来的特性 当子元素内容超出容器宽度高度限制的时候,剪裁的边界是 border box 的内边缘,而非 padding box 的内边缘 实现元素剪裁同时四周留有间隙:使用透明边框,此时内间距 padding 属性是无能为力的 浏览器兼容性: chrome 滚动高度包含 padding-bottomIE 和 Firefox 滚动高度不包含 padding-bottom因此在实际开发中,要避免滚动容器设置 padding-bottom 值,除了样式表现不一致,还会导致 scrollHeight 的值不一样 overflow、overflow-x、overflow-y 的属性取值: visible: 默认值hidden:剪裁scroll:滚动条区域一直在auto:不足以滚动时没有滚动条,可以滚动时滚动条出现 永远不可能实现一个方向溢出剪裁或滚动,另一方向内容溢出 除非 overflow-x 和 overflow-y 的值均为 visible,否则 visible 会被当成 auto 来解析 IE8+默认 overflow: auto 的标签, 即默认可以产生滚动条的: PC 端,默认滚动条均来自 去除默认滚动条 html { overflow: hidden; } PC 端窗口滚动高度:document.documentElement.scrollTop移动端窗口滚动高度:document.body.scrollTopPC端:滚动条会占用容器的可用宽度或高度,IE7+、chrome、firefox 滚动条所占据的宽度均是 17px移动端:屏幕尺寸有限,滚动条一般都是悬浮模式,不会占据可用宽度 获取滚动栏占据的宽度: .box { width: 400px; overflow: scroll; } <div class="box"> <div id="in" class="in"></div> </div> console.log(400 - document.getElementById("in").clientWidth); 让页面滚动条不发生晃动: html { overflow-y: scroll; /* for IE8 */ } :root { overflow-y: auto; overflow-x: hidden; } :root body { position: absolute; } body { width: 100vw; overflow: hidden; } 自定义滚动条: ::-webkit-scrollbar { /* 血槽宽度 */ width: 8px; height: 8px; } ::-webkit-scrollbar-thumb { /* 拖动条 */ background-color: rgba(0, 0, 0, .3); border-radius: 6px; } ::-webkit-scrollbar-track { /* 背景槽 */ background-color: #ddd; border-radius: 6px; } 单行文字溢出点点点效果: .ell { text-overflow: ellipsis; white-space: nowrap; overflow: hidden; } 多行文字打点效果: .ell-rows-2 { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; } 锚点定位: 让页面定位到某个位置的点本质是通过改变容器滚动高度(scrollTop)或者宽度来实现scrollHeight: 视区高度 + 可滚动高度clientHeight: 视区高度 触发锚点定位 URL 地址中的锚链与锚点元素对应并有交互行为 让元素定位在浏览器窗体的上边缘<a href="javascript:">返回顶部</a> 可 focus 的锚点元素处于 focus 状态 让元素在浏览器窗体范围内显示即可,不一定是在上边缘document.querySelector('input').focus();“focus 锚点定位” 不依赖于 JS,是浏览器内置的无障碍访问行为 元素设置了 overflow: hidden , 同时高度溢出,滚动依然存在,仅仅滚动条不存在!_选项卡切换效果 div + ainput + label + JSoption + label + :checked 6.5 float 的兄弟 position: absolute 都兼具“块状化”、“包裹性”、“破坏性”等特性由于 absolute 血脉更纯,能力更霸道,因此,当 absolute 和 float 同时存在的时候,float 属性是无任何效果的absolute 的自适应性最大宽度往往不是由父元素决定的,本质上说,是由“包含块”的差异决定的 包含块(containing block): 元素用来计算和定位的一个框 根元素()被称为“初始包含块”,其尺寸等同于浏览器可视窗口的大小对于其他元素,如果该元素的 position 是 relative 或者 static,则“包含块”由其最近的 块容器 祖先盒的 content box 边界形成position: fixed ,则“包含块”是“初始包含块”position: absolute, 则“包含块”是由最近的 position 不为 static 的祖先元素建立的 若有收获,就点个赞吧 0 人点赞 上一篇: 下一篇: Csharp即时消息技术剖析与实战从0打造音视频直播系统从零开始搭建前端监控平台webkit技术内幕云音乐领导力训练营微信公众号运营108招过年乐一乐javascript高级程序设计狼书2透视 HTTP 协议技术人的管理之路《Node.js来一打C++扩展》深入浅出 C++《ES6 标准入门》- 阮一峰学习JS数据结构与算法用户体验相关《你不知道的JS》(上)《文案训练手册》《SVG 精髓》(上)HTML5 Canvas 核心技术(中)Grid 布局基础《Linux Shell 编程从初学到精通》《图解HTTP》《PWA 实战》《正则指引》《React 设计模式与最佳实践》《人人都是产品经理》《精通CSS》第3版React 状态管理与同构实战jQuery 技术内幕重学前端-极客时间WebAssembly标准入门《JS 设计模式与开发实践》《HTML5 Canvas 核心技术》(上)CSS 世界H5 高级程序设计JS 语言精粹HTTP/2 基础教程浅谈项目管理Don't make me think %26 微交互 %26 清醒思考的艺术React前端技术与工程实践Head First Sql深入浅出 webpack前端工程化体系设计与实践了不起的 Node.jsReact 全家桶 %26%26 Node 全栈开发企业级后台电商管理系统React 前端技术与工程实践深入浅出 React 和 Redux《狼书1》 暂无相关搜索结果! 让时间为你证明 分享,让知识传承更久远 × 文章二维码 × 手机扫一扫,轻松掌上读 文档下载 × 请下载您需要的格式的文档,随时随地,享受汲取知识的乐趣! PDF文档 EPUB文档 MOBI文档 书签列表 × 阅读记录 × 阅读进度: 0.00% ( 0/0 ) 重置阅读进度 × 思维导图备注