最近在群里,有个小伙伴问了这么一道很有趣的问题:

  1. CSS 能否实现,容器再某个高度下是某种表现,一旦超出某个高度,则额外展示另外一些内容

为了简化实际效果,我们看这么一张示意效果图:

可以看到,当容器高度没有超过某一个值时,没有箭头图标。反之,箭头图标出现。

这个效果在很多场景都会出现,可以算是一个高频场景,那么在今天,我们能否不使用 JavaScript,仅仅凭借 CSS 实现类似于这样的功能呢?

答案当然是可以,XBoxYan 大佬在 CSS 实现超过固定高度后出现展开折叠按钮 介绍了一种非常巧妙的借助浮动的解法,十分有意思,感兴趣的同学可以先行一步了解。

当然,浮动 float 在现如今的 CSS 世界,运用的已经非常少了。那么除了浮动,还有没有其它有意思的解法?本文我们将一起来探究探究。

方法一:借助最新的容器查询

第一种方法,非常简单,但是对兼容性有所要求。那就是使用容器查询 -- @container 语法。

容器查询在 新时代布局新特性 -- 容器查询 也详细介绍过。

简单而言,容器查询它给予了 CSS,在不改变浏览器视口宽度的前提下,只是根据容器的宽度或者高度变化,对布局做调整的能力。

基于这个场景,我们假设我们有如下的 HTML/CSS 结构:

<div class="g-container">
<div class="g-content">
Lorem ipsum dolor s...
</div>
</div>
.g-container {
position: relative;
width: 300px;
height: 300px;
resize: vertical;
overflow: hidden; .g-content {
height: 100%;
} .g-content::before {
content: "↑";
position: absolute;
bottom: 0px;
left: 50%;
transform: translate(-50%, 0);
}
}

它是这么一个样式效果:

其中,我们给元素 .g-content 添加了 resize: vertical,让它变成了一个可以在竖直方向上通过拖动改变高度的容器,以模拟容器在不同内容的场景下,高度不一致的问题:

我们通过元素的伪元素实现了箭头 ICON,并且它是一直显示在容器内的。

下面,我们通过简单的几句容器查询代码,就可以实现让箭头 ICON,只在容器高度超过特定高度的时候才出现:

.g-container {
container-type: size;
container-name: container;
} @container container (height <= 260px) {
.g-content::before {
opacity: 0;
}
}

简单解释一下:

  1. .g-container 它被用作容器查询的目标容器

    • container-type 属性指定了容器的类型为 size,表示我们将使用容器的尺寸来应用样式。
    • container-name 属性指定了容器的名称为 container,以便在后面的容器查询规则中引用。
  2. @container container (height <= 260px) {} 表示这是一个容器查询规则,在括号中的条件 (height <= 260px) 表示当容器的高度小于等于 260px 时,应用该规则下的样式
  3. 具体规则为,如果容器的高度小于等于 260px 时,.g-content 元素的伪元素将变得透明

这样,我们就非常简单的实现了容器在不同高度下,ICON 元素的显示隐藏切换:

完整的代码,你可以戳这里:CodePen Demo -- flexible content

当然,这个方案的唯一缺点在于,截止至今天(2023-11-11),兼容性不是那么好:

那,有没有兼容性更好的方案?当然,来我们一起来看看 clamp + calc 的方案。

方法二:clamp + calc 大显神威

上面效果的核心在于:

  1. 如果容器的高度大于某个值,显示样式 A
  2. 如果容器的高度小于等于某个值,显示样式 B

那么想想看,如果拿容器的高度减去一个固定的高度值,会发生什么?假设一下,ICON 元素的 CSS 代码如下:

.g-content::before {
content: "↑";
position: absolute;
left: 50%;
transform: translate(-50%, 0);
bottom: calc(100% - 200px);
}

仔细观察 bottom: calc(100% - 200px),在元素的 bottom 属性中,100% 表示的是容器当前的高度,因此 calc(100% - 200px) 的含义就代表,容器当前高度减去一个固定高度 200px。因此:

  1. 当容器高度大于 200pxcalc(100% - 200px) 表示的是一个正值
  2. 当容器高度小于 200pxcalc(100% - 200px) 表示的是一个负值
  3. 当容器高度等于 200pxcalc(100% - 200px) 表示 0

我们看看这种情况下,整个 ICON 的表现是如何的:

