背景
昨天开发,老本提了一个有趣(zhi zhang)的需求,希望一个背景图能根据标题内容的高度,智能调整展示位置:
当标题内容较少时,背景图要靠右居中展示,并根据区域上下裁剪,从中间部分开始显示:
当标题内容较多时,背景图要靠右底部对齐展示:
标题内容继续增大,图片的位置尺寸不变,固定在右下角。
简单来说,就是内容小于图片高度时,用于从图片中心开始展示,上下截断。
简单理解就是:内容少,图居中裁;内容多,图靠下贴边。
老板说这个要下午给客户演示用,我上个厕所,回来你发我。
我内心一万个泥马奔腾而过,老板觉得这是很简单的一句代码的事儿啊!
看来,只能借助AI的力量了!
本文使用Trae编译器完成示例
基础回顾
由于图片作为内容展示区(div元素)的一个背景图,那它的位置一定是通过background
的相关属性控制的。
先通过Tare回顾下:
属性 | 作用 | 常用值示例 |
---|---|---|
background-image |
设置背景图 | url('xxx.jpg') |
background-size |
控制图像缩放方式 |
cover , contain , 100px 80px
|
background-repeat |
是否平铺 |
no-repeat , repeat
|
background-position |
控制图像显示位置 |
right bottom , 50% 100%
|
我还是更喜欢简写的方式,让Trae在帮我回忆一下
你可以将以上多个属性整合为一行 background
简写:
background: #fff url('your-image.jpg') right center / cover no-repeat;
语法结构是:
background: [背景颜色] [背景图] [背景图位置] / [背景图大小] [是否平铺];
实现方式
css+js
其实上述的效果无非就是通过两个类名控制,内容高度低于图片时,用一个类名控制图片样式;内容高度高于图片时,用另一个类名控制图片样式。
直接提问Trae来生成最简单的html吧:
<div class="card auto-align">
<h2>标题内容,根据长度不同会影响容器高度</h2>
</div>
CSS 样式实现
.card {
width: 100%;
min-height: 200px;
padding: 16px;
background:#fff url("@/assets/svg/bg.svg") no-repeat center right/446px 326px;
transition: background-position 0.3s ease;
}
/* 用 content 高度多的时候切换 class */
.card.bottom-align {
background-position: bottom right; /* 高内容时靠底 */
}
搭配 JS 动态判断
const card = document.querySelector('.card');
const contentHeight = card.scrollHeight;
const threshold = 326; // 326是图片高度
if (contentHeight > threshold) {
card.classList.add('bottom-align');
} else {
card.classList.remove('bottom-align');
}
容器查询
css+js的方式虽然能实现上述效果,但是比较麻烦,我在思考能否用类似媒体查询的方式实现这个效果。通过AI提问,发现了一个好用的CSS属性:容器查询
Container Query(容器查询) 是 CSS 中的一项现代特性,它允许根据“父容器的尺寸”而不是“视口尺寸”来响应式地改变样式。这与传统的媒体查询(Media Query)相比,粒度更细、组件更独立,非常适合组件化开发。
它的用法也比较简单:
步骤 1:给容器启用查询能力
.container {
container-type: inline-size;
container-name: card-container;
}
container-type
是必须的属性,表示该容器可以被查询。常用值:
-
inline-size
:仅根据宽度查询 -
size
:根据宽度和高度都可查询
步骤 2:使用 @container
编写容器查询规则
@container (min-width: 400px) {
.card {
font-size: 18px;
}
}
@container (min-width: 600px) {
.card {
font-size: 24px;
}
}
如果你设置了容器名称(container-name
),可以写成:
@container card-container (min-width: 600px) { ... }
现在,让Trae帮我用容器查询实现效果吧
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8" />
<title>智能背景定位</title>
<style>
.card {
container-type: size;
background: url('https://picsum.photos/id/1015/800/400') right center / cover no-repeat;
padding: 20px;
border-radius: 8px;
color: #fff;
font-family: sans-serif;
margin-bottom: 40px;
}
@container (min-height: 300px) {
.card {
background: url('https://picsum.photos/id/1015/800/400') right bottom / cover no-repeat;
}
}
</style>
</head>
<body>
<div class="card">
<h2>
这是一个非常非常长的标题,可能会有多行文字,用于测试内容过多时背景图自动靠右下展示的效果。
这一段话模拟实际中可能会出现的文案,比如产品详情、新闻摘要或者营销标题等场景。
</h2>
</div>
</body>
</html>
容器查询虽然好用,但也要注意兼容性
浏览器 | 支持情况 | 支持版本 |
---|---|---|
Chrome | ✅ 支持 | 105+(2022) |
Edge | ✅ 支持 | 105+(Chromium) |
Safari | ✅ 支持 | 16+(2022) |
Firefox | ✅ 支持 | 110+(2023) |
Opera | ✅ 支持 | 91+ |
IE 11 | ❌ 不支持 | 永不支持 |
Android 浏览器 | ✅ 支持 | 基于 Chrome |
iOS Safari | ✅ 支持 | 16+ |