Angular 由一个bug说起之三:为什么时不时出现额外的水平/垂直滚动条?怎样能更好的防止它的出现?

news2024/11/26 1:53:39

目录:

  1. 什么是单元溢出

  2. 控制滚动条出现的属性

  3. 怎样能减少意外的滚动条出现

一、什么是单元溢出

在说到这个问题之前我们先简单阐述一下视图窗口(Viewport)视图内容(View Content)

视图窗口简单来说就是呈现内容的视口,浏览器就是一个窗口,其中所显示的内容就是视图内容。

而当元素里的内容(包括文本内容、图片、视频等内容)的大小超出窗口的大小区域时,内容会有一部分显示在盒子所在区域的外部,这就是单元溢出

二、控制滚动条出现的属性

CSS中对单元溢出处理的属性是overflow属性,该属性是overflow-xoverflow-y属性的简写。该属性常用的值有如下4个:

描述

visible

默认值。内容不会被修剪,超出部分会溢出到元素容器外面。

hidden

内容会被修剪,并且其余内容是不可见的。

scroll

内容会被修剪,但是浏览器会显示滚动条以便查看其余的内容。

auto

如果内容被修剪,则浏览器会显示滚动条以便查看其余的内容。

示例代码如下所示:

<div class="app-layout">
    <div class="viewport overflow-visible">
        <p class="overflow-description">overflow: visible</p>
        <div class="view-content"></div>
    </div>
    <div class="viewport overflow-hidden">
        <p class="overflow-description">overflow: hidden</p>
        <div class="view-content"></div>
    </div>
    <div class="viewport overflow-scroll">
        <p class="overflow-description">overflow: scroll</p>
        <div class="view-content"></div>
    </div>
    <div class="viewport overflow-auto">
        <p class="overflow-description">overflow: auto</p>
        <div class="view-content"></div>
    </div>
</div>
.app-layout {
    width: 100%;
    height: 100%;
    display: flex;
    flex-flow: row nowrap;
    .viewport {
        width: 400px;
        height: 500px;
        background-color: #87CEFA;
        margin-right: 20px;
        &.overflow-visible {
            overflow: visible;
        }
        &.overflow-hidden {
            overflow: hidden;
        }
        &.overflow-scroll {
            overflow: scroll;
        }
        &.overflow-auto {
            overflow: auto;
        }
        .overflow-description {
            font-size: 16px;
            font-family: Microsoft YaHei;
            line-height: 30px;
            text-align: center;
        }
        .view-content {
            width: 300px;
            height: 600px;
            background-color: #FFB6C1;
        }
    }
}

运行结果如下所示:

三、怎样能减少意外的滚动条出现

综上所述,滚动条的出现需要满足两个条件。第一,视窗的 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;
}

方案:

  1. 父级可以设定 overflow-x: hidden
  2. 严格控制内容的偏移

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

总结

虽然意外出现的滚动条是一个小问题,但是引发这个问题出现的原因却多种多样。上面的例子并不完全,只包含了我在平时工作中所遇到的情况。面对这种频发的小问题我们也是有一些可以尽量避免它的方法的:

  1. 理清 DOM 层级关系,尽量简化它。越简单的代码就越健壮,这是放在哪里都适用的道理。通过分析并明确视窗与内容的关系,我们不仅能有效避免上述情况的发生,还能降低其它问题出现的概率。
  2. 借助 UI 库来完成功能实现。
  3. 多使用自适应布局,在有动画或者渐变需求时多考虑视窗区域是否符合动画要求。
  4. 制定并遵循代码规范。规范的代码也是考察程序员能力的一个方面,清晰整洁的代码能够规避很多错误,并且也易于维护。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1292141.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RabbitMQ(一)概述

1 RabbitMQ 概念 RabbitMQ 是一个消息中间件&#xff1a;它接受并转发消息。你可以把它当做一个快递站点&#xff0c;当你要发送一个包裹时&#xff0c;你把你的包裹放到快递站&#xff0c;快递员最终会把你的快递送到收件人那里&#xff0c;按照这种逻辑 RabbitMQ 是一个快递站…

一文搞懂系列——你真的了解如何生成动态库了吗?

引言 动态库的编译&#xff0c;这有什么难度&#xff0c;这不是手到擒来的事情吗&#xff1f;无非不就是&#xff1a; gcc -FPIC -shared -o libxxx.so *.o *.c 我若是提出这些需求场景&#xff0c;阁下又如何应对呢&#xff1f; 动态库A依赖其他部分提供的能力。但是却不…

IT外包对中小企业的独特优势

在竞争激烈的商业环境中&#xff0c;企业的发展稍有缓慢&#xff0c;就很有可能被竞争对手快速赶超、趁机抢占市场。一些中小企业为了更好地应对市场变化和提高自身竞争力&#xff0c;越来越多地转向了IT外包服务。相较于大型企业&#xff0c;中小企业在选择IT外包时能够获得一…

SSL证书代理

众所周知&#xff0c;SSL证书已经成为当下网络安全中不可或缺的一个环节&#xff0c;对于很多开发公司来说&#xff0c;给自己的客户提供SSL证书安全服务也是最为基础的。 但是目前市面上像阿里云之类的证书服务商对于开发公司需要的证书并没有太大的一个优惠政策&#xff0c;给…

一:C语言常见概念

一&#xff1a;C语言常见概念 1.认识C语言&#xff1a; ​ C语言是人和计算机交流的语言 ​ C语言是一门面向过程的语言&#xff0c;而C&#xff0c;Java&#xff0c;Python等是一门面向对象的语言 ​ 软件开发&#xff08;项目&#xff09;&#xff1a;面向过程面向对象 …

python爬虫来抓取闲鱼二手机信息,小赚一笔

