前言
刚过去的双11大家都去哪些网站购物了呢?不论去哪个网站,预计都少不了天猫吧,在逛天猫时发现了这样一种乏味的景象:
尽管说这种成果还比拟常见,但有一个细节不同凡响,比如说咱们先来看一个一般的 header 随窗口滚动而渐隐渐现的成果:
比照一下发现哪里不同了么,一般版的是一开始齐全通明,随着窗口的滚动而缓缓显示进去,靠的是管制opacity
透明度属性来实现的。
而小黑盒那版是一开始就有一个渐变色,突变到靠近半透明,这种形式看起来更加的优雅,但看起来只是一开始进入页面还没滚动的时候带着很漂亮的渐变色,一滚动的时候行为又和以前靠透明度的时候差不多。
咱们要改良的就是用滚动的间隔来管制background-position
,随着窗口的滚动,会缓缓扭转渐变色突变的水平而管制显隐成果。
款式
首先咱们先把header
的款式写进去:
header {
/* 设置一个管制背景色地位的CSS变量,不便JS管制 */
--position: 100;
/* 居中靠下显示子元素 */
display: grid;
place-items: end center;
/* 设置为固定定位 */
position: fixed;
/* 间隔上边右边为0 */
top: 0;
left: 0;
/* 宽度铺满屏幕 */
width: 100%;
/* 给个适合的高度 */
height: 40px;
/* 红色字体 */
color: white;
/* 字体大小 */
font-size: 16px;
/* 让字体细一点 */
font-weight: 100;
/* 减少下内变局,避免文字过于靠下 */
padding-bottom: 10px;
/* 设置过渡成果 */
transition: background-position .2s;
/* 彩色突变背景 */
background: linear-gradient(black, rgba(148, 88, 88, 0.3) 80%, rgba(0, 0, 0, 0)) 0 calc(var(--position) * 1%) / 100% 300%;
}
运行后果:
能够看到咱们在header
外面设置了一条CSS变量,如果不太分明什么是CSS变量的话请点击这里,这里还用到了 gird 来进行居中,当然并不是完完全全的居中,而是稍稍偏下了一点,因为我看天猫的小黑盒就是做的偏下居中。
整体实现
而后咱们开始写 JS 代码了,因为纯 CSS 的话还是无奈获取屏幕的滚动间隔,然而为了可能更不便的进行单方交互,咱们还是采纳了CSS变量,因为CSS变量带来的晋升绝不仅仅是节约点 CSS 代码,以及升高 CSS 开发和保护老本这点作用。
更重要的是,把组件中泛滥的交互开发从原来的JS转移到了CSS代码中,让组件代码更简洁,同时让视觉体现实现更加灵便了。 ——张鑫旭
CSS变量具体能为咱们带来哪些益处,能够参考张鑫旭的博客:
《CSS变量对JS交互组件开发带来的晋升与改革》
来看一下CSS变量是怎么与 JS 进行交互的:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>属于本人的突变小黑盒</title>
<style>
/* 革除默认款式 */
* { padding: 0; margin: 0 }
header {
/* 设置一个管制背景色地位的CSS变量,不便JS管制 */
--position: 100;
/* 居中靠下显示子元素 */
display: grid;
place-items: end center;
/* 设置为固定定位 */
position: fixed;
/* 间隔上边右边为0 */
top: 0;
left: 0;
/* 宽度铺满屏幕 */
width: 100%;
/* 给个适合的高度 */
height: 40px;
/* 红色字体 */
color: white;
/* 字体大小 */
font-size: 16px;
/* 让字体细一点 */
font-weight: 100;
/* 减少下内变局,避免文字过于靠下 */
padding-bottom: 10px;
/* 设置过渡成果 */
transition: background-position .2s;
/* 彩色突变背景 */
background: linear-gradient(black, rgba(148, 88, 88, 0.3) 80%, rgba(0, 0, 0, 0)) 0 calc(var(--position) * 1%) / 100% 300%;
}
main {
/* 给个适合的高度 */
height: 1000px;
}
</style>
</head>
<body>
<header>咱们本人的小黑盒</header>
<main></main>
<script>
// 获取header
const header = document.getElementsByTagName('header')[0]
addEventListener('scroll', () => {
// 获取偏移值
const top = document.documentElement.scrollTop
// 设置一个适合的范畴
if (top <= 200) {
// 令header的渐变色地位变成计算后的突变地位
header.style.setProperty('--position', 100 - Math.min(100, top))
} else {
// 在挪动肯定范畴后令其齐全不通明
header.style.setProperty('--position', 0)
}
})
</script>
</body>
</html>
运行后果:
设想一下如果不必CSS变量的话会变成什么样:
header.style.backgroundPosition = '0 ' + 100 - Math.min(100, top) + '%'
尽管看起来如同没啥的,但当要管制的属性较多时这将会是一种劫难,而且这种形式要时刻都带着 CSS 单位,像 px、%、rem 这些,为咱们减少了不必要的心智累赘,而且也拖慢了程序的运行效率。
用了CSS变量之后都不必带单位了,间接赋值一个数字即可,那么为什么能够不带单位呢?答案就在 calc
函数上:
calc(
var(--position)
*1%
)
记住在这里可不能再用 JS 的思维来写 calc 函数了,在 JS 里咱们用的是+
,因为这代表了字符串拼接,而在这里数字乘以
百分之一,就会变成具体的百分数,同理如果你须要的是其余单位的话能够依据具体需要进行灵便批改:
calc(
var(--position)
*1px
)
⚠️留神 px 后面那个1
很重要,不能省略掉!
而且也不是必须要写1
,还能够依据具体的需要按倍数来:
calc(
var(--position)
*6.6rem
)
扩大
其实从代码和咱们日常生活中见到的成果能够得悉,基本上滚动一段距离后header
的透明度就固定住了不会再发生变化,节约了监听 onscroll
事件。但又不能取消监听,因为不晓得用户何时会再滑到顶部去,但这种状况却非常适合做另一种成果:
我遗记了这种成果叫啥来着,总之就是随着用户滚动页面的间隔而在顶部显示一个相似于进度条之类的货色,不便用户得悉本人处在网页中大略什么样的一种地位,来看代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>属于本人的突变小黑盒</title>
<style>
/* 革除默认款式 */
* { padding: 0; margin: 0 }
header {
/* 设置一个管制地位的CSS变量,不便JS管制 */
--position: 0;
/* 设置为固定定位 */
position: fixed;
/* 间隔上边右边为0 */
top: 0;
left: 0;
/* 宽度铺满屏幕 */
width: 100%;
/* 给个适合的高度 */
height: 10px;
/* 设置过渡成果 */
transition: transform .1s;
/* 突变背景 */
background: linear-gradient(to right,#4481eb,#04befe);
/* 设置形变成果 */
transform: scaleX(var(--position));
/* 设置变形参照点 */
transform-origin: left;
}
main {
/* 给个适合的高度 */
height: 10000px;
/* 突变背景 */
background: linear-gradient(#30cfd0,#330867)
}
</style>
</head>
<body>
<header></header>
<main></main>
<script>
// 获取header
const header = document.getElementsByTagName('header')[0]
addEventListener('scroll', () => {
// 获取偏移值
const top = document.documentElement.scrollTop
// 获取页面总高度
const height = document.documentElement.scrollHeight
// 设置CSS变量
if (top > height - document.documentElement.clientHeight - 1) {
header.style.setProperty('--position', 1)
} else {
header.style.setProperty('--position', top / height)
}
})
</script>
</body>
</html>
本文首发于微信公众号:《前端学不动》
发表回复