libin1991 / libin_Blog

爬虫-博客大全
https://libin.netlify.com/
124 stars 17 forks source link

《css世界》的那些实用技巧 #460

Open libin1991 opened 6 years ago

libin1991 commented 6 years ago

下面所有的内容都来至张鑫旭所著的《css世界》。

《css世界》这是一本专门写css的书,书中并没有涉及css3的知识,但是它所展现的东西很多都是我从未知道或以前未重视的。这是一本能够开阔视野的书,我把这本书推荐所有从事前端的人。

下面都是我在看这本书所记录的一些新奇但实用的布局技巧。

max-width

  1. max-系列的权重非常的高,甚至超越了!important。如下代码p最后的宽度是150px
p {
  width: 200px !important;
  max-width: 150px;
}
  1. min-widthmax-width大小有冲突的时候会采用最大原则,即谁大取谁的值。如下代码最后的宽度是1400px
.container {
  min-width: 1400px;
  max-width: 1200px;
}
  1. 当我们实现一个元素高度逐渐变大的效果,但是我们又不知道这个元素的具体高度,这个时候我们就可以用max-height 的方式。我们不需要给以具体高度值就可以实现这个效果。当然这样做会出现元素高度达到实际高度但是动画还没结束。会有动画延迟的感觉。
.element {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.25s;
}
.element.active {
  max-height: 666px; /* 一个足够大的最大高度值 */
}

content attr

类似于img的 alt。

.icon:before {
  content: attr(data-title);
}

padding 与 margin

这种三道扛的效果我们经常要遇到,我们可以借助 background-clippadding 实现这种效果。不需要任何图片。

.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;
}

当我们要实现这种两端对齐的效果,我们给每一个列表都设置margin-right然后去掉最后一个的margin-right。实现这种效果需要借助css3的新增选择器,有时候还需要js,或者直接用flex布局。但我们利用给父级margin 负值就可以轻松实现。

ul {
  margin-right: -20px;
}
ul > li {
  float: left;
  width: 100px;
  margin-right: 20px;
}

border

  1. 因为 ie6 下 border 设置虚线显示的是圆点。所有用这种方法可以在ie6下实现一个圆。
.box {
  width: 150px;
  height: 150px;
  /* 超出区域隐藏,只显示一个圆 */
  overflow: hidden;
}
.dotted {
  width: 100%;
  height: 100%;
  border: 149px dotted #cd0000;
}

利用边框制作三角形其实是一个广为人知的方法,还是写一下吧。

注意:边框也是css标准的上右下左的设置顺序,需要上面方向的三角形就给它相反的方向设置想要的颜色,其他方向都设为透明色。

div {
  width: 0;
  border: 10px solid;
  border-color: #f30 transparent transparent;
}

ex

ex是一个被忽略的距离单位,它表示一个小写字母x(x、y、z的x)的高度。是一个相对单位,它和父元素的字号有关系。

这种图标和字垂直居中的布局我们经常见到,只要这样设置就可以简单实现,而且还不会受字号,页面高度的影响。

.icon-arrow {
  display: inline-block;
  width: 20px;
  height: 1ex;
  background: url(xxx.png) no-repeat center;
}

vertical-align

可以利用 vertical-align 实现水平垂直居中,这种定位方法不用知道居中元素的宽高度,兼容ie6

下面模拟的是一个全屏的对话框。这种居中方法核心是父元素的text-aglin:center,在写一个居中元素的兄弟元素给与display: inline-block;height: 100%;vertical-align: middle;三个属性,自身设置display: inline-block; vertical-align: middle;

<div id="container">
  <div id="dialog">....</div>//要居中的元素
  <div id="assist"></div>
</div>
#container {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: rgba(0, 0, 0, 0.5), none;
  text-align: center;
  white-space: nowrap;
  font-size: 0;
  z-index: 99;
}
#dialog {
  display: inline-block;
  vertical-align: middle;
}
#assist {
  display: inline-block;
  height: 100%;
  vertical-align: middle;
}

BFC

以前就知道overflow:hidden一种触发BFC的方法,其实以下都能出发BFC。

  • <html>根元素;
  • float 的值不为 none;
  • overflow 的值为 auto、scroll 或 hidden;
  • display 的值为 table-cell、table-caption 和 inline-block 中的任何一个;
  • position 的值不为 relative 和 static。

overflow

  1. 滚动条是html所产生的所有想要页面禁止出现滚动条没必要拉着body一起设置overflow:hidden

  2. 当页面加载非常慢的时候会出现页面向左偏移的情况,因为滚动条占据了body的宽度导致body偏移。下述代码是让body占据整个 window 的宽度。这样不会出现页面加载慢时导致居中元素偏移的问题。(现在用户宽带大幅度提升基本上不会有这种情况了)

