项目地址
Split Landing Page
展示效果
Split Landing Page
实现思路
当鼠标移动到左右两块区域时,分别给容器添加不同的class实现样式的变换。
有两种思路可以实现,一种是hover时改变宽度,一种是hover时改变flex拉伸比例,两种方式在实现上稍有区别:
- 改变宽度就需要让左右两块分区绝对定位,且左右两边的class宽度改变都需要设置
- flex布局,左右两块区域相对定位,当添加class时只需要改变一侧的拉伸比例即可。
实现细节
HTML结构
在容器container中,包含了左右两块分区,设置一个共同的类名split和一个能区分彼此的类名;区域内是标题和按钮,这个按钮实际是一个可跳转的a标签。
左右两块区域还有蒙层,可以借助before伪元素来实现。
<body>
<div class="container">
<div class="split left">
<h1>Playstation 5</h1>
<a href="#" class="btn">Buy Now</a>
</div>
<div class="split right">
<h1>XBox Series X</h1>
<a href="#" class="btn">Buy Now</a>
</div>
</div>
<script src="script.js"></script>
</body>
CSS样式
案例使用了改变宽度的方案,涉及flex布局的属性会以注释的形式标注出来。
container容器本身肯定是相对定位,而如果采用flex布局解决方案,则需要在容器这层添加flex属性。
如果是改变宽度,则split分区应该用绝对定位来固定两块分区的位置,并且初始宽度应该是父容器的一半;如果是flex布局,split分区就还应该是相对定位,设置拉伸比例为1,而其他为0,此时设置宽度将不再有意义。
:root {
--left-bg-color: rgba(87, 84, 236, 0.7);
--right-bg-color: rgba(43, 43, 43, 0.8);
--left-btn-hover-color: rgba(87, 84, 236, 1);
--right-btn-hover-color: rgba(28, 122, 28, 1);
--hover-width: 75%;
--other-width: 25%;
--speed: 1000ms;
}
.container {
position:relative;
width: 100%;
height: 100%;
overflow: hidden;
/* display: flex; */
}
.split {
/* position: relative; */
/* flex: 1; */
position: absolute;
width: 50%;
height: 100%;
overflow: hidden;
}
分区的蒙层使用before伪元素进行填充,由于设置为绝对定位,因此尺寸都会参照split这个父元素来更改,所以两种方案并没有什么区别。
.split.left {
left: 0;
background: url('ps.jpg');
background-repeat: no-repeat;
background-size: cover;
}
.split::before {
position: absolute;
content: '';
width: 100%;
height: 100%;
background-color: var(--left-bg-color);
}
.split.right {
right: 0;
background: url('xbox.jpg');
background-repeat: no-repeat;
background-size: cover;
}
.split.right::before {
background-color: var(--right-bg-color);
}
.split.right,
.split.left,
.split.right::before,
.split.left::before {
transition: all var(--speed) ease-in-out;
}
接下来处理鼠标hover的情况:
- 改变宽度时,左右分区的宽度都要改变,所以需要分别写出两种情况对应两个元素的四条样式规则;
- 改变flex布局,只需要更改要拉伸一边的元素的比例,所以只需要写出两条样式规则即可。
.hover-left .left {
width: var(--hover-width);
/* flex: 3; */
}
.hover-left .right {
width: var(--other-width);
}
.hover-right .right {
width: var(--hover-width);
/* flex: 3; */
}
.hover-right .left {
width: var(--other-width);
}
JavaScript逻辑
逻辑比较简单,只需要给两个分区绑定鼠标移入和移出时,给container容器挂上或者去除相应的class即可。
const left = document.querySelector('.left')
const right = document.querySelector('.right')
const container = document.querySelector('.container')
left.addEventListener('mouseenter',()=> container.classList.add('hover-left'));
left.addEventListener('mouseleave',()=> container.classList.remove('hover-left'));
right.addEventListener('mouseenter',()=> container.classList.add('hover-right'));
right.addEventListener('mouseleave',()=> container.classList.remove('hover-right'));
总结
- 改变宽度和flex布局均可以实现该交互,区别在于split分区的定位方式上。
- 蒙层采用before伪元素即可实现。