CSS中的一些小细节

1、CSS排版原理

box

box-sizing

  • 改变盒模型计算方式
  • 取值:border-box | content-box
  • 初始值:content-box

举个例子:css

<div class="box a">Box A</div>
<div class="box b">Box B</div>

<style>
  .box {
    width: 100px;
    height: 100px;
    padding: 10px;
    border: 10px solid #f66;
    background: #f99;
    margin: 1em;
  }
  .b {
    box-sizing: border-box;
  }
</style>

演示结果:html

box

box-sizing mdn文档css3

2、一些容易被忽视的小细节

2.1 下面代码,p标签的高度是多少?

<p>Some text</p>

<style>
p {
  height: 100%;
  background: red;
}
</style>

解析:默认状况下body是没有高度只有宽度。因此p标签的父级是body默认高度为0,因此p的高度也是0。
解决办法:能够设置height: 100vh,使用一些屏幕的单位如vh vw,一个屏幕的高度是100vhcanvas

2.2 下面代码中padding-top值多少?

<div> </div>

<style>
  div {
    background: red;
    padding-top: 100%;
  }
</style>

以上代码padding-top等于父容器body的宽度,实现了一个响应式的正方形 浏览器

解析:padding不论是padding-top仍是padding-left,它的百分比都是根据父容器的'宽度'来决定的。ide

使用场景:能够利用padding的百分比来作出一些固定宽高比的盒子。svg

2.3 Margin Collapse 合并

<div class="a"></div>
<div class="b"></div>

<style>
  .a{
    background: lightblue;
    height: 100px;
    margin-bottom: 100px;
  }
  .b {
    background: coral;
    height: 100px;
    margin-top: 100px;
  }
</style>
  • 之前是为了让报纸、排版而设定的
  • a与b之间的高度仍是100px,这就是margin合并。

2.4 利用border能够制做任意角度的三角形

<div class="box"></div>

<style>
  .box {
    border-width: 50px;
    border-style: solid;
    border-color: #f35 #269 #649 #fa0;
    width: 0px;
    height: 0px;
    margin: 1em auto;
  }
</style>

border

经过给border的其余的三条边设置透明色,就能够制做任意角度的三角形。布局

思考题:这个图标怎么作?字体

reat

方法1:使用border构造相间的三角形,而后使用overflow-hiddenborder-radius剪裁成圆。另外注意水平、垂直居中的实现方式。flex

<div id="warning">
  <div class="bg"></div>
  <div class="bg"></div>
  <div class="bg"></div>
</div>

<style>
#warning {
  position: relative;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 200px;
  height: 200px;
  overflow: hidden;
  border-radius: 50%;
}

#warning .bg {
  position: absolute;
  width: 0;
  height: 0;
  top: -73.2px;
  left: 0px;
  border-top: solid 173.2px rgb(246, 226, 54);
  border-left: solid 100px transparent;
  border-bottom: solid 173.2px black;
  border-right: solid 100px transparent;
} 

#warning .bg:nth-child(1) {
  transform: rotate(0deg);
} 

#warning .bg:nth-child(2) {
  transform: rotate(120deg);
} 

#warning .bg:nth-child(3) {
  transform: rotate(240deg);
}
</style>

方法2:利用svg的虚线来作,这个方法比较灵巧,不容易理解,请屡次调试stroke和stroke-dasharray的值加深理解。

<svg viewBox="0 0 64 64" class="warning">
  <circle r="25%" cx="50%" cy="50%"/>
</svg>

<style>
.warning {
  width: 300px;
  background: black;
  border-radius: 50%;
}

.warning circle {
  fill: none;
  stroke: yellow;
  stroke-width: 32;
  stroke-dasharray: 26%;
}
</style>

方法3:利用css3新特性:锥形渐变。

<div></div>

<style>
div {
  padding-top: 100%;
  background: repeating-conic-gradient(black 0 60deg, yellow 0 120deg);
  border-radius: 50%;
}
</style>

方法4:也可使用canvas和js等等。

