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

目录:

  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. 制定并遵循代码规范。规范的代码也是考察程序员能力的一个方面,清晰整洁的代码能够规避很多错误,并且也易于维护。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【flink番外篇】1、flink的23种常用算子介绍及详细示例(2)- keyby、reduce和Aggregations

Flink 系列文章 1、Flink 专栏等系列综合文章链接 文章目录 Flink 系列文章一、Flink的23种算子说明及示例6、KeyBy7、Reduce8、Aggregations 本文主要介绍Flink 的3种常用的operator&#xff08;keyby、reduce和Aggregations&#xff09;及以具体可运行示例进行说明. 如果需要…

【设计模式】职责链模式设计在线文档帮助系统

职责链模式设计在线文档帮助系统 任务三&#xff1a;使用职责链模式设计在线文档帮助系统 某公司欲开发一个软件系统的在线文档帮助系统&#xff0c;用户可以在任何一个查询环境中输入查询关键字&#xff0c;如果当前查询环境下没有相关内容&#xff0c;则系统会将查询按照一定…

Ubuntu22.04 使用Docker部署Neo4j出错 Exited(70)

项目场景&#xff1a; 最近需要使用Neo4j图数据库&#xff0c;因此打算使用docker部署 环境使用WSL Ubuntu22.04 问题描述 拉下最新Neo4j镜像&#xff0c;执行命令部署 启动容器脚本 docker run -d -p 7474:7474 -p 7687:7687 \ --name neo4j \ --env "NEO4J_AUTHneo…

git的安装及ssh配置(Linux)

环境 CentOS Linux release 7.9.2009 (Core) Xftp7 安装 方法一&#xff1a;yum安装 yum是一个客户端软件&#xff0c;就好比手机上的应用商店&#xff0c;帮助我们对软件的下载、安装和卸载 1、首先查看自己是否安装过git [rootxiaoxi ~]# git -bash: git: command not fo…

一文入门Python面向对象编程(干货满满)

在开始之前&#xff0c;我一直企图找到一个通俗直观的例子来介绍面向对象。找来找去&#xff0c;发现什么都可以是面向对象&#xff0c;什么又都不是面向对象。后来我发现&#xff0c;人类认识社会的方式更多的就是面向对象的方式。“物以类聚、人以群分”&#xff0c;这句话好…

观察者模式(常用)

观察者模式&#xff08;Observer模式&#xff09; 在现实世界中&#xff0c;许多对象并不是独立存在的&#xff0c;其中一个对象的行为发生改变可能会导致一个或者多个其他对象的行为也发生改变。例如&#xff0c;某种商品的物价上涨时会导致部分商家高兴&#xff0c;而消费者…

VPS简介:基于Amazon Ligtsail的概述

当你作为一个开发者&#xff0c;你想要开发自己的系统&#xff0c;构建自己的系统架构时&#xff0c;你会有以下两种选择&#xff1a;第一种就是亲自去挑选组件&#xff0c;例如&#xff1a;云服务器、存储、IP地址等等&#xff0c;然后再花时间自己组装起来&#xff0c;就像该…

VIVADO-FFT IP核学习记录

根据用户手册使用IP核 ① 找到user guide / product guide 并打开 ② 找到Customizing and Generating the Core(不同手册可能题目不一样)&#xff0c;查看IP核的创建过程中各个参数的意义和设置方法。 ③ 找到port description &#xff0c;查看接口注释 根据网络教程使用…

Python中PyQt5可视化界面通过拖拽来上传文件

注&#xff1a;这个窗口提供了一个快速上传文件的小tips&#xff0c;如果需要对上传的文件进行进一步处理的可以在“processFiles”函数或者编写其它函数进行扩充就可以。 1、需要安装模块 pip install PyQt5 2、运行效果 1、通过拖拽的方式上传需要的文件到窗口&#xff0c;会…

06 g2o 学习

文章目录 06 g2o 学习6.1 概念6.2 框架简介6.3 代码示例 06 g2o 学习 6.1 概念 g2o(General Graphic Optimization)是基于图优化的库。图优化是把优化问题表现成图的一种方式。一个图由若干个顶点(Vertex)&#xff0c;以及连接这这些顶点的边(Edge)组成。用顶点表示优化变量&…

