综上所述,滚动条的出现需要满足两个条件。
第一,视窗的
overflow
被设定成允许滚动条出现的属性
(scroll, auto)
。第二,内容超出了视窗的显示区域。
只有当这两个条件都满足时才会出现滚动条。那么针对这两点有不同的解决方案。
一、视窗的
overflow
属性只在需要的时候才设定为
auto
或者
scroll
。
根据设计要求,在允许滚动的视窗设定允许滚动条出现的属性。在不允许滚动条出现的地方可以设定
hidden
属性,并且严格控制视图内容的尺寸。
二、内容超出视窗区域,这是出现意外滚动条最常见的原因。
虽然视图的内容也是由我们来控制,看似是不会出现滚动条的情况,但是我们的页面是可以互动的。随着互联网的发展,页面的互动更加的频繁。这就涉及到了动画,偏移,缩放或者弹出层等功能的运用。往往这时内容会突破视图区域,当这个视图又允许滚动时,很容易就会出现多余的滚动条。
1.
当内容出现偏移时
示例:
示例代码如下所示:
<div class="app-layout">
<div class="viewport">
<p class="overflow-description">偏移或动画</p>
<button class="trigger" (click)="running = !running">Start</button>
<div class="view-content" [ngClass]="{ 'content-translate': running }"></div>
</div>
</div>
.app-layout {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.viewport {
width: 400px;
height: 500px;
background-color: #87CEFA;
margin-right: 20px;
overflow: auto;
.overflow-description {
font-size: 16px;
font-family: Microsoft YaHei;
line-height: 30px;
text-align: center;
}
.trigger {
width: 60px;
height: 36px;
display: block;
line-height: 36px;
font-size: 16px;
font-family: Microsoft YaHei;
text-align: center;
border-radius: 5px;
margin: 0 auto 20px;
cursor: pointer;
}
.view-content {
width: 200px;
height: 200px;
background-color: #FFB6C1;
transition: all 1s ease-in-out;
position: relative;
left: 0;
&.content-translate {
left: 300px;
}
}
}
}
import { Component } from '@angular/core';
@Component({
selector: 'extra-scroll-bar',
templateUrl: './extraScrollBar.component.html',
styleUrls: ['./extraScrollBar.component.less']
})
export class ExtraScrollBarComponent{
running = false;
}
方案:
-
父级可以设定
overflow-x: hidden
-
严格控制内容的偏移
2.
鼠标悬停出现提示框
示例:
示例代码如下所示:
<div class="app-layout">
<div class="viewport">
<p class="overflow-description">提示框</p>
<div class="view-content">
<div class="tooltip">信息提示框</div>
</div>
</div>
</div>
.app-layout {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.viewport {
width: 400px;
height: 500px;
background-color: #87CEFA;
overflow: auto;
.overflow-description {
font-size: 16px;
font-family: Microsoft YaHei;
line-height: 30px;
text-align: center;
}
.view-content {
width: 200px;
height: 200px;
background-color: #FFB6C1;
position: relative;
margin: 0 auto;
&:hover {
.tooltip {
display: block;
}
}
.tooltip {
width: 120px;
height: 80px;
background-color: #FFFFFF;
font-size: 14px;
font-family: Microsoft YaHei;
line-height: 80px;
text-align: center;
position: absolute;
top: 0;
left: 200px;
display: none;
}
}
}
}
方案:
1. 借助
UI
组件库,其中的
tooltip
不在目标区域层级,而是
body
的子元素,不影响视窗
图中使用的是
Angular Material
,其它框架也有许多类似的
UI
库可供选择
2. 自己造轮子,完成一个类似于
UI
库的
tooltip
组件
3.
视图内容属性 box-sizing
示例:
示例代码如下所示:
<div class="app-layout">
<div class="viewport">
<p class="overflow-description">Box Sizing</p>
<div class="view-content"></div>
</div>
</div>
.app-layout {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.viewport {
width: 400px;
height: 500px;
background-color: #87CEFA;
overflow: auto;
.overflow-description {
font-size: 16px;
font-family: Microsoft YaHei;
line-height: 30px;
text-align: center;
}
.view-content {
width: 380px;
height: 400px;
background-color: #FFB6C1;
position: relative;
margin: 0 auto;
padding: 0 20px;
}
}
}
方案:
建议所有的
div 设定 box-sizing: border-box,效果如下:
另外,即便设置了
box-sizing: border-size
。内容区域的
margin
也会对视窗产生类似的影响,这时候我们最好使用其它布局方式代替
margin
,或者计算好尺寸。
4.
当内容部分缩放时
示例:
示例代码如下所示:
<div class="app-layout">
<div class="viewport">
<p class="overflow-description">缩放</p>
<div class="view-content"></div>
</div>
</div>
.app-layout {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.viewport {
width: 400px;
height: 500px;
background-color: #87CEFA;
overflow: auto;
.overflow-description {
font-size: 16px;
font-family: Microsoft YaHei;
line-height: 30px;
text-align: center;
}
.view-content {
width: 380px;
height: 400px;
background-color: #FFB6C1;
position: relative;
margin: 0 auto;
transform-origin: center center;
transition: all 1s ease-in-out;
&:hover {
width: 450px;
height: 450px;
}
}
}
}
方案:
在内容缩放时为视窗设定
overflow: hidden 或者 overflow: visible
5.
多层嵌套内部元素溢出
示例:
示例代码如下所示:
<div class="app-layout">
<div class="viewport">
<p class="overflow-description">多层嵌套内部元素溢出</p>
<button class="trigger" (click)="running = !running">Start</button>
<div class="view-content">
<p class="overflow-description">Content</p>
<div class="view-child-content" [ngClass]="{ 'content-translate': running }">
<p class="overflow-description">Content Child</p>
</div>
</div>
</div>
</div>
.app-layout {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.viewport {
width: 400px;
height: 500px;
background-color: #87CEFA;
margin-right: 20px;
overflow: auto;
.overflow-description {
font-size: 16px;
font-family: Microsoft YaHei;
line-height: 30px;
text-align: center;
}
.trigger {
width: 60px;
height: 36px;
display: block;
line-height: 36px;
font-size: 16px;
font-family: Microsoft YaHei;
text-align: center;
border-radius: 5px;
margin: 0 auto 20px;
cursor: pointer;
}
.view-content {
width: 360px;
height: 360px;
background-color: #FFB6C1;
margin: 0 auto;
position: relative;
.view-child-content {
width: 120px;
height: 120px;
background-color: #D3D3D3;
position: absolute;
top: 100px;
left: 200px;
transition: all 1s ease-in-out;
&.content-translate {
left: 300px;
}
}
}
}
}
import { Component } from '@angular/core';
@Component({
selector: 'extra-scroll-bar',
templateUrl: './extraScrollBar.component.html',
styleUrls: ['./extraScrollBar.component.less']
})
export class ExtraScrollBarComponent{
running = false;
}
方案:
减少层级嵌套,明确每个
div 的用途,在有必要的地方加上 overflow: hidden