3、视觉格式化模型

  • 视口(viewport): 浏览器的可视区域
  • 块级元素

    • 会被格式化成块状的元素
    • 例如 p div section
    • display设置为blocklist-itemtable将元素变为块级
  • 行级元素

    • 不会为其内容生成块级框
    • 让其内容分布在多行中
    • display设置为inlineinline-blockinline-table使元素变为行级
  • 盒子的生成

    • 每一个块级元素生成一个主块级盒,用它来包含子级盒
    • 每一个行级元素生成一个行级盒,行级盒分布于多行
  • 块级盒子中的子盒子的生成

    • 块级盒子中能够包含多个子块级盒子
    • 也能够包含多个行级盒子
    • 不在行级元素里面的文字,会生成匿名行级盒。好比 <p>Some <em>Text</em></p>,some在块级盒子里,而且没有被行级元素包裹,因此会生成匿名的行级盒子。
    • 块级盒子中不能同时包含块级和行级盒子。遇到这种状况时,会生成匿名块级盒来包含行级盒。好比 <div><h1>标题</h1><span>2018-5-12</span></div>
  • 行级盒子内的子盒子的生成

    • 行级盒子内能够包含行级盒子
    • 行级盒子包含一个块级盒子时,会被块级盒子拆成两个行级盒子,这两个盒子又分别被匿名块级盒包含。

举个栗子🌰:

<span>
    aaaaa
    <div>
        bbb
    </div>
    ccc
</span>

img

行级盒子spandiv分割成两个行级盒子aaa,bbb,这两个行级盒子又被匿名块级盒子包含,因此呈三个块级元素布局。

  • display属性

    • block 生成块级盒
    • inline 生成行级盒
    • inline-block 生成行级盒,里面内容能够是块级盒
    • none 在排版时将元素忽略
  • 经过css生成盒子

    • ::before 在元素内部的前面添加一个行盒
    • ::after 在元素内部的后面添加一个行盒
    • display:list-item 这个就是列表前方的小圆点,就是给li前面添加一个行盒,生成小圆点。

举个栗子🌰

<p><span>Learn to Code HTML & CSS is a simple and comprehensive
guide dedicated to helping beginners learn HTML and CSS.
Outlining the fundamentals, this guide works through all common
elements of front-end design and development.</span></p>

<style>
  p {
    line-height: 2;
    padding: 1em;
    border: 2px solid #00f;
    background: #ccf;
  }
  span {
    background: #fcc;
    border: 2px solid #f00;
  }
</style>

img

块级盒子能够包含多个行级盒子,行级盒子能够分布多行。

4、定位模式

  • 常规流
  • 浮动
  • 绝对定位

4.1 常规流

  • 除根元素、浮动元素和绝对定位元素外,其它元素都在常规流以内(in-flow)
  • 而根元素、 浮动和绝对定位的元素会脱离常规流(out of flow)
  • 常规流中的盒子,属于块级格式化上下文或行级格式化上下文

4.2 块级格式化上下文

  • Block Formatting Contex (BFC)
  • 盒子在容器(包含块)内从上到下一个接一个地放置
  • 两个兄弟盒之间的竖直距离由 margin 属性决定
  • 同一个 BFC 内垂直 margin 会合并
  • 盒子的左外边缘挨着容器(包含块)的左边

4.3 行级格式化上下文

  • Inline Formatting Context (IFC)
  • 盒子一个接一个水平放置
  • 盒之间的水平 marginborderpadding都有效
  • 同一行的盒子所在的矩形区域叫行盒(Line box)
  • 当一个行盒放不下上下文内全部盒子时,会被分到多个垂直堆叠的行盒里
  • 行盒内的水平分布由text-align属性决定
  • 若是一个行级块没法分割(单词、inline-block),该元素会被做为一个总体决定分布在哪个行盒

4.4 float

  • 浮动元素从常规流中脱离,被漂浮在容器(包含块)左边或右边
  • 浮动盒会一直漂到其外边缘挨到容器边缘或另外的浮动盒
  • 浮动元素不会影响其后面的流内块级盒
  • 可是浮动元素后面的行级盒子会变短以避开浮动元素

总结一下:浮动元素后面的块级元素不会‘发现’浮动元素,而行级盒子会避开前面的浮动元素。

举个栗子🌰:

