CSS 选择器
选择器 | 格式 | 优先级权重 |
---|---|---|
id 选择器 | #id | 100 |
类选择器 | .classname | 10 |
属性选择器 | [title]/[title=“one”] | 10 |
伪类选择器 | div:hover | 10 |
标签选择器 | div | 1 |
伪元素选择器 | input::after | 1 |
子选择器 | ul>li | 0 |
后代选择器 | li a | 0 |
通配符选择器 | * | 0 |
CSS 选择器优先级
https://developer.mozilla.org/zh-CN/docs/Web/CSS/Specificity
选择器权重
https://www.w3.org/TR/selectors/#specificity
./Demo/css_selector_and_priority.html
link
: 链接外部资源的标签,此标签决定了文档与外部资源的关系,常用于链接样式表(css),网页站点图标(favicon)。
<link rel="stylesheet,icon,image/png,shortlink,help,author,image/svg+xml" href="网络路径/相对路径/绝对路径"/>
/* @import "03.css"; */ body, html { background-color: aquamarine; } /* @import "03.css"; */
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <div class="container"></div> </body> </html> <link rel="stylesheet" href="./01.css" /> <style> @import "./03.css"; </style>
box-sizing: content-box;
box-sizing: border-box;
display: none;
: 不会渲染该元素,不会占位,也不会响应绑定的监听事件visibility: hidden;
: 会渲染,但是不会显示且会占位,也不会响应绑定的监听事件opacity: 0;
: 将元素的透明度设置为 0, 以此来达到隐藏元素的效果,会占位,能够响应绑定的监听事件position: absolute;
: 使用绝对定位将元素移除了可视区域外,不会占位,以此来实现元素的隐藏z-index:负值;
: 使用其他元素将该元素隐藏,会占位clip:position:absolute; clip: rect(200px, 200px, 200px, 200px);/clip-path:clip-path: circle(0);
: 使用元素裁切的transform: scale(0,0)
: 使用缩放,来实现元素的隐藏,会占位,但是不会响应绑定的监听事件filter: opacity(0)
: 使用元素滤镜来改变元素的透明度, 会占位border-radius: 8px;
text-shadown: 2px 2px #ff0000; box-shadown: 10px 10px 5px #888888;
text-decoration
linear-gradient: 线性渐变 radial-gradient 径向渐变
transform
伪类选择器:first-child, 伪元素选择器,否定选择器(:not),属性选择器[title="one"]
multi-column:
@media
查询,可针对不同的媒体类型定义不同的样式,@media 可针对不同的屏幕尺寸设置不同的样式,特别是设置响应式的页面,定义:
理解:BFC(Block Formatting Context, BFC) 块级格式化上下文,页面布局盒模型的一种 CSS 渲染模式,是一个独立的容器,在这个容器中里面的元素和外部的元素互不影响。
创建 BFC 的条件:
BFC 的特点:
BFC 的作用:
overflow:hidden
。-webkit-text-size-adjust: none;
。chrome 27 版本后不可用了。transform: scale(0.5);
/* 多行文本溢出 */ display: -webkit-box; /*作为弹性伸缩盒子模型显示。 */ -webkit-box-orient:vertical; /*设置伸缩盒子的子元素排列方式:从上到下垂直排列 */ -webkit-line-clamp:3; /*显示的行数 */ overflow: hidden; /*溢出隐藏 */ text-overflow: ellipsis; /*溢出用省略号显示 */ /* 单行文本溢出 */ white-space: nowrap; /*规定段落中的文本不进行换行 */ overflow: hidden; /*溢出隐藏 */ text-overflow: ellipsis; /*溢出用省略号显示 */
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div class="div1"></div> <div class="div2"></div> <div class="div3"></div> <div class="div4"></div> </body> </html> <style> div{ width: 0px; height: 0px; border: 50px solid transparent; } .div1{ border-top-color: red; } .div2{ border-bottom-color: red; } .div3{ border-left-color: red; } .div4{ border-right-color: red; } </style>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div class="div1"></div> </body> </html> <style> .div1{ width: 0; height: 0; border-radius: 100px; border: 100px solid transparent; border-top-color: red; } </style>
width: 250px; height: 1px; background-color: gray; transform: scaleY(0.5);
单冒号(:)
表示伪类,双冒号(::)
表示伪元素单冒号
来表示伪元素的,但在 CSS3 规范中,伪元素的语法被修改为使用 双冒号
less, sass, styuls
,它们增加了 css 代码的复用性,例如:变量,循环,方法等postcss
,最常做的是给 css 代码添加浏览器前缀,实现跨浏览器兼容性的问题、像素px,百分比%,em,rem,vw/vh
.outer { height: 100px; } .left { float: left; width: 200px; background: tomato; } .right { margin-left: 200px; width: auto; background: gold; }
.left{ width: 100px; height: 200px; background: red; float: left; } .right{ height: 300px; background: blue; overflow: hidden; }
.outer { display: flex; height: 100px; } .left { width: 200px; background: tomato; } .right { flex: 1; background: gold; }
.outer { position: relative; height: 100px; } .left { position: absolute; width: 200px; height: 100px; background: tomato; } .right { margin-left: 200px; background: gold; }
.outer { position: relative; height: 100px; } .left { width: 200px; background: tomato; } .right { position: absolute; top: 0; right: 0; bottom: 0; left: 200px; background: gold; }
左右两遍固定。中间自适应
利用绝对定位,左右两栏设置为绝对定位,中间设置对应方向大小的 margin 的值。
.outer { position: relative; height: 100px; } .left { position: absolute; width: 100px; height: 100px; background: tomato; } .right { position: absolute; top: 0; right: 0; width: 200px; height: 100px; background: gold; } .center { margin-left: 100px; margin-right: 200px; height: 100px; background: lightgreen; }
.outer { display: flex; height: 100px; } .left { width: 100px; background: tomato; } .right { width: 100px; background: gold; } .center { flex: 1; background: lightgreen; }
.outer { height: 100px; } .left { float: left; width: 100px; height: 100px; background: tomato; } .right { float: right; width: 200px; height: 100px; background: gold; } .center { height: 100px; margin-left: 100px; margin-right: 200px; background: lightgreen; }
.outer { height: 100px; padding-left: 100px; padding-right: 200px; } .left { position: relative; left: -100px; float: left; margin-left: -100%; width: 100px; height: 100px; background: tomato; } .right { position: relative; left: 200px; float: right; margin-left: -200px; width: 200px; height: 100px; background: gold; } .center { float: left; width: 100%; height: 100px; background: lightgreen; }
.outer { height: 100px; } .left { float: left; margin-left: -100%; width: 100px; height: 100px; background: tomato; } .right { float: left; margin-left: -200px; width: 200px; height: 100px; background: gold; } .wrapper { float: left; width: 100%; height: 100px; background: lightgreen; } .center { margin-left: 100px; margin-right: 200px; height: 100px; }
.parent { display: flex; justify-content:center; align-items:center; }
.parent { position: relative; } .child { position: absolute; top: 50%; left: 50%; margin-top: -50px; /* 自身 height 的一半 */ margin-left: -50px; /* 自身 width 的一半 */ }
.parent { position: relative; } .child { position: absolute; top: 0; bottom: 0; left: 0; right: 0; margin: auto; }
.parent { position: relative; } .child { position: absolute; left: 50%; top: 50%; transform: translate(-50%,-50%); }
@media
查询检测不同的设备屏幕尺寸做处理absolute: 绝对定位的元素的位置相对于最近的已定位父元素,如果元素没有已定位的父元素,那么它的位置相对于
relative: 相对定位元素的定位是相对其正常位置
fixed: 元素的位置相对于浏览器窗口是固定位置。即使窗口是滚动的它也不会移动:
static: HTML 元素的默认值,即没有定位,遵循正常的文档流对象。静态定位的元素不会受到 top, bottom, left, right影响。
inherit: 规定从父元素继承 position 属性的
sticky: 基于用户的滚动位置来定位
前面三者的定位方式如下:
position:relative/absolute/fixed
的元素,就以该元素为基准定位,如果没找到,就以浏览器边界定位。如下两个图所示:Retina
屏幕上,移动端页面的 1px 会变得很粗,所呈现出来不止是 1px 的效果,原因就是 CSS 中的 1px 不能和移动端的 1px 划等号,他们之间是有一个比例关系。window.devicePixelRatio = 设备的物理像素 / CSS像素。
<div id="container" data-device={{window.devicePixelRatio}}></div>
#container[data-device="2"] { position: relative; } #container[data-device="2"]::after{ position:absolute; top: 0; left: 0; width: 200%; height: 200%; content:""; transform: scale(0.5); transform-origin: left top; box-sizing: border-box; border: 1px solid #333; }
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
const scale = 1 / window.devicePixelRatio; // 这里 metaEl 指的是 meta 标签对应的 Dom metaEl.setAttribute('content', `width=device-width,user-scalable=no,initial-scale=${scale},maximum-scale=${scale},minimum-scale=${scale}`);
`window.innerHeight` 是浏览器可视区的高度; `document.body.scrollTop || document.documentElement.scrollTop` 是浏览器滚动的过的距离; `imgs.offsetTop` 是元素顶部距离文档顶部的高度(包括滚动条的距离); 内容达到显示区域的:`img.offsetTop < window.innerHeight + document.body.scrollTop;`
// 公式 el.offsetTop - document.documentElement.scrollTop <= viewPortHeight // 代码实现 function isInViewPortOfOne (el) { // viewPortHeight 兼容所有浏览器写法 const viewPortHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight const offsetTop = el.offsetTop const scrollTop = document.documentElement.scrollTop const top = offsetTop - scrollTop return top <= viewPortHeight }
const target = document.querySelector('.target'); const clientRect = target.getBoundingClientRect(); console.log(clientRect); // { // bottom: 556.21875, // height: 393.59375, // left: 333, // right: 1017, // top: 162.625, // width: 684 // } // A: // 如果一个元素在视窗之内的话,那么它一定满足下面四个条件: // top 大于等于 0 // left 大于等于 0 // bottom 小于等于视窗高度 // right 小于等于视窗宽度 // 代码实现 function isInViewPort(element) { const viewWidth = window.innerWidth || document.documentElement.clientWidth; const viewHeight = window.innerHeight || document.documentElement.clientHeight; const { top, right, bottom, left, } = element.getBoundingClientRect(); return ( top >= 0 && left >= 0 && right <= viewWidth && bottom <= viewHeight ); }
// 第一步:创建观察者 const options = { // 表示重叠面积占被观察者的比例,从 0 - 1 取值, // 1 表示完全被包含 threshold: 1.0, root:document.querySelector('#scrollArea') // 必须是目标元素的父级元素 }; const callback = (entries, observer) => { ....} const observer = new IntersectionObserver(callback, options); // 通过new IntersectionObserver创建了观察者 observer,传入的参数 callback 在重叠比例超过 threshold 时会被执行` // 上段代码中被省略的 callback const callback = function(entries, observer) { entries.forEach(entry => { entry.time; // 触发的时间 entry.rootBounds; // 根元素的位置矩形,这种情况下为视窗位置 entry.boundingClientRect; // 被观察者的位置举行 entry.intersectionRect; // 重叠区域的位置矩形 entry.intersectionRatio; // 重叠区域占被观察者面积的比例(被观察者不是矩形时也按照矩形计算) entry.target; // 被观察者 }); }; // 第二步:传入被观察者 const target = document.querySelector('.target'); observer.observe(target);
<head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js" integrity="sha512-STof4xm1wgkfm7heWqFJVn58Hm3EtS31XFaagaa8VMReCXAkQnJZ+jEy8PCC/iT18dFy95WcExNHFTqLyp72eQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <title>Document</title> <style> .container { display: flex; flex-wrap: wrap; } .target { margin: 5px; width: 20px; height: 20px; background: red; } </style> </head> <body> <div class="container"></div> </body> </html> <script> (() => { const $container = $(".container"); function createTargets() { const htmlString = new Array(10000).fill('<div class="target"></div>').join("") $container.html(htmlString) } createTargets(); const $targets = $(".target"); function isInViewPort(el){ //方法1 // const viewPortHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; // const offsetTop = el.offsetTop; // const scollTop = document.documentElement.scrollTop; // return offsetTop-scollTop <= viewPortHeight // 方法2 const viewPortHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; const viewPortWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; const {top,right,left,bottom} = el.getBoundingClientRect(); return top >= 0 && left >= 0 && bottom <= viewPortHeight && right <= viewPortWidth } //事件监听 $(window).on("scroll",()=>{ console.log("scroll!!"); $targets.each((index,element)=>{ if(isInViewPort(element)){ $(element).css("background-color","blue") } }) }) })(); </script>
<head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.3/jquery.min.js" integrity="sha512-STof4xm1wgkfm7heWqFJVn58Hm3EtS31XFaagaa8VMReCXAkQnJZ+jEy8PCC/iT18dFy95WcExNHFTqLyp72eQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <title>Document</title> <style> * { margin: 0; padding: 0; } .test { width: 200px; height: 1000px; background: orange; } .box { width: 150px; height: 150px; margin: 50px; background: red; } #sta { position: fixed; left: 40%; top: 40%; width: 200px; height: 100px; background: greenyellow; } </style> </head> <body> <div class="test">test</div> <div class="box">box</div> <div id="sta">初始化</div> </body> </html> <script> (() => { var status_node=document.querySelector("#sta"); const box = document.querySelector('.box'); const intersectionObserver = new IntersectionObserver((entries) => { entries.forEach((item) => { if (item.isIntersecting) { box.innerText = '进入可视区域'; status_node.innerText = '进入可视区域'; console.log('进入可视区域'); }else{ box.innerText = '出去了'; status_node.innerText = '出去了'; } }) }); intersectionObserver.observe(box); })(); </script>
Q:(question)
R:(result)
A:(attention matters)
D:(detail info)
S:(summary)
Ana:(analysis)
T:(tips)