css奇技淫巧
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()
第一个参数是重复的次数,第二个参数是所要重复的值、也可以是某个模式
/* 重复 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 定位
/* 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 徽章
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");
}
}