CSS - 你知道都有哪些方案可以隐藏一个元素吗

难度级别:初级及以上                                 提问概率:70% 

在前端开发中,隐藏元素并不是一个陌生的话题。根据业务场景不同,实现方案也多种多样,在面试中,应该尽可能多的描述自己遇到过的场景,使用过的方案。而不应该吝啬描述,只是单纯的说出一些解决点子,给面试官一种指导型回复。这一章中,我们将整理总结一些关于隐藏元素的方案,但需要强调的是,这一章重点并非是要记忆这些隐藏或移除一个元素的解决方案,而是掌握根据一个点发散的去整理相关知识体系的过程,这对面试来说是非常重要的。

 

目录

1 display隐藏

2 visibility隐藏

3 opacity隐藏

4 z-index设置为更低级别

5 宽高设置为0

6 clip裁剪

7 为元素添加hidden属性

8 scale缩放

9 font-size设置为0

10 Vue中的v-if和v-show

10的小结


1 display隐藏

使用display:none的CSS属性设置,可以将元素隐藏,虽然用户在页面中看不见这个元素,但它却还存在于页面DOM树中。需要注意的是,这种方式将会在页面中瞬间留出空白区域,也就是说需要其他元素进行补位,这势必引起页面的重排。

HTML代码:
<div class="box"></div>
CSS代码:
<style>
.box {
display: none;
width: 100px;
height: 100px;
background: red;
}
</style>

2 visibility隐藏

通过visibility:hidden;的CSS属性设置,虽然用户看不见这个元素,但元素所占的位置仍然存在,也就是宽和高并没有改变。这种方式与display隐藏有明显的区别,并不会引起重排。

HTML代码:
<div class="box"></div>

CSS代码:
<style>
.box {
visibility: hidden;
width: 100px;
height: 100px;
background: red;
}
</style>

3 opacity隐藏

将CSS的opacity属性值设置为0,又是一种截然不同的实现方案,这种方式可以理解为一种相对用户的假隐藏,而非相对于浏览器的隐藏。这个元素是真实存在的,只是将内容设置为透明,给用户一种不存在的感觉。但需要注意的是,如果这个元素自身带有点击事件,用户仍然可以无意间点中元素区域,并触发事件。

HTML代码:
<div class="box" onclick="opaClick()"></div>
CSS代码:
<style>
.box {
opacity: 0;
width: 100px;
height: 100px;
background: red;
}
</style>
Javascript代码:
<script>
function opaClick () {
alert(‘真的隐藏了吗?’);
}
</script>

4 z-index设置为更低级别

当给元素设置CSS样式position:absolute;绝对定位后,再辅助以z-index更低的级别,也可以实现元素的隐藏。采用这种实现方案后,使元素脱离的原本的DOM文档流,使其可以隐藏于其他元素的背部。但需要注意的是,这个方案的重点在于隐藏于其他元素背部,但如果当前上下文环境没有其他元素内,很显然这种方式就不成立了。不过结合真实业务场景来看,当前上下文环境没有其他元素的情况应该是很少吧。

与此类似的方案还有,为元素设置绝对定位,然后将left属性值设置为超小的负数;还有为父元素设置overflow:hidden属性,然后为元素设置绝对定位,再辅助以超大负数的left属性值,这些做法基本都是相似的,都是为了通过使元素脱离用户网页视野,来达到隐藏的效果。

HTML代码:
<div class="box-show"></div>
<div class="box"></div>
CSS代码:
<style>
.box-show {
position: absolute;
width: 100px;
height: 100px;
background: yellow;
}
.box {
position: absolute;
width: 100px;
height: 100px;
background: red;
z-index: -1;
}
</style>

5 宽高设置为0

我们知道页面中一个元素之所以能被用户看见,是因为浏览器在渲染之初,通过对CSS样式的计算,为元素预留出了相应的区域,然后再逐步渲染区域内的内容。但如果把元素的宽和高设置为0,也就不符合浏览器渲染的区块规则,自然也就达到了隐藏的效果。但一般来说一个块元素内会包含其他子元素,即便父元素的宽高设置为0,达到了隐藏效果,但也不能保证子元素不会超出显示。所以还需要辅助以overflow:hidden的上下文边界规范设置。