html {
  overflow-y: scroll; /* for IE8 */
}
:root {
  overflow-y: auto;
  overflow-x: hidden;
}
:root body {
  position: absolute;
}
body {
  width: 100vw;
  overflow: hidden;
}

absolute

当我使用绝对定位的时候,总会老老实实的子决父相。但是无依赖的绝对定位效果会更好。

无依赖的布局方,即不使用传统的子决父相的方式。不使用lefttop控制,用 margin 或者 transform 来控制位置。

.icon-warn {
  position: absolute;
  margin-left: -20px;
  width: 20px;
  height: 20px;
  background: url(warn.png) no-repeat center;
}
  1. absolute 与 text-align 相配合实现水平居中。

代码如下

<p > <img src="1.jpg" > </p > 
p {
  text-align: center;
}
img {
  position: absolute;
  margin-left: ...;
}

虽然本示例中图片位置确实受 text-align 属性影响,但是并不是 text-align 和 absolute 元素直接发生关系,absolute 元素的 display 计算值是块状的,text-align是不会有作用的。这里之所以产生了位置变化,本质上是“幽灵空白节点”和“无依赖绝对定位”共同作用的结果


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


当然我们是需要知道内联元素的宽度的。margin-left的值与负的一般宽度。与父元素position:relative 然后定位元素设置left:50%的方法类似。但不会有层级问题。


2. absolute 与 overflow 关于绝对定位元素是否会受到`overflow`的影响有如下判断

overflow 不是定位元素,同时绝对定位元素和 overflow 容器之间也没有定位元素 如果 ,则overflow 无法对 absolute 元素进行剪裁。

根据上述所言。无依赖的absolute不会被父级的overflow所裁剪。

注意:由于 transform 在各个浏览器对overflow的支持不一样所以当元素还是被裁剪的话,试着找找是不是transform的原因


3. absolute 与流体自适应

当一个绝对定位元素的相对方向都有定位的时候该元素就会拥有一种和文档流相似的流体特性如

.box {
position: absolute;
left: 0; right: 0;
}

当一个绝对定位元素有如下的设置就能覆盖整个浏览器。注意它的宽度高度是一种"格式化宽度/高度",于width:100%完全不同。给与margin也不会出现超出屏幕。

.box {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
}

根据上面所说可以使用margin:auto实现水平居中的效果,如果有没有left: 0; right: 0;这种能够激发流体特性的属性就不会有这种居中效果。当然想要用margin:auto auto实现垂直水平居中是不能的。毕竟在标准文档流也没有这种效果。

代码如下

.element {
  width: 300px;
  height: 200px;
  position: absolute;
  left: 0;
  right: 0;
  margin: auto;
}

fixed

fixed也可以用无依赖布局,如下实现一个在元素内部的固定定位

<div class="father" > 
    <div class="son" > </div > 
</div >
.father {
  width: 300px;
  height: 200px;
  position: relative;
}
.son {
  width: 40px;
  height: 40px;
  position: fixed;
  margin-left: -40px;
}

与绝对定位的无依赖一样不能使用left等定位属性。

获取滚动条宽度

如下代码可以获取滚动条宽度,避免了禁用滚动条之后的页面偏移现象。

//显示
var widthBar = 17,
  root = document.documentElement;
if (typeof window.innerWidth == "number") {
  widthBar = window.innerWidth - root.clientWidth;
}
root.style.overflow = "hidden";
root.style.borderRight = widthBar + "px solid transparent";
//隐藏
var root = document.documentElement;
root.style.overflow = "";
root.style.borderRight = "";

z-index

z-index在css2 中只对定位元素有用但是在 css3 中加入了对flex的支持

font-size

这种效果也可以借助vertical-alignfont-size实现。

p {
  font-size: 16px;
  line-height: 1.5;
}
p > img {
  vertical-align: -25%;
  vertical-align: 0.6ex;;
}

子元素vertical-align使用百分比可以实现图标与文字居中的问题而且不受字体大小的影响,但是会受到行高的影响。如果是 ex 不仅可以实现而且不会受到行高的影响。

text-decoration

在中文下text-decoration有可能与下一行的字出现重叠这时候我们用边框来作为下划线,边框不要设置颜色,它会默认的和字体一个颜色。

显示与隐藏

利用visibility和绝对定位来实现隐藏而且不占位置。或者透明度加绝对定位

.hidden {
  position: absolute;
  visibility: hidden;
}

.opacity {
  position: absolute;
  opacity: 0;
  filter: Alpha(opacity=0);
}

visibility 与 display 的小区别

visibility的子元素会被隐藏但是如果设置了visibility:visible就会显现出来,但是display:none的元素就没有这样的效果。

这些就是我阅读《css世界》所学到的技巧,更多内容请阅读原书





引用: 《css世界》