<section>
  <img src="http://p0.qhimg.com/t0117c2689d8703d551.jpg"
    width="120" alt="house">
  <p><span>莫哈韦沙漠不只纬度较高,并且温度要稍微低些,是命名该公园的
  短叶丝兰——约书亚树的特殊栖息地。约书亚树以从茂密的森林到远远
  间隔的实例等各类形式出现。除了约书亚树森林以外,该公园的西部包
  括加州沙漠里发现的最有趣的地质外观。</span></p>
</section>

<style>
  img {
    float: left;
  }
  p {
    font-size: 14px;
    line-height: 1.8;
    border: 1px solid;
  }
</style>

代码演示
img

解释一下:
上述代码中,<p>没有由于<img>的而影响定位,<p>并无‘发现’<img>图片,而<span>里的文字‘避开’了<img>

利用float能够作图文混排效果

4.5 clear

  • 指定元素哪一边不能与以前的浮动框相邻
  • 取值: left | right | both

4.6 清除浮动

  • 最经常使用的清除浮动的方法 clearfix
/* 凡是遇到清除浮动,就这么写 */ 
.clearfix::after {
  content: ' ';
  display: block;
  clear: both;
  height:0;
  overflow: hidden;
}
  • 下面这些属性会触发bfc,bfc里面的浮动不会溢出影响外部的盒子的排版,这样与清除浮动的效果是同样的。

    • overflow: hidden/auto
    • display: inline-block
    • float: left/right

4.7 块级格式化上下文(BFC) 的特性

  • BFC 内的浮动不会影响到BFC外部的元素
  • BFC 的高度会包含其内的浮动元素
  • BFC 不会和浮动元素重叠
  • BFC 能够经过 overflow:hidden 等方法建立

4.8 BFC 的建立

  • 浮动框
  • 绝对定位框
  • 非块级的块容器 inline-block
  • overflow 属性非 visible 的块框

4.9 BFC的做用

bfc就是为了把本身里面的东西‘封闭’起来,不与外界作过多的‘干扰’。

  • 清除浮动
  • 防止 margin 折叠
  • 两栏布局

5、定位和堆叠

  • position

    • static 非定位,默认值
    • relative 相对定位(相对本身)
    • absolute 绝对定位,相对非 static 祖先元素定位
    • fixed 相对于视口绝对定位
  • z-index 堆叠层次

    • 为定位元素指定其在 z 轴的上下等级
    • 用一个整数表示,数值越大,越靠近用户
    • 初始值为 auto,能够为负数、0、正数

5.1 思考一个问题:是否是z-index越大,就越在上面呢?

来看下面一坨代码,重点看有z-index的元素

<nav>
  <ul>
    <li>z-index: 2</li>
  </ul>
</nav>

<div id="dialog">
  z-index: 1
</div>

<style>
  nav {
    position: fixed;
    top: 0;
  }
  nav ul {
   position: absolute;
    z-index: 2;
    top: 0;
    left: 0;
    background: red;
    padding: 1em;
    width: 10em;
  }
  #dialog {
    position: absolute;
    z-index: 1;
    top: 5em;
    left: 5em;
    background: blue;
    height: 10em;
    width: 10em;
  }

  body {
    color: #fff;
  }
  li {
    margin: 1em 0;
    list-style:none;
  }
  #dialog {
    padding: 1em;
  }
  ul {
    padding: 1em;
  }
</style>

5.2 结果为何是z-index: 1在上面呢?

img

  • 在排版的时候,浏览器不仅是比较z-index的值,是比较同一个堆叠上下文的z-index的值的大小。
  • 上述例子中,应该是<nav>div#dialog比较,<nav>中的z-index是默认值auto, div#dialog中的z-index1,因此蓝色框在上面。nav里面的元素的z-index再大也不能排在上面,由于他的父级‘不行’😁😀。
  • 可是若是把nav里的position设置为absolute呢?你能够试试改一下上面的代码,得出结果是否是大吃一惊呢?为何红色就上去了呢?

