一种引发浏览者探索兴趣的方法是,页面打开以后并不立刻把全部内容都呈现给用户,而是隐藏其中的一部份内容,其余内容则须要用户交互以后才展现出来。这种方式很合适那些小众的、要营造艺术氛围的网站,经过特效来展示后续内容,有一种与用户对话的感受。本做品就是采用这样的方式,当页面加载以后先把图片遮住,而后当鼠标移动到元素之上时,图片才展示出来。css
按下右侧的“点击预览”按钮能够在当前页面预览,点击连接能够全屏预览。html
https://codepen.io/comehope/pen/MWejLqY前端
每日前端实战系列的所有源代码请从 github 下载:git
https://github.com/comehope/front-end-daily-challengesgithub
容器名为 .container
,其中包含一个名为 .item
的元素。.item
元素则包含 3 个子元素,.picture
表示图片自己,.title
是图片上的文字,.mask
是用来制做遮罩效果的元素。
做品完成时,会有多个 .item
元素,但此时咱们先只展现 1 张图片,待效果完成以后,再增长其余图片。segmentfault
<div class="container"> <div class="item"> <img class="picture" src="images/toggle.png"> <span class="title">Toggle</span> <div class="mask"></div> </div> </div>
本做品用到的4张图片可从下列地址下载。
https://assets.codepen.io/947...
https://assets.codepen.io/947...
https://assets.codepen.io/947...
https://assets.codepen.io/947...网络
设置页面背景色为深灰色,令容器居中。布局
body { background-color: #222; margin: 0; height: 100vh; display: flex; align-items: center; justify-content: center; }
设置图片尺寸,用相对单位 em
。学习
.item { width: 18em; height: 12em; } .item .picture { width: 100%; }
效果以下图:测试
由于先处理遮罩效果,因此把暂时用不到的文字隐藏起来,避免干扰。
.item .title { display: none; }
利用 .mask
元素为图片增长遮罩。遮罩大小是 20em * 20em 的一个大圆,背景色先暂用半透明的醒目的黄色,便于在开发过程当中观察。
.item { position: relative; display: flex; align-items: center; justify-content: center; } .item .mask { position: absolute; width: 20em; height: 20em; background-color: hsla(60, 100%, 50%, 0.7); border-radius: 50%; }
效果以下图:
上面只是测试了遮罩的大小,把刚才的代码注释掉,改用 box-shadow
实现咱们真正须要的遮罩效果。这个遮罩层尺寸是 50em * 50em
,远远大于图片自己,但它的大部分区域是内阴影,在内阴影以内才透出遮罩下方的图片来。
内阴影的尺寸是 15em
,这是内阴影的半径,因此内阴影的直径是 30em
,用遮罩元素的宽高 50em
减去遮罩的 30em
,剩下的就是 20em
,和刚才测试的遮罩大小是同样的。
.item .mask { /*width: 20em;*/ /*height: 20em;*/ /*background-color: hsla(60, 100%, 50%, 0.7);*/ width: 50em; height: 50em; color: hsla(60, 100%, 50%, 0.7); box-shadow: inset 0 0 0 15em; }
效果以下图:
加上鼠标悬停效果试一下。注意,这里元素上的内阴影尺寸设置为 25em
,这是内阴影的半径尺寸,那么阴影的直径就是 50em
,和遮罩自己的尺寸是同样大的,这表示在默认状况下,整张图片都被内阴影遮住了;而鼠标悬停时,内阴影变小,就显示出了遮罩下方的图片。另外为遮罩层增长了 pointer-events: none
属性,它的做用是避免遮罩层响应鼠标事件。
.item .mask { box-shadow: inset 0 0 0 25em; transition: box-shadow 0.3s; pointer-events: none; } .item:hover .mask { box-shadow: inset 0 0 0 15em; }
再下来制做鼠标滑动时遮罩跟随的效果。
先把遮罩移到图片的左上方。遮罩的高是 50em
,top: -25em
就是令遮罩的水平中线与图片顶边对齐;同理,left: -25em
则是令遮罩的垂直中线与图片的左边对齐,二者叠加,就是遮罩的中心与图片的左上角对齐。
.item .mask { top: -25em; left: -25em; }
增长脚本,为 .item
元素绑定 mousemove
事件,令鼠标在 .item
元素上滑动时,带动 .mask
元素滑动。
window.onload = init function init() { let items = document.querySelectorAll('.item') items.forEach((item) => { item.addEventListener('mousemove', e => { let mask = item.querySelector('.mask') mask.style.transform = 'translate(' + e.offsetX + 'px, ' + e.offsetY + 'px)' }) }) }
至此,主要的效果已经完成了,接下来再加强一下效果。
稍加大图片的原始尺寸,在鼠标悬停时恢复图片大小,这样的效果是在鼠标进入图片区域时,图片能“扭曲抖动”一下,增强互动的效果。
.item .picture { transform: scale(1.1); transition: 0.3s; } .item:hover .picture { transform: scale(1); }
鼠标悬停和滑动效果完成,下面这几行代码是一些收尾工做。
经过 overflow: hidden
属性隐藏掉图片以外的部分、容器加一点圆角、遮罩的颜色改用不透明的灰色。
.container { border-radius: 0.3em; } .item { overflow: hidden; } .item .mask { /*color: hsla(60, 100%, 50%, 0.7);*/ color: #333; }
效果以下图:
接下来处理文字。
先把文字显示出来,除了注释掉 display: none
以外,还要设置它的 z-index
,令它显示在遮罩层的上方,再有也要取消它的鼠标事件,防止它影响鼠标滑动效果。
.item .title { /*display: none;*/ position: absolute; color: #777; z-index: 1; pointer-events: none; }
设置文字样式。
.item .title { font-family: sans-serif; font-weight: bold; text-transform: uppercase; }
增长文字特效,当鼠标滑入图片时,隐藏文字。
.item .title { transition: 0.2s; } .item:hover .title { opacity: 0; }
效果以下图:
至此,单图图片的效果都完成了。
增长多个 .item
元素。
<div class="container"> <div class="item"> <img class="picture" src="images/toggle.png"> <span class="title">Toggle</span> <div class="mask"></div> </div> <!-- 此处再增长3个 .item 元素,代码略 --> </div>
用 grid
布局把图片排列成田字格形状。
.container { display: grid; grid-template-columns: repeat(2, 1fr); grid-gap: 1em; }
效果以下图:
大功告成!
张偶,网络笔名 @comehope,20世纪末触网,被 Web 的无穷魅力所俘获,自此始终战斗在 Web 开发第一线。
《前端每日实战》专栏是我近年来实践项目式学习的笔记,以项目驱动学习,展示从灵感闪现到代码实现的完整过程,亦可做为前端开发的练手习题和开发参考。
拙做《CSS3 艺术》一书已由人民邮电出版社出版,全彩印刷,用100多个生动美观的实例,系统地剖析了 CSS 与视觉效果相关的重要语法,并含有近10小时的视频演示讲解。京东/天猫/当当有售。