HTML代码:
<div class="box">
<div class="inner"></div>
</div>
CSS代码:
<style>
.box {
overflow: hidden;
width: 0;
height: 0;
background: red;
}
.inner {
width: 200px;
height: 200px;
background: yellow;
}
</style>

6 clip裁剪

clip裁剪功能,提供了一个rect属性函数,可以传入上、右、下、左4个参数值,表示显示区域距离元素远点的距离。试想一下,如果把元素内容全部裁剪掉,是不是也可以达到隐藏的效果呢。但需要注意的是,这种裁剪方案只针对绝对定位的元素有效果。

HTML代码:
<div class="box"></div>
CSS代码:
<style>
.box {
position: absolute;
width: 100px;
height: 100px;
background: red;
clip: rect(0 0 0 0);
}
</style>

7 为元素添加hidden属性

也可以采用直接在HTML标签上添加hidden属性的方式,实现效果类似于display:none的方案。

HTML代码:

<div class="box" hidden></div>

8 scale缩放

缩放可以使元素缩小或者放大,这取决于scale函数内参数的数值。但如果传入参数值为0,也可以达到完全隐藏元素的效果。需要注意的是,scale缩放功能对行内元素不起作用,这意味着要么是块元素,要么是行内块元素才可以使用这种方案。虽然scale函数内传入0可以达到完全隐藏的效果,缩放的原点却是元素的中心原点,这就导致虽然用户看不见真实的元素内容了,但元素却还类似于visibility:hidden的实现方案,占据着一定的区域。

HTML代码:
<div class="top-box"></div>
<div class="box"></div>
<div class="bottom-box"></div>
CSS代码:
<style>
.top-box {
width: 100px;
height: 100px;
background: yellow;
}
.box {
width: 100px;
height: 100px;
background: red;
transform: scale(0);
}
.bottom-box {
width: 100px;
height: 100px;
background: green;
}
</style>

 

9 font-size设置为0

在浏览器中,一般情况下设置字体样式font-size小于12px的时候,就不容易识别了,而是以最小的12px来渲染。但如果是块元素,为字体设置font-size属性值为0的时候,便可以将文字隐藏;而如果是行内元素字体设置font-size属性值为0的时候,则整个行内元素都会被隐藏掉。

HTML代码:
<div class="box">隐藏一个元素</div>
CSS代码:
<style>
.box {
display: inline;
width: 100px;
height: 100px;
background: red;
font-size: 0;
}
</style>

10 Vue中的v-if和v-show

在说Vue的v-if和v-show这两个指令之前,我们先来看一下,如果不使用第三方框架,做一个自定义弹框的过程。

假如当前的业务需求场景是,点击按钮,生成一个弹框,要求弹框包含背景遮罩层、标题、提示内容展示、关闭按钮等元素,点击“关闭按钮”,执行关闭弹出事件,代码如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>弹出提示</title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
.cover {
                display: flex;
                align-items: center;
                justify-content: center;
                position: fixed;
                left: 0;
                top: 0;
                width: 100vw;
                height: 100vh;
                background: rgba(0, 0, 0, 0.2);
                z-index: 10;
            }
            .dialog-box {
                overflow: hidden;
                width: 360px;
                height: 190px;
                background: #FFF;
                border-radius: 4px;
            }
            .dialog-title {
                height: 40px;
                padding-left: 20px;
                line-height: 40px;
                font-size: 18px;
                background: blue;
                color: #FFF;
                font-weight: 600;
            }
.dialog-txt {
                height: 100px;
                line-height: 100px;
                text-align: center;
            }
            .dialog-btn {
                margin: 0 auto;
                width: 120px;
                height: 38px;
                line-height: 38px;
                background: blue;
                text-align: center;
                color: #FFF;
                border-radius: 4px;
                cursor: pointer;
            }
        </style>
    </head>   
	<body>
        <button onclick="showDialog('提示文字内容')">显示弹框</button>
        <script>
            function showDialog(txt) {
                let dialogDom = document.querySelector('#coverId');
                // 如果创建过弹框,则直接进行展示
                if (dialogDom) {
                    dialogDom.style.display = 'flex';
} else {  // 如果未创建过弹框,则进行创建
                    // 定义弹框DOM内容
                    let newDom = `<div class="dialog-box">
                            <p class="dialog-title">提示</p>
                            <div class="dialog-txt">${ txt }</div>
                            <div class="dialog-btn" onclick="hideDialog()">知道了</div>
                        </div>`;
                    // 定义弹框背景遮罩层
                    let coverDom = document.createElement('div');
                    coverDom.setAttribute('class', 'cover');
                    coverDom.setAttribute('id', 'coverId');
                    coverDom.innerHTML = newDom;
                    let bodyDom = document.querySelector('body');
                    // 将弹框插入body元素底部
                    bodyDom.appendChild(coverDom);
                }
            }
            // 关闭弹出,只是做隐藏操作
            function hideDialog() {
                let dialogDom = document.querySelector('#coverId');
                dialogDom.style.display = 'none';
            }
        </script>
    </body>
