显示 / 隐藏 文章目录 ]

css奇技淫巧

上次更新: 2023-12-26 12:54:48

grid 布局

flex 布局操纵的是一维、一行/一列,grid 布局具备操纵二维的能力

设为网格布局以后,容器子元素(项目)的floatdisplay: inline-blockdisplay: table-cellvertical-aligncolumn-等设置都将失效。

  • grid-template-columns: 定义每一列的列宽
  • grid-template-rows: 定义每一行的行高
  • grid-row-gap: 行间距
  • grid-column-gap: 列间距
  • grid-gap: 行列间距合并
  • grid-template-areas: 一个区域由单个或多个单元格组成
  • grid-auto-flow: 默认值是 row,即”先行后列”,即先填满第一行,再开始放入第二行
  • justify-items: 单元格内容的水平对齐
  • align-items: 单元格内容垂直对齐
  • place-items: align-items 属性和 justify-items 属性的合并简写形式
  • justify-content: 整个内容区域水平对齐
  • align-content: 整个内容区域垂直对齐
  • place-content: align-content 属性和 justify-content 属性的合并简写形式

设置的行或者列比较多的时候,可以使用 repeat()这个函数简化重复的值

repeat()

第一个参数是重复的次数,第二个参数是所要重复的值、也可以是某个模式

/* 重复 3个100px的列 */
grid-template-columns: repeat(3, 100px);
/* 重复这种布局2次 */
grid-template-columns: repeat(2, 100px 20px 80px);
/* 自动填充,直到容器放不下为止 */
grid-template-columns: repeat(auto-fill, 100px);

fr

方便表示比例关系,网格布局提供了 fr 关键字

grid-template-columns: 1fr 1fr;

grid-template-areas

grid-template-areas:
  "header header header"
  "main main sidebar"
  "footer footer footer";

item 定位

grid_1

/* 1号项目就是从第二根垂直网格线开始第四根结束 */
.item1 {
  grid-column-start: 2;
  grid-column-end: 4;
  background: red;
}

硬件加速(IE9+)

移动端开启,吃内存、增加耗电

animationtransformtransition不会自动开启GPU加速,利用transform: translateZ(0) 就可以开启3D变换,出发硬件加速

场景:webKit内核偶尔页面闪烁:transform: translate3d(0, 0, 0);

控制台打印 shield 徽章

console.log(
  "%c" +
    eval("'mozzie.com'") +
    "%cv" +
    eval("'2.0.0'") +
    "%c\r\n" +
    eval("'了解更多:https://www.mozzie.com'"),
  "color: #fff; background: #5281FA; font-size: 12px;border-radius:2px 0 0 2px;padding:3px 6px;",
  "border-radius:0 2px 2px 0;padding:3px 6px;color:#333;background:#EBEBEB",
  "margin-top:10px;"
);

css 判断 input 是否为空

:placeholder-shown:占位符是否显示的伪类,配合 :not() (不是必须,反过来也可以)

<div id="demo">
  <input id="demo-input" type="text" placeholder="name" />
  <label id="demo-label">Name</label>
</div>
#demo {
  width: 90%;
  max-width: 450px;
  position: relative;
}
#demo-input {
  width: 100%;
  height: 60px;
  line-height: 60px;
  font-size: 20px;
  border-bottom: 1px solid #ffa500;
}
#demo-input::placeholder {
  font-size: 0;
}
#demo-input:focus + label,
#demo-input:not(:placeholder-shown) + label {
  top: 0;
  font-size: 12px;
}
#demo-label {
  font-size: 22px;
  color: #ffa500;
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  transition: all 0.3s;
}
/*
* Default
*/
body {
  height: 100vh;
  display: flex;
}
body div {
  margin: auto;
}
body div input {
  border: 0;
  outline: 0;
}

居中

transform 大法

#wrapper {
  position: relative;
}
#box {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

0000 大法

#wrapper {
  position: relative;
}
#box {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}

如何让 img 垂直居中

<div id="imgWrapper">
  <img src="xxx.png" />
</div>
.imgWrapper {
  display: table-cell;
  text-align: center;
  vertical-align: middle;
}

ul 下 li 居中

<!--外层包个div/section block元素 -->
<div>
  <ul class="clearfix">
    <li>1</li>
    <li>2</li>
  </ul>
</div>
div{
  text-align: center
}
ul{
  display: inline-block
}
li{
  display: inline
  float: left
}

js 随机渐变背景

function getRandomRangeNum(min, max) {
  return min + Math.floor(Math.random() * (max - min));
}

function setRandomBg(el) {
  var left = getRandomRangeNum(0, 255);
  var bottom = getRandomRangeNum(0, 255);
  var css = [
    "linear-gradient(to left bottom,hsl(",
    left,
    ", 100%, 85%) 0%,hsl(",
    bottom,
    ", 100%, 85%) 100%)",
  ];
  el.style.background = css.join("");
}

css 三角形

span {
  width: 0;
  height: 0;
  border-top: 40px solid transparent;
  border-left: 40px solid transparent;
  border-right: 40px solid transparent;
  border-bottom: 40px solid #ff0000;
}

1px 神迹

pc 端最优解

