simker

Life is too short, just make it.


  • 首页

  • 归档

  • 分类

  • 标签

  • 关于

  • 音乐

  • 搜索

如何用css隐藏scrollbar

发表于 2021-10-22 更新于 2021-10-30 分类于 CSS 阅读次数: Disqus:
本文字数: 4.4k 阅读时长 ≈ 4 分钟

我是怎么遇到这个问题的?

其实这个问题在去年我就遇到过了,准确的说不是我遇到了,是同事(舒柳)遇到了,与我一起探讨怎么解决这个问题,当时也是惭愧,没能给同事解决。今天在项目里面再一次遇到这个问题,瞬间记上心头,研究了一下,解决了这个问题,随笔记下以便后续查看。

问题的根本

下拉滑动的scrollbar影响了整体的设计,布局等。原本有这个scrollbar是给用户一个提示:诶,下拉可以看到更多内容哦~。但是碍于设计等诸多原因,我想把它干掉。

解决方案

核心思路:

  • 利用overflowY: scroll 让溢出内容滚动
  • 利用overflow: hidden 这条样式隐藏掉scrollbar

上面两句话搞定了直接上代码。
首先是问题复现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Test.tsx
import React from "react";
import { RouteComponentProps } from "react-router";

import less from './Test.module.less'

interface ownProps extends RouteComponentProps {
}

const Test = (props: ownProps): JSX.Element => {
return (
<div className={less.container}>
<div className={less.child} id="box">
{Array.from({ length: 99 }).map((item, index) => {
return <p>{index} - 文本文本文本文本文本文本文</p>
})}
</div>
</div>
)
};

export default Test;

样式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Test.module.less
@height: 800px;

.container {
background-color: ghostwhite;
height: 100vh;
width: 100vw;
position: relative;

.child {
background: white;
position: absolute;
overflow: hidden;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: @height;
height: @height;
overflow-y: scroll;
& > * {
text-align: center;
}
}
}

这里我让container铺满全屏,且用定位固定child的位置让其居中,虽然我给了child 800像素的宽高,但是在child里面我写了大量的<P>标签,高度是远远溢出的。

好了,现在我已经复现了问题,接下来就要用overflow: hidden 这条样式隐藏掉scrollbar。

不多说直接上修改后的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Test.tsx
import React from "react";
import { RouteComponentProps } from "react-router";

import less from './Test.module.less'

interface ownProps extends RouteComponentProps {
}

const Test = (props: ownProps): JSX.Element => {
return (
<div className={less.container}>
<div className={less.parent}>
<div className={less.child} id="box">
{Array.from({ length: 99 }).map((item, index) => {
return <p>{index} - 文本文本文本文本文本文本文</p>
})}
</div>
</div>
</div>
)
};

export default Test;

样式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// Test.module.less
@height: 800px;

.container {
background-color: ghostwhite;
height: 100vh;
width: 100vw;
position: relative;
.bar {
position: absolute;
transform: translateX(-50%);
left: 50%;
top: 100px
}

.parent {
background: white;
position: absolute;
overflow: hidden;
width: calc(@height - 17px);
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
.child {
width: @height;
overflow-y: scroll;
& > * {
text-align: center;
}
}
}
.parent,.child {
height: @height;
}
}

这样,你可以看到scrollbar 被完全隐藏了起来,我让parent的宽度略小于child的宽度,以便让其在x方向上隐藏掉了scrollbar。

当然我也可把这个封装成一个组件以后直接拿来即用。
组件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// component/HiddenScrollbar.tsx
import React, { CSSProperties } from 'react';

interface IProps {
component: any,
wrapperStyle?: CSSProperties,
}

const HiddenScrollbar = (props: IProps): JSX.Element => {
const { component: WrappedComponent, wrapperStyle } = props;

// @ts-ignore
const width = typeof wrapperStyle.width === "number" ? `${wrapperStyle.width}px` : wrapperStyle.width;
const selfStyle = {
// @ts-ignore
height: wrapperStyle.height,
// @ts-ignore
width: `calc(${width} - 17px)`,
overflow: "hidden"
};

return <div style={{ ...wrapperStyle, ...selfStyle }}>
<WrappedComponent />
</div>
};

export default HiddenScrollbar;

使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// Text.tsx
import React from "react";
import { RouteComponentProps } from "react-router";

import less from './Test.module.less'
import HiddenScrollbar from "../component/HiddenScrollbar";

interface ownProps extends RouteComponentProps {
}

const Test = (props: ownProps): JSX.Element => {
return (
<div className={less.container}>
<HiddenScrollbar
wrapperStyle={{
background: "white",
position: "absolute",
left: "50%",
top: "50%",
transform: "translate(-50%, -50%)",
width: "800px",
height: "800px",
}}
component={() => <div className={less.child} id="boxs">
{Array.from({ length: 99 }).map((item, index) => {
return <p>{index} - 文本文本文本文本文本文本文</p>
})}
</div>}
/>
</div>
)
};

export default Test;

以此谨记下我在前端的爬坑。

Cai xian 微信支付

微信支付

Cai xian 支付宝

支付宝

# CSS
记一次关于extends的bug
记一次用vite搭建react的经历
Cai xian

Cai xian

A super nice guy!
24 日志
12 分类
15 标签
© 2019 – 2021 Cai xian | 70k | 1:04
由 Hexo 强力驱动 v3.9.0
|
主题 – NexT.Pisces v7.3.0
|