</html>

 弹框展示效果如图

 

10的小结

以上案例通过简单的代码,实现了日常业务开发中比较常见的弹框功能。本案例重点并非想要描述如何实现一个弹框,而想要表达的是,这个按钮只是页面众多元素其中的一个,或许是一个重点功能,用户会频繁的点击,又或许只是一个弱化的功能,用户一直到离开网页都不会去点击这个按钮。所以弹框也不应该是页面初始化就需要加载的,必要的做法是当用户第一次需要使用弹框功能的时候,再去创建弹框,而一旦第一次创建后,关闭只是隐藏。当用户需要再次打开弹框的时候,就不需要做创建操作了,而是直接将之前隐藏的弹框再次展示即可。

通过以上这种方式最大限度节约浏览器的开销,那么在Vue项目中使用v-if和v-show也是同样的道理。我们知道v-if是通过依赖数据判断是否需要创建或移除对应的组件,而v-show则是在初始化过程中就已经将组件创建完成,只是通过依赖数据的改变,进而判断是否需要对组件进行隐藏或者显示。这就需要在项目场景中,根据页面中组件显示与隐藏切换的频次,以及切换后组件内容是否需要继续保持等因素,判断两种指令更适合使用的场景,而绝对不是项目全篇的使用v-if这一个指令。


刷题思考

    这是一道非常经典而又高频的CSS面试题,它体现了CSS面试题中一个非常大的特点,那就是几乎每个问题都会有非常多的解决方案。但问题的症结就在于每种解决方案都不会很难,而细节却很多。所以,CSS面试题的考察点并不是要看求职者掌握的多么

有深度,而是考察在日常工作中,对于某一类问题是否有一个知识点聚合的意识。

我们知道,一旦接触的项目多了,同一类问题有时候使用同一种方案却不能很好的得到解决,这个时候就需要通过这种知识聚合的意识,变换不同的思路,快速找到解决方案。


类似考点

    因为CSS细节知识点非常多,所以这道题非常有代表性,它可以通过一个问题点,让人发散的去思考非常多相关联的知识点,最终通过最初的问题点聚合到一起,形成一个知识体系。面试官还可能会问,例如请你说一下垂直居中的解决方案都有哪些?例如请你说一说清楚浮动的方案都有哪些等。

相关推荐

  1. css隐藏元素方式哪些

    2024-04-04 17:40:02       24 阅读
  2. 知道Web框架哪些?

    2024-04-04 17:40:02       30 阅读
  3. 知道数据库哪些约束

    2024-04-04 17:40:02       18 阅读
  4. CSS隐藏元素方法

    2024-04-04 17:40:02       9 阅读
  5. ReentrantLock 原理知道

    2024-04-04 17:40:02       16 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-04 17:40:02       17 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-04 17:40:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-04 17:40:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-04 17:40:02       18 阅读

热门阅读

  1. 【实时监控主机与某个IP的网络连接情况】

    2024-04-04 17:40:02       21 阅读
  2. 在Go语言中如何调试

    2024-04-04 17:40:02       18 阅读
  3. C语言——字符函数和字符串函数(下)

    2024-04-04 17:40:02       18 阅读
  4. springboot实现七牛云的文件上传下载

    2024-04-04 17:40:02       17 阅读
  5. Linux常见命令简介

    2024-04-04 17:40:02       15 阅读
  6. 探索Django REST框架构建强大的API

    2024-04-04 17:40:02       18 阅读
  7. redis-乐观锁Watch使用方法

    2024-04-04 17:40:02       19 阅读