<div style="height:1px;overflow:hidden;background:red"></div>

移动端 - 媒体查询 + transform

@media only screen and (-webkit-min-device-pixel-ratio: 2) {
  .border-bottom::after {
    -webkit-transform: scaleY(0.5);
    transform: scaleY(0.5);
  }
}

移动端 - 媒体查询 + 伪类

.border__1px:before {
    content: '';
    position: absolute;
    top: 0;
    height: 1px;
    width: 100%
    background-color: #000;
    transform-origin: 50% 0%;
}
@media only screen and (-webkit-min-device-pixel-ratio:2) {
    .border__1px:before {
        transform: scaleY(0.5)
    }
}
@media only screen and (-webkit-min-device-pixel-ratio:3) {
    .border__1px:before {
        transform: scaleY(0.33)
    }
}

横竖屏适配

js 检测

window.addEventListener("resize", () => {
  if (window.orientation === 180 || window.orientation === 0) {
    // 正常方向或屏幕旋转180度
    console.log("竖屏");
  }
  if (window.orientation === 90 || window.orientation === -90) {
    // 屏幕顺时钟旋转90度或屏幕逆时针旋转90度
    console.log("横屏");
  }
});

css 检测

@media screen and (orientation: portrait) {
  /*竖屏...*/
}
@media screen and (orientation: landscape) {
  /*横屏...*/
}

像素

  • 物理像素: 物理设备真实的像素
  • 独立像素: 平时开发写的 px
  • 设备像素比(DPR): = 物理像素 / 设备独立像素
// 获取 DPR
window.devicePixelRatio;

也可以使用媒体查询

@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2) {
}

srcset

使用 img 标签的 srcset 属性,浏览器会自动根据像素密度匹配最佳显示图片:

<img src="conardLi_1x.png" srcset="conardLi_2x.png 2x, conardLi_3x.png 3x" />

字体小于 12px

css3 的 transform 属性,设置值为 scale(x, y) 定义 2D 缩放转换

css 清浮动

.clearfix::after {
  content: "";
  display: block;
  clear: both;
}

ellipsis

单行

.ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

多行

.ellipsis {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3; // 最多显示几行
  overflow: hidden;
}

页面导入样式时,使用 link 和 @import

你可能不信,ie5+就支持@import 了

  • link: 与dom异步加载
  • @import: 先加载dom

em | rem 换算

相对于HTML根元素 font-size 来确定的,浏览器的默认字体高是 16px,因此:

  • 16px = 1em
  • 12px = .75em
  • 10px = .625em

简化 rem 到 px 的换算,因为每个 rem 单位都是 10px 的倍数

html {
  font-size: 62.5%; /* 这会将默认的 16px 缩小为 10px */
}

也可以使用 js 检测设置

// set 1rem = viewWidth / 10
function setRemUnit() {
  var docEl = document.documentElement;
  var rem = docEl.clientWidth / 10;
  docEl.style.fontSize = rem + "px";
}

window.addEventListener("resize", setRemUnit);
window.addEventListener("pageShow", function (e) {
  if (e.persisted) setRemUnit()
});

less 常用

变量

LESS 中的变量为完全的 常量 ,所以只能定义一次

@nice-blue: #5B83AD;
@light-blue: @nice-blue + #111;

#header {
  color: @light-blue;
}

输出

#header {
  color: #6c94be;
}

混合

.bordered {
  border-top: dotted 1px black;
  border-bottom: solid 2px black;
}

使用

#menu a {
  color: #111;
  .bordered;
}
.post a {
  color: red;
  .bordered;
}

带参

.border-radius (@radius) {
  border-radius: @radius;
  -moz-border-radius: @radius;
  -webkit-border-radius: @radius;
}

#header {
.border-radius(4px);
}

@arguments变量,包含了所有传递进来的参数. 如果你不想单独处理每一个参数

.box-shadow (@x: 0, @y: 0, @blur: 1px, @color: #000) {
  box-shadow: @arguments;
  -moz-box-shadow: @arguments;
  -webkit-box-shadow: @arguments;
}
.box-shadow(2px, 5px);

无参

.wrap () {
  text-wrap: wrap;
  white-space: pre-wrap;
  white-space: -moz-pre-wrap;
  word-wrap: break-word;
}

pre {
  .wrap;
}

lighten 和 darken

@color-base: #3bafda;
@color-hover:lighten (@color-primary,10%);
@color-focus:darken (@color-primary,10%);

contrast

选择两种颜色中哪一种颜色与另一种颜色形成最大对比。

p {
  a: contrast(#bbbbbb); //output: black
  b: contrast(#222222, #101010); //output: white
}

JavaScript 表达式

@var: ` "hello" .toUpperCase() + "!" `;
@height: `document.body.clientHeight`;

& 父选择器

& 只能代表父元素,不能代表父亲的父辈元素,施加改性类或伪类

a {
  color: blue;
  &:hover {
    color: green;
  }
}

重复父类名

.button {
  &-ok {
    background-image: url("ok.png");
  }
  &-cancel {
    background-image: url("cancel.png");
  }

  &-custom {
    background-image: url("custom.png");
  }
}

重拾纯粹的写作