2024品牌营销为何需要提供“情绪价值”和“感官滋养”?徐礼昭

什么是情绪价值&#xff1f; 品牌营销在当今市场中&#xff0c;已经超越了单纯的产品推广和销售&#xff0c;更多地涉及到提供“情绪价值”和“感官滋养”。 情绪价值是指产品或服务能够引发的消费者情感反应和共鸣&#xff0c;从而满足消费者情感需求的一种价值。它与产品的…

蓝桥杯 动态规划

01 数字三角形 #include<bits/stdc.h> using namespace std; const int N105; using lllong long; ll a[N][N],dp[N][N]; int main(){int n;cin>>n;for(int i1;i<n;i){for(int j1;j<i;j){cin>>a[i][j];}}for(int i5;i>1;i--){for(int j1;j<i;j){…

解决SecureFX的中文乱码问题

SecureFX的乱码截图 一般出现乱码问题&#xff0c;看起来会很烦&#xff0c;所以&#xff0c;我们要干掉它。 解决步骤&#xff1a; 1&#xff0c;在SecureFX中&#xff0c;选择“选项”-“全局选项”&#xff0c;打开对话框&#xff0c;不同的版本可能会显示略有不同&#x…

【Openstack Train】十五、glance命令合集

本文介绍了glance组件的常用命令。关于openstack的安装&#xff0c;可以参考以下内容&#xff1a; 【Openstack Train安装】一、虚拟机创建 【Openstack Train安装】二、NTP安装 【Openstack Train安装】三、openstack安装 【Openstack Train安装】四、MariaDB/RabbitMQ 安…

【java+vue+微信小程序项目】从零开始搭建——健身房管理平台(1)spring boot项目搭建、vue项目搭建、微信小程序项目搭建

项目笔记为项目总结笔记,若有错误欢迎指出哟~ 【项目专栏】 【java+vue+微信小程序项目】从零开始搭建——健身房管理平台(1)项目搭建 持续更新中… java+vue+微信小程序项目】从零开始搭建——健身房管理平台 项目简介Java项目搭建(IDEA)1.新建项目2.项目类型3.项目设置4…

Springboot养老院信息管理系统的开发-计算机毕设 附源码 27500

Springboot养老院信息管理系统的开发 摘 要 随着互联网趋势的到来&#xff0c;各行各业都在考虑利用互联网将自己推广出去&#xff0c;最好方式就是建立自己的互联网系统&#xff0c;并对其进行维护和管理。在现实运用中&#xff0c;应用软件的工作规则和开发步骤&#xff0c;…

「Swift」类淘宝商品瀑布流展示

前言&#xff1a;需要做一个类似于淘宝商品页面的瀑布流展示 结构分析&#xff1a; ps&#xff1a;图片来源 思路分析&#xff1a; 该瀑布流主要还是基于UICollectionView进行展示&#xff0c;只是在cell展示的UICollectionViewFlowLayout需要进行相应调整和自定义&#xff…

医药行业:轻松学会超低温冰箱技能

超低温冰箱在医疗、科研和生物领域中扮演着至关重要的角色&#xff0c;用于存储和保护对温度极为敏感的样品和药品。 然而&#xff0c;由于这些冰箱内的温度波动可能导致样品的损坏&#xff0c;因此对超低温冰箱的监控变得至关重要。 客户案例 医疗研究机构 上海某医疗研究机…

【Seata源码学习 】篇六 全局事务提交与回滚

【Seata源码学习 】篇六 全局事务提交与回滚 全局事务提交 TM在RPC远程调用RM后,如果没有出现异常&#xff0c;将向TC发送提交全局事务请求io.seata.tm.api.TransactionalTemplate#execute public Object execute(TransactionalExecutor business) throws Throwable {// 1. …

大文件分片上传、分片进度以及整体进度、断点续传【前端原生、后端 Koa、Node 原生】(一)

分片进度 效果展示&#xff0c;一个分片是 500MB 的 这个分片大小是 10MB 的 大文件分片上传 效果展示 前端 思路 前端的思路&#xff1a;将大文件切分成多个小文件&#xff0c;然后并发给后端。 页面构建 先在页面上写几个组件用来获取文件。 <body><input ty…