[TOC]
bfc ifc gfc
CSS2.1中只有BFC和IFC, CSS3中才有GFC和FFC。 FC的全称是:Formatting Contexts,即格式化上下文,它决定了其子元素将如何定位,以及和其他元素的关系和相互作用。
BFC 块级格式化上下文
BFC(Block Formatting Contexts)直译为"块级格式化上下文"。容器里面的子元素不会在布局上影响到外面的元素,反之也是如此。 如何产生BFC?
- float的值不为none。
- overflow的值不为visible。
- position的值不为relative和static。
- display的值为table-cell, table-caption, inline-block中的任何一个。
那BFC一般有什么用呢? 比如常见的多栏布局,独立的块级元素等。
BFC原理(渲染规则) 1.BFC区域垂直方向会发生重叠 2.BFC不会与浮动元素相互干扰,可实现清除浮动 3.BFC区域是个独立的容器,其外部元素不会对其造成干扰 4.计算BFC高度时候,浮动也会参与计算
IFC 内联格式化上下文
IFC(Inline Formatting Contexts)直译为"内联格式化上下文",IFC的line box(线框)高度由其包含行内元素中最高的实际高度计算而来(不受到竖直方向的padding/margin影响) IFC中的line box一般左右都贴紧整个IFC,但是会因为float元素而扰乱。 float元素会位于IFC与与line box之间,使得line box宽度缩短。 同个ifc下的多个line box高度会不同。 IFC中时不可能有块级元素的,当插入块级元素时(如p中插入div)会产生两个匿名块与div分隔开,即产生两个IFC,每个IFC对外表现为块级元素,与div垂直排列。
那么IFC一般有什么用呢?
- 水平居中:当一个块要在环境中水平居中时,设置其为inline-block则会在外层产生IFC,通过text-align则可以使其水平居中。
- 垂直居中:创建一个IFC,用其中一个元素撑开父元素的高度,然后设置其vertical-align:middle,其他行内元素则可以在此父元素下垂直居中。
GFC 网格布局格式化上下文
GFC(GridLayout Formatting Contexts)直译为"网格布局格式化上下文",当为一个元素设置display值为grid的时候,此元素将会获得一个独立的渲染区域,我们可以通过在网格容器上定义网格行和网格列。
那么GFC有什么用呢,和table又有什么区别呢? 首先同样是一个二维的表格,但GridLayout会有更加丰富的属性来控制行列,控制对齐以及更为精细的渲染语义和控制。
FFC 自适应格式化上下文
FFC(Flex Formatting Contexts)直译为"自适应格式化上下文",Flex Box由伸缩容器和伸缩项目组成。通过设置元素的 display 属性为 flex 或 inline-flex 可以得到一个伸缩容器。设置为 flex 的容器被渲染为一个块级元素,而设置为 inline-flex 的容器则渲染为一个行内元素。
css绘制特殊图形
基础图形主要有:三角形、梯形、直角三角形、圆形、椭圆等,大多启发点都是源于下面的原始图形,原始图形原理演示如下,实际css都可以做出动画片: [原始图形]
CSS绘制一个QQ企鹅 椭圆原理:效果图:
椭圆也可变异为石头等形状,演示如下:<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>css 绘制特殊图形</title>
<style>
div{
width: 100px;
height: 100px;
border: 30px solid;
background-color: orange;
border-left-color: blueviolet;
border-right-color: brown;
border-top-color: yellowgreen;
border-bottom-color: teal;
margin-top: 10px;
}
.三角形{
width: 0px;
height: 0px;
background-color: transparent;
border-left-color: transparent;
border-right-color: transparent;
border-top-color: transparent;
border-bottom-color: teal;
}
.直角三角形{
width: 0px;
height: 0px;
background-color: transparent;
border-top-color: transparent;
border-right-color: transparent;
border-left-color: teal;
}
.对角切割 {
width: 0px;
height: 0px;
background-color: transparent;
border-bottom: 0;
border-left: 0;
}
.直角三角形2{
background-color: transparent;
border-top-color: transparent;
}
.梯形{
height: 0px;
background-color: transparent;
border-right-color: transparent;
border-left-color: transparent;
border-top-color: transparent;
}
.圆环{
border-radius: 50%;
}
.圆{
border:0;
border-radius: 50%;
}
.椭圆{
border:0;
width: 200px;
border-radius: 50%;
/* border-top-left-radius: 50%;
border-top-right-radius: 50%;
border-bottom-left-radius: 50%;
border-bottom-right-radius: 50%; */
}
</style>
</head>
<body>
<div class="原始图形"></div>
<div class="三角形"></div>
<div class="直角三角形"></div>
<div class="对角切割"></div>
<div class="对角切割 直角三角形2"></div>
<div class="梯形"></div>
<div class="圆环"></div>
<div class="圆"></div>
<div class="椭圆"></div>
</body>
</html>
css next
css预处理器: sass,less,stylus css后处理器:postcss PostCSS 是使用 javascript 插件转换 CSS 的后处理器。PostCSS 本身不会对你的 CSS 做任何事情,你需要安装一些 plugins 才能开始工作。这不仅使其模块化,同时功能也会更强。 它的工作原理就是解析 CSS 并将其转换成一个 CSS 的节点树,这可以通过 javascript 来控制(也就是插件发挥作用)。然后返回修改后的树并保存。它与 Sass(一种预处理器)的工作原理不同,你基本上是用一种不同的语言来编译 CSS 。 案例参考: 展望未来:使用 PostCSS 和 cssnext 书写 CSS cssnext特性
css自定义函数
案例1:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>css自定义函数</title>
<style>
:root {
--number-var: 1
}
div::before {
counter-reset: number var(--number-var);
content: counter(number)
}
</style>
</head>
<body>
<div></div>
<script>
// 使用js给css变量赋值:setProperty,不会触发重排
setTimeout(() => {
document.documentElement.style.setProperty("--number-var", 4)
}, 1000);
</script>
</body>
</html>
css doodle
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>css doodle</title>
<style>
:root {
--customUnit: 100%;
--flag: 0;
}
html,
body {
width: var(--customUnit);
height: var(--customUnit);
display: flex;
align-items: center;
justify-content: center;
}
body {
background: #0a0c27;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/css-doodle/0.7.1/css-doodle.min.js"></script>
</head>
<body>
<css-doodle>
/* 将页面分成1行10列的树格 */
:doodle {
@grid: 1x10 / 61.8vmax;
}
/* 将每个格子按照中心排列 */
@place-cell:center;
/* 根据索引逐渐变大 */
@size:calc(@index() * 10%);
border-radius: 50%;
border-width: calc(@index()*1vmin);
border-style: dashed;
border-color: hsla(calc(20 * @index()), 70%, 68%, calc( 3 / @index() * .8));
/* 添加动画 */
/* 私有变量定义 */
--d: @rand(20s, 40s);
--rf: @rand(360deg);
--rt: calc(var(--rf) + @pick(1turn, -1turn));
animation: spin var(--d) linear infinite;
@keyframes spin
{
from{
transform: rotate(var(--rf))
}
to{
transform: rotate(var(--rt))
}
}
</css-doodle>
</body>
</html>
js in css: css houdini (js in css)
常用的方式为css in js,即将css代码打包到js中
浏览器在网頁的渲染过程如下: file:///private/var/folders/sm/02s6fkbd3sq130n5npc9bhrr0000gp/T/WizNote/e4802792-b496-4ea7-adb6-50662f235cb2/index_files/66936370.png
浏览器的 Render Pipeline 中,JavaScript 与 Style 两个阶段会解析 HTML 并为加载的 JS 与 CSS 建立 Render Tree,也就是所谓的 DOM 与 CSSOM。 而就现阶段的 Web 技术來看,开发者们能操作的就是通过 JS 去控制 DOM 与 CSSOM,來来影响页面的变化,但是对于接下來的 Layout、Paint 与 Composite 就几乎沒有控制权了。 为了解決上述问题,为了让 CSS 的魔力不再浏览器把持,Houdini 就诞生了!
css Houdini CSS魔术师Houdini API介绍
案例1:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<style>
.el {
--elUnit: 500px;
--arcColor: #8266ff;
height: var(--elUnit);
width: var(--elUnit);
background: url("../test.png"); /* 2.使用图片或者gif做Houdini降级展示(浏览器不支持时候使用) */
/* 1.Houdini(实现了js in css,跳过重绘和重排使用GPU渲染):绘制canvas,除了不可以操作dom,其他就是canvas语法;把canvas效果直接粘贴过来就可以 */
--background-canvas: (ctx, geom)=> {
ctx.strokeStyle= `var(--arcColor)`;
ctx.lineWidth=2;
ctx.beginPath();
ctx.arc(200, 200, 50, 0, 2*Math.PI);
ctx.stroke();
ctx.closePath();
};
/* background-canvas 为Houdini中的自定义属性 */
background: paint(background-canvas);
}
</style>
<title>Houdini实战1</title>
</head>
<body>
需要使用http-server 启动访问才可,否则资源无法获取
<div class="el"></div>
</body>
<script>
CSS.paintWorklet.addModule("./arc.js"); // 这行代码是浏览器原生支持的
</script>
</html>
arc.js
// css Houdini
// 也可以采用类的方式注册,参考sky.js
if (typeof registerPaint !== "undefined") {
registerPaint("background-canvas", class {
static get inputProperties() {
// --background-canvas 是index.html中css定义的样式变量
return ["--background-canvas"];
}
paint(ctx, geom, properties) {
eval(properties.get("--background-canvas").toString())(
ctx, geom, properties
);
}
});
}
案例2:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Houdini实战1</title>
<style>
body:before {
--star-sky: 1;
background-image: paint(yd-sky);
}
</style>
</head>
<body>
<script>
CSS.paintWorklet.addModule("./sky.js");
</script>
</body>
</html>
sky.js
class YdSky {
static get inputProperties() {
return ["--star-sky"];
}
paint(ctx, geom, properties) {
const starSky = properties.get("--star-sky");
//....... ctx绘制动画
}
}
registerPaint("yd-sky", YdSky);
新的css高级效果
自动的marign+flex 实现居中
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>自动的marign</title>
<style>
.automargin {
--ydUnit: 500px;
width: var(--ydUnit);
height: var(--ydUnit);
border: 1px solid yellowgreen;
/* 设置为flex,结合下面的margin可以实现多种居中效果 */
display: flex;
}
.automargin div{
margin: auto;
}
</style>
</head>
<body>
<div class="automargin">
<div>
<img src="./assets/batman.png">
</div>
</div>
</body>
</html>
色相:色域角度变化改变色相
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>色相的妙用</title>
<style>
.btn{
background: yellow;
width: 100px;
height:100px;
/* 实现变色效果,且通过60deg的角度旋转,实现修改多种色相 */
filter: hue-rotate(60deg)
}
</style>
</head>
<body>
<div class="btn"></div>
</body>
</html>
改变色相实现流光的字体
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>色相之流光的字体</title>
<style>
@keyframes hue
{
from{
filter: hue-rotate(0deg)
}
to{
filter: hue-rotate(360deg)
}
}
.yd-slogon{
font-size: 120px;
background-image: linear-gradient(
to right,
red,
orange,
yellow,
green,
cyan,
blue,
purple
);
/* 字体裁剪+填充:将渐变背景投到字的颜色上 */
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
/* 添加色相使色相循环变化 */
animation: hue 2s linear infinite;
}
</style>
</head>
<body>
<h1 class="yd-slogon">京程一灯冲击月薪3万</h1>
</body>
</html>
左右分栏的拖动效果实现
案例1:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>分栏CSS</title>
<style>
.resize-bar{
border: 1px solid #bbb;
width: 100px;
height: 100px;
/* resize实现大小可拖动 */
resize: horizontal;
overflow: scroll;
}
/* 修改默认拖动角的样式 */
.resize-bar::-webkit-scrollbar{
width: 60px;
height:60px;
}
</style>
</head>
<body>
让一个div可拖动
<div class="resize-bar"></div>
</body>
</html>
案例2:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>可拖动大小的左右分栏布局</title>
<style>
:root {
--ydUnit: 400px;
}
.column {
overflow: hidden;
border: 1px dashed yellowgreen;
}
.column-left {
height: var(--ydUnit);
position: relative;
float: left;
}
.column-right {
padding: 16px;
box-sizing: border-box;
overflow: hidden;
}
.resize-content {
position: absolute;
top: 0;
right: 5px;
bottom: 0;
left: 0;
padding: 16px;
overflow-x: hidden;
}
.resize-bar {
width: 200px;
height: inherit;
/* 支持拖动 */
resize: horizontal;
overflow: scroll;
/* 指示双向重新设置大小 */
/* cursor: ew-resize; */
/* 通过透明隐藏拖动下标样式 */
opacity: 0;
}
.resize-bar::-webkit-scrollbar {
height: inherit;
}
/* 分割线 */
.resize-line {
position: absolute;
right: 0;
top: 0;
bottom: 0;
/* 两条线有刻在页面内的阴影视觉效果 */
border-right: 2px solid #eee;
border-left: 1px solid #bbb;
/* 取消鼠标事件 */
pointer-events: none;
}
.resize-bar:hover ~ .resize-line{
border-left: 1px dashed aqua;
}
</style>
</head>
<body>
<div class="column">
<div class="column-left">
<div class="resize-bar"></div>
<div class="resize-line"></div>
<div class="resize-content">左侧内容 左侧内容 左侧内容 左侧内容 左侧内容</div>
</div>
<div class="column-right">
右侧内容 右侧内容 右侧内容 右侧内容 右侧内容 右侧内容 右侧内容
</div>
</div>
</body>
</html>
更改滚动条样式
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>更改滚动条样式</title>
<style>
html {
background: #100e17;
}
/* 滚动槽 */
html::-webkit-scrollbar {
width: 10px;
height: 10px;
}
/* 拖动手把 */
html::-webkit-scrollbar-thumb{
border-radius: 10px;
background: linear-gradient(to bottom,#ff8a00,#da1b60);
}
/* 滚动槽边框 */
html::-webkit-scrollbar-track {
background: linear-gradient(
to right,
#201c29,
#201c29 1px,
#100e17 1px,
#100e17
)
}
</style>
</head>
<body>
<img src="./assets/scroll.png" width="700px" alt="">
<br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br />
<br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br />
<br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br />
<br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br />
<br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br />
<br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br />
<br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br />
<br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br /> <br />
</body>
</html>
图层遮罩裁边效果
两张原图:
最终效果:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>图层遮罩裁边效果</title>
<style>
.mask-image{
width: 260px;
height: 250px;
-webkit-mask-image: url(./assets/star.png)
}
</style>
</head>
<body>
<img src="./assets/bg.jpeg" width="800px" class="mask-image" alt="">
</body>
</html>
混合模式---汽车换肤 mix-blend-mode
原图:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>混合模式---汽车换肤</title>
<style>
html,
body {
height: 100%;
}
body {
margin: 0;
}
img {
height: 100%;
width: 100%;
object-fit: cover;
}
input {
padding: 0;
border: none;
position: absolute;
/* input 大小和图片一样大,浮在上一层 */
width: 100%;
height: 100%;
/* 混合模式 */
mix-blend-mode: hue;
cursor: pointer;
}
</style>
</head>
<body>
<input type="color" value="#0000ff" />
<img src="./assets/car.jpg" />
</body>
</html>
混合模式+滤镜: 房间变晚上
原图:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>混合模式+滤镜</title>
<style>
.night{
width: 780px;
height: 520px;
background: rgba(0,40,140,0.6) url(./assets/house.jpeg);
/* 混合模式:实现房间黑夜效果 */
background-blend-mode: darken;
/* 滤镜:brightness 亮度 contrast 对比度 grayscale 灰度 */
filter: brightness(80%) grayscale(20%) contrast(1.2)
}
</style>
</head>
<body>
<div class="night"></div>
</body>
</html>
滑动轮播图
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>滑动轮播图</title>
<style>
body{
width: 100vw;
height: 100vh;
overflow: hidden;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
background: #333;
}
.container{
width: 400px;
overflow-x: auto;
overflow-y: hidden;
white-space: nowrap;
margin: auto;
/* 在滚动容器中的执行方式 */
scroll-snap-align: x mandatory;
}
.container img{
width: 400px;
height: 600px;
scroll-snap-align: center;
}
</style>
</head>
<body>
<div class="container">
<img src="./assets/1.jpeg" alt="">
<img src="./assets/2.jpeg" alt="">
<img src="./assets/3.jpeg" alt="">
<img src="./assets/4.jpeg" alt="">
<img src="./assets/5.jpeg" alt="">
<img src="./assets/6.jpeg" alt="">
<img src="./assets/7.jpeg" alt="">
<img src="./assets/8.jpeg" alt="">
</div>
</body>
</html>
github代码如下: 欢迎给个小星星,谢谢🙏