时间到2022年9月23日,记录一下通过css实现鼠标滚动横向滚动条。
用vue3封装了一个组件需要的拷贝过去。
效果图:
视觉上可能没什么效果
父组件调用样例:
<scrolXDiv :height="300" style="display: flex; flex-direction: row">
<div v-for="i in 9" :key="i" class="img">
<img src="/image/file1.jpg" />
</div>
</scrolXDiv>
可以把scrolXDiv当作一个普通的div使用,但必须设置height否则滚动条会出不来。
vue组件scrolXDiv.vue
<template>
<div
style="position: relative; overflow: hidden"
:style="{ height: height + 'px' }"
>
<div class="sxd-square" name="绘制一个正方形">
<div
class="sxd-box"
name="继承正方形高度并旋转"
:style="{ width: height + 'px' }"
>
<div class="sxd-rebox" name="旋转回原来的方向" v-bind="$attrs">
<slot />
</div>
</div>
</div>
</div>
</template>
<script lang="ts">
// 提供一个纯css的横向滚动框,必须指定高度且只支持数字
import { defineComponent } from 'vue';
export default defineComponent({
inheritAttrs: false,
});
</script>
<script lang="ts" setup>
defineProps<{ height: number }>();
</script>
<style lang="less" scoped>
@import url('@/style/scrollbar.less');// 对滚动条的美化参数
.sxd-square {
width: 100%;
height: 0;
padding-top: 100%;
position: relative;
}
.sxd-box {
transform: rotateZ(-90deg) rotateY(180deg);
transform-origin: left top;
position: absolute;
top: 0;
left: 0;
height: 100%;
overflow-y: auto;
overflow-x: hidden;
.scrollbar();
.sxd-rebox {
transform: rotate(90deg) rotateX(180deg);
transform-origin: left top;
}
}
</style>
实现原理是套多层div:
1.第一层最外层的 相对定位作为容器;
2.第二层div继续相对定位,利用padding-top:100%;绘制一个正方形,这样把容器的宽度转为了正方形的高度;
3.第三层div用height:100%;继承第二层的高度,再通过transform: rotateZ(-90deg) rotateY(180deg);翻转使得高度变成宽度,由于高度继承自第二层的高度也就是第二层的宽度即第一层的宽度,这样旋转以后视觉的宽度就和容器一样了,视觉的实际上是width来自于外部传参设置(这里不设置也是有滚动效果的但是滚动条会被遮挡)
4.第四层div再旋转回来,保证里面的内容视觉效果和原本一样。
5.这里只设置横向滚动并且滚动鼠标滚轮的时候滚动是横向的,如果还需要纵向滚动可以设置第四层的style,通过$attrs把调用组件传入的属性直接传给第四层div以达到类似默认div的效果。
滚动条的美化参数 scrollbar.less
.scrollbar {
&::-webkit-scrollbar {
width : 7px;
height : 7px;
background-color: #f5f5f5;
}
/*定义滚动条轨道 内阴影+圆角*/
&::-webkit-scrollbar-track {
box-shadow : inset 0 0 6px rgba(0, 0, 0, 0.3);
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
border-radius : 10px;
background-color : #f5f5f5;
}
/*定义滑块 内阴影+圆角*/
&::-webkit-scrollbar-thumb {
border-radius : 10px;
box-shadow : inset 0 0 6px rgba(0, 0, 0, 0.1);
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.1);
background-color : #c8c8c8;
}
}