虽然海鲜市场现在已经不如以前了&#xff0c;但是还是可以捡漏的&#xff0c;省钱也是赚钱&#xff0c;最近正好有换机的准备&#xff0c;每天刷来刷去的浪费了好多时间&#xff0c;也会进入选择困难症。 参考了一些大神的思路写法&#xff0c;写了个简单抓取指定需求的爬虫代码…

微信服务号转订阅号的流程

服务号和订阅号有什么区别&#xff1f;服务号转为订阅号有哪些作用&#xff1f;很多小伙伴想把服务号改为订阅号&#xff0c;但是不知道改了之后具体有什么作用&#xff0c;今天跟大家具体讲解一下。首先我们知道服务号一个月只能发四次文章&#xff0c;但是订阅号每天都可以发…

JSP以监听生命周期为例 讲解监听器

好 最后 我们说说监听器 内容还是非常多的 这里 从老师哪里拿到的一个文案 大家可以查看具体内容 我们这里以监听声明周期为例 这边 我们在项目java模块下创建一个包 叫 listener 名字随便取 我们就这样 看着明显一点 然后 我们在下面创建一个java类 叫 test 因为是用来测试的…

一张图理解接口测试框架

测试框架先向测试数据库中插入测试数据&#xff08;如&#xff1a;name”Tom“&#xff09; 调用被测系统提供的接口&#xff08;传参&#xff1a;name”Tom“&#xff09; 从测试数据库中查到符合参数的数据 将查询到的数据组成Json格式&#xff0c;并返回给测试框架 提供…

坐标机械手配件有哪些?

直线模组是一种常见的机械传动装置&#xff0c;广泛应用于机械手等自动化设备中&#xff0c;在机械手中的主要作用是实现机械手的运动控制和定位。 直线模组具有高精度、高可靠性的特点&#xff0c;可以满足坐标机械手对运动精度和稳定性的要求&#xff0c;在坐标机械手的关节处…

详解线段树

前段时间写过一篇关于树状数组的博客树状数组&#xff0c;今天我们要介绍的是线段树&#xff0c;线段树比树状数组中的应用场景更加的广泛。这些问题也是在leetcode 11月的每日一题频繁遇到的问题&#xff0c;实际上线段树就和红黑树 、堆一样是一类模板&#xff0c;但是标准库…

Linux篇之在Centos环境下搭建Nvidia显卡驱动

一、前提条件 1、首先确认内核版本和发行版本&#xff0c;再确认显卡型号 uname -a // Linux localhost.localdomain 4.18.0-408.el8.x86_64 #1 SMP Mon Jul 18 17:42:52 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux1.2 cat /etc/redhat-release // CentOS Stream release 81.3…

logback日志框架使用

依赖引入 <dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.1.7</version> </dependency> 使用logback日志框架只需要引入以上即可&#xff0c;(我们平时使用较多的Slf4j…

获取Github Copilot的Token

可以在线提取出Github Copilot插件的Token&#xff0c;这样的话就可以把Token拿来做别的用处了&#xff0c;比如共享给其他人 Github Copilot是一款由GitHub和OpenAI合作开发的人工智能编程助手。它利用机器学习和自然语言处理技术&#xff0c;能够根据用户的输入自动生成代码…

使用DockerUI结合内网穿透工具轻松实现公网访问和管理docker容器

文章目录 前言1. 安装部署DockerUI2. 安装cpolar内网穿透3. 配置DockerUI公网访问地址4. 公网远程访问DockerUI5. 固定DockerUI公网地址 前言 DockerUI是一个docker容器镜像的可视化图形化管理工具。DockerUI可以用来轻松构建、管理和维护docker环境。它是完全开源且免费的。基…

Python小案例:while练习题

目录 while练习题&#xff1a;1、存款多少年能翻倍2.小球坠落长度计算3、猴子吃桃4、计算&#xff1a;1-23-4...99-100的和 while练习题&#xff1a; 1、存款多少年能翻倍 1万本金&#xff0c;年利息&#xff1a;0.0325&#xff0c;求连本带息多少年能翻倍 解析&#xff1a;…

IP地址定位技术的原理与应用

在当今的数字化时代&#xff0c;我们的在线活动每时每刻都在生成大量数据。其中&#xff0c;IP地址作为网络设备在互联网上的唯一标识&#xff0c;提供了一种独特的方式来追踪和定位这些活动。本文将深入探讨IP定位技术的原理及其在现实生活中的应用。 IP定位技术的原理 IP地址…

【Hive】——概述

1 什么是Hive 2 Hive 优点 3 Hive和Hadoop 的关系 4 映射信息记录 5 SQL语法解析、编译 Hive能将一个文件映射成为一张表&#xff0c;文件和表之间的关系称为映射 Hive的功能职责是将SQL语法解析编译成为MapReduce 6 Hive 架构 6.1 分析 6.2 架构图 6.3 用户接口 6.4 元数据存…

通信线缆是什么

通信线缆 电子元器件百科 文章目录 通信线缆前言一、通信线缆是什么二、通信线缆的类别三、通信线缆应用实例四、通信线缆的作用原理总结前言 每种线缆都有其特定的特性和用途。通信线缆起到连接和传输信号的作用,是实现通信和数据传输的重要组成部分。 一、通信线缆是什么 …

评论送书:一本书讲透Java线程:原理与实践

摘要&#xff1a;互联网的每一个角落&#xff0c;无论是大型电商平台的秒杀活动&#xff0c;社交平台的实时消息推送&#xff0c;还是在线视频平台的流量洪峰&#xff0c;背后都离不开多线程技术的支持。在数字化转型的过程中&#xff0c;高并发、高性能是衡量系统性能的核心指…