img

  • 由于positionfixedsticky 的元素不用z-index就会建立堆叠上下文,这样<div><nav>进行z-index比较。
  • positiong:absolute的元素须要同时设定z-index才会建立堆叠上下文,nav中没有设置z-index,因此不会建立堆叠上下文,而<nav>里面的<ul>既包含了定位与z-index属性,因此div就会和<nav>里面的<ul>做比较,这样红色框会在蓝色框上面。

5.3 建立堆叠上下文

  • Root 元素
  • relative 或 absolute 且 z-index 不是 auto 的元素
  • position 为 fixed 或 sticky 的元素
  • 设置了某些 CSS3 属性的元素,好比 opacity、transform、animation、will-change 等
  • flexbox 的子元素且 z-index 不是 auto

有以上特色的都会建立堆叠上下文

5.4 绘制层级

在每个堆叠上下文中,从下到上:

  • 造成该上下文的元素的 border 和 background
  • z-index 为负值的子堆叠上下文
  • 常规流内的块级元素非浮动子元素
  • 非定位的浮动元素
  • 常规流内非定位行级元素
  • z-index 为 0 的子元素或子堆叠上下文
  • z-index 为正数的子堆叠上下文

6、行内排版

6.1 全部的文字都是基于baseline来排版的。

img

6.2 line-height

img

6.3 line-box中盒子摆放

img

  • 对于图片、不一样的文字都是基于同一个baseline来布局
  • 图片的baseline是图片的底边
  • 对于inline-block的盒子,他是基于文字的最后一行的baseline来摆放

若是想改变对齐方式怎么办呢?

6.4 vertical-align 垂直对齐关系

  • 定义盒子所处的行盒(line box)的垂直对齐关系
  • 取值:baseline | sub | super | top | text-top | middle | bottom | text-bottom | <percentage>| <length>
  • 百分比相对于元素自身的行高
  • 初始值 baseline

img

由上图举例说明:

  1. 首先给这些元素画一个baseline(基线),baseline的肯定是按照父级盒子的字体的大小来肯定的。
  2. 若是给文字设置成vertical-alignmiddle,middle这根线的位置是x-height的一半(x-height在font-metrics图片中有定义)。
  3. 若是行盒Text设置成vertical-align设置为text-top,那么它的上边缘与text-top这条线对齐。
  4. 其余同理。

6.5 举个栗子🌰

<p>
  <img 
    src="https://p5.ssl.qhimg.com/t013753a42172e3170a.jpg"
    alt="car"
    width="400"
  />
</p>

<style>
  p {
    padding: 0;
    background: red;
  }
</style>

代码演示:

img

能够看出img图片是基于p标签中的文字基线来排版的,那么如何让图片下面这段红线去掉呢?

  1. 能够将img设置成block,这样块级与块级就不会涉及(行内排版)这种状况。
  2. 能够给p设置vertical-align设置middle属性,这样img的中线与p的中线对齐,就不会出现这种问题

7、水平方向的对齐方式

  • text-align
  • 定义文本在容器内的对齐方式
  • 取值:left | right | center | justify(两端对齐)
  • 初始值由 HTML 的 dir 属性决定,可继承

7.1 看一下这坨代码中text-align: justify生效了么?

<nav>
  <a href="#">Home</a>
  <a href="#">Products</a>
  <a href="#">Contact</a>
  <a href="#">Help</a>
</nav>

<style>
nav {
  text-align: justify;
  background: #dcc
}
nav a {
  display: inline-block;
  line-height: 3;
}
</style>

img

答案是并无,这是由于什么呢?由于nav中的文字仅仅只有一行,它是第一行也是最后一行,text-align:justify不会对最后一行起做用。

img

css为何要这样设置呢?

咱们能够想一下,若是咱们有多行文字,最后结尾的文字大多数都是少于一行的,若是css对于最后一行文字也进行两端对齐的话,岂不是很丑。。。

像这样:
img

因此css不给最后一行文字进行两段对齐。

7.2 若是咱们要强制让最后一行两端对齐呢?

可使用text-align-last:justify, 能够给最后一行文字设置两端对齐。

8、最后

若是对你有所帮助,请点个赞呀~~

若是想对css想深刻了解能够看看张鑫旭老师的博客,关注奇舞周刊~

相关文章
相关标签/搜索