可以看到,当容器高度大于 200px 的时候,箭头 ICON 确实出现了,但是,它无法一直定位在整个容器的最下方

有什么办法让它在出现后,一直定位在容器的最下方吗?

别忘了,CSS 中,还有几个非常有意思的数学函数:min()max()clamp(),它们可以有效限定动态值在某个范围之内!

不太了解的,可以看看这篇 现代 CSS 解决方案:CSS 数学函数

利用 clamp(),我们可以限定计算值的最大最小范围,在这个场景下,我们可以限制 bottom 的最大值为 10px

.g-content::before {
// ...
bottom: clamp(-99999px, calc(100% - 200px), 10px);
}

上面的代码 clamp(-99999px, calc(100% - 200px), 10px),核心在于,如果 calc(100% - 200px) 的计算值大于 10px,它只会取值为 10px,利用这个技巧,我们可以在容器高度超长时,把箭头 ICON 牢牢钉在容器的下方,无论容器的高度是多少:

到此,结束了吗?显然没有。

虽然上面的代码,解决当 calc(100% - 200px) 的计算值大于 10px 的场景,但是没有解决,当 calc(100% - 200px) 的计算值处于 -10px ~ 10px 这个范围内的问题。

我们可以清楚的看到,当我们往下拖动容器变高的时候,箭头元素是逐渐慢慢向上出现,而不是突然在某一个高度下,直接出现,所以在实际使用中,会出现这种 ICON 只出现了一半的尴尬场景:

但是,莫慌!这个问题也好解决,我们只需要给 calc(100% - 200px) 的计算值,乘上一个超级大的倍数即可。原因在于:

  1. calc(100% - 200px) 的计算值是负数时,我们其实不希望 ICON 出现,此时,乘上一个超级大的倍数,依然是负数,不影响效果
  2. calc(100% - 200px) 的计算值是正数时,为了避免 ICON 处在只漏出部分的尴尬场景,通过乘上一个超级大的倍数,让整个计算值变得非常大,但是由于又有 clamp() 最大值的限制,无论计算值多大,都只会取 10px

看看代码,此时,整个 bottom 的取值就改造成了:

.g-content::before {
// ...
bottom: clamp(-9999px, calc(calc(100% - 200px) * 100000), 10px);
}

通过,将 calc(100% - 200px) 的值,乘上一个超大的倍数 100000,无论是正值还是负值,我们把计算值放大了 100000 倍。这样,整个效果就达成了我们想要的效果:

仔细看上图,ICON 元素从渐现,变成了瞬间出现!与上面的 @container 效果几乎一致,最终达成了我们想要的效果。

其核心就在于 clamp(-9999px, calc(calc(100% - 200px) * 100000), 10px),一定需要好好理解这一段代码背后的逻辑。

基于此,我们就巧妙的利用 clamp() + calc() 方法,近似的实现了类似于 if/else 的逻辑,实在是妙不可言!

CodePen Demo -- flexible content

最后

好了,本文到此结束,希望本文对你有所帮助

更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。

如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。

CSS 也能实现 if 判断?实现动态高度下的不同样式展现的更多相关文章

  1. css中height 100vh的应用场景,动态高度百分比布局,浏览器视区大小单位

    css中height 100vh的应用场景,动态高度百分比布局,浏览器视区大小单位 height:100vh 一些只能vw, vh才能完成的应用场景: 1. 场景之:元素的尺寸限制 vw vh 主要是 ...

  2. CSS 奇技淫巧:动态高度过渡动画

    这个问题源自于掘金上的一个留言,一个朋友问到,为什么我下面这段代码的高度过渡动画失效了? 伪代码大概是这样: { height: unset; transition: all 0.3s linear; ...

  3. 第一百一十八节,JavaScript,动态加载脚本和样式

    JavaScript,动态加载脚本和样式 一动态脚本 当网站需求变大,脚本的需求也逐步变大.我们就不得不引入太多的JS脚本而降低了整站的性能,所以就出现了动态脚本的概念,在适时的时候加载相应的脚本. ...

  4. 动态环境下的slam问题如何解决?

    作者:颜沁睿链接:https://www.zhihu.com/question/47817909/answer/107775045来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注 ...

  5. WPF 动态添加控件以及样式字典的引用(Style introduction)

    原文:WPF 动态添加控件以及样式字典的引用(Style introduction) 我们想要达到的结果是,绑定多个Checkbox然后我们还可以获取它是否被选中,其实很简单,我们只要找到那几个关键的 ...

  6. soui中,列表控件动态高度的使用注意

    1.listview的模板template中,需要增加defHeight属性,即默认高度,同时,不能出现itemHeight属性,否则动态高度会失效 2.数据适配器中,重写getViewDesired ...

  7. 字符串判断设置TextView高度

    问题:项目中需要根据字符串的长度判断Textview的高度   一.如果全是英文的也比较容易,根据长度判断从而设置mTextView的高度就好. double temp = str.length(); ...

  8. Easyui中使用jquery或js动态添加元素时出现的样式失效的解决方法

    Easyui中使用jquery或js动态添加元素时出现的样式失效的解决方法 2014-03-27 11:44:46|  分类: Easy UI|举报|字号 订阅     可以使用$.parser.pa ...

  9. jquery 动态添加下拉框 需要增加 煊染 selectmenu("refresh");

    若通过js动态选择下拉框的值必须刷新下拉框,例如:var selArray = $("select#sel");selArray[0].selectedIndex = 1;selA ...

  10. swift 版本 UItableViewCell的动态高度补足

    用swift的朋友们很多都是从ios8开发了, 其中针对table cell高度自动计算的 UITableViewAutomaticDimension 异常好用,但好像只对uilabel对象有效    ...

随机推荐

  1. 【go语言】2.1.1 变量,常量和数据类型

    Go 语言中,变量是存储数据的基本单位,常量则是固定不变的数据.每个变量和常量都有其对应的数据类型. 变量 在 Go 语言中,你可以使用 var 关键字来声明一个变量: var name string ...

  2. 如何在Avalonia11中设置自定义字体

    如何在Avalonia11中设置自定义字体 由于avalonia默认的中文字体显示的效果不太理想,我们需要下载一些自定义的字体,来优化UI的显示效果.avalonia的官方文档地址. 对我在项目中运用 ...

  3. Llama2 论文中译版——开放式基础和微调聊天模型

    Llama 2:开放式基础和微调聊天模型 写在前头 因为最近一直在使用 LLM 工具,所以在学习 Llama 2:开放式基础和微调聊天模型 这篇论文的期间,顺手将内容翻译了过来. 整片译文是由 Cha ...

  4. Yunfly 一款高效、性能优异的 node.js web 框架

    介绍 Yunfly 一款高性能 Node.js WEB 框架, 使用 Typescript 构建我们的应用. 使用 Koa2 做为 HTTP 底层框架, 使用 routing-controllers ...

  5. Proxmox VE软件防火墙的配置

    1 软件防火墙的基本概念 防火墙是计算机网络中用于保护网络安全的关键技术.防火墙可以是硬件设备部署在网络出口,也可以是软件部署在终端设备出口.本文主要介绍软件防火墙. 软件防火墙可以根据网络流量的方向 ...

  6. 原来ES7~12分别增加了这些属性呀

    ES6也称为ES2015,于2015年发布,此后每年都有新增一些属性,分别命名为ES7~12,发布的年份分别对应2016年到2021年 ES7 includes方法 数组中新增了includes方法, ...

  7. SimpleDateFormat 线程安全问题修复方案

    问题介绍 在日常的开发过程中,我们不可避免地会使用到 JDK8 之前的 Date 类,在格式化日期或解析日期时就需要用到 SimpleDateFormat 类,但由于该类并不是线程安全的,所以我们常发 ...

  8. 1.JDK的安装与卸载

    1.卸载: 卸载或更改程序,找到相应的JDK程序,删除 2.安装: 官网下载JDK程序:jdk-8u25-windows-i586.exe 双击安装程序,同意协议,更改安装路径:C:\jdk1.8.0 ...

  9. 解放生产力orm并发更新下应该这么处理求求你别再用UpdateById了

    解放生产力orm并发更新下应该这么处理求求你别再用UpdateById了 背景 很多时候为了方便我们都采用实体对象进行前后端的数据交互,然后为了便捷开发我们都会采用DTO对象进行转换为数据库对象,然后 ...

  10. 通过WinSW部署JAR包为windows服务

    通过WinSW部署JAR包为windows服务 背景 使用 Java 编写了一些有用的工具,因为不方便部署到服务器上,所以需要把 Java 生成的 jar 包在本地 Windows 上部署. 查阅了几 ...