---
title: css奇技淫巧
categories:
- Front-End
status: doing
---
# grid 布局
> flex 布局操纵的是一维、一行/一列,grid 布局具备操纵二维的能力
设为网格布局以后,容器子元素(项目)的`float`、`display: inline-block`、`display: table-cell`、`vertical-align`和 `column-`等设置都将失效。
- 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()
第一个参数是重复的次数,第二个参数是所要重复的值、也可以是某个模式
```css
/* 重复 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 关键字
```css
grid-template-columns: 1fr 1fr;
```
## grid-template-areas
```css
grid-template-areas:
"header header header"
"main main sidebar"
"footer footer footer";
```
## item 定位
![grid_1](/img/grid_1.png)
```css
/* 1号项目就是从第二根垂直网格线开始第四根结束 */
.item1 {
grid-column-start: 2;
grid-column-end: 4;
background: red;
}
```
# 硬件加速(IE9+)
> 移动端开启,吃内存、增加耗电
`animation`、`transform`、`transition`不会自动开启`GPU`加速,利用`transform: translateZ(0)` 就可以开启`3D变换`,出发硬件加速
场景:`webKit内核`偶尔页面闪烁:`transform: translate3d(0, 0, 0);`
# 控制台打印 shield 徽章
```js
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()` (不是必须,反过来也可以)
```html
```
```css
#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 大法
```css
#wrapper {
position: relative;
}
#box {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
```
## 0000 大法
```css
#wrapper {
position: relative;
}
#box {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
```
## 如何让 img 垂直居中
```html
```
```css
.imgWrapper {
display: table-cell;
text-align: center;
vertical-align: middle;
}
```
## ul 下 li 居中
```html
```
```css
div{
text-align: center
}
ul{
display: inline-block
}
li{
display: inline
float: left
}
```
# js 随机渐变背景
```javascript
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 三角形
```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 端最优解
```html
```
## 移动端 - 媒体查询 + transform
```css
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
.border-bottom::after {
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
}
}
```
## 移动端 - 媒体查询 + 伪类
```css
.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 检测
```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 检测
```css
@media screen and (orientation: portrait) {
/*竖屏...*/
}
@media screen and (orientation: landscape) {
/*横屏...*/
}
```
# 像素
- 物理像素: 物理设备真实的像素
- 独立像素: 平时开发写的 px
- 设备像素比(DPR): = 物理像素 / 设备独立像素
```js
// 获取 DPR
window.devicePixelRatio;
```
也可以使用媒体查询
```css
@media (-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2) {
}
```
# srcset
使用 img 标签的 `srcset` 属性,浏览器会自动根据像素密度匹配最佳显示图片:
```html
```
# 字体小于 12px
css3 的 `transform` 属性,设置值为 `scale(x, y)` 定义 2D 缩放转换
# css 清浮动
```css
.clearfix::after {
content: "";
display: block;
clear: both;
}
```
# ellipsis
## 单行
```css
.ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
```
## 多行
```css
.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 的倍数
```css
html {
font-size: 62.5%; /* 这会将默认的 16px 缩小为 10px */
}
```
也可以使用 js 检测设置
```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 中的变量为完全的 `常量` ,所以只能定义一次
```less
@nice-blue: #5B83AD;
@light-blue: @nice-blue + #111;
#header {
color: @light-blue;
}
```
输出
```less
#header {
color: #6c94be;
}
```
## 混合
```less
.bordered {
border-top: dotted 1px black;
border-bottom: solid 2px black;
}
```
使用
```less
#menu a {
color: #111;
.bordered;
}
.post a {
color: red;
.bordered;
}
```
带参
```less
.border-radius (@radius) {
border-radius: @radius;
-moz-border-radius: @radius;
-webkit-border-radius: @radius;
}
```
#header {
.border-radius(4px);
}
`@arguments`变量,包含了所有传递进来的参数. 如果你不想单独处理每一个参数
```less
.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);
```
无参
```less
.wrap () {
text-wrap: wrap;
white-space: pre-wrap;
white-space: -moz-pre-wrap;
word-wrap: break-word;
}
pre {
.wrap;
}
```
## lighten 和 darken
```less
@color-base: #3bafda;
@color-hover:lighten (@color-primary,10%);
@color-focus:darken (@color-primary,10%);
```
## contrast
选择两种颜色中哪一种颜色与另一种颜色形成最大对比。
```less
p {
a: contrast(#bbbbbb); //output: black
b: contrast(#222222, #101010); //output: white
}
```
## JavaScript 表达式
```less
@var: ` "hello" .toUpperCase() + "!" `;
@height: `document.body.clientHeight`;
```
## & 父选择器
`&` 只能代表父元素,不能代表父亲的父辈元素,施加改性类或伪类
```less
a {
color: blue;
&:hover {
color: green;
}
}
```
## 重复父类名
```less
.button {
&-ok {
background-image: url("ok.png");
}
&-cancel {
background-image: url("cancel.png");
}
&-custom {
background-image: url("custom.png");
}
}
```