稀土掘金技术社区

老板让背景位置智能展示:字多居中,字少右下

点击关注公众号,“技术干货” 及时达!

背景

昨天开发,老本提了一个有趣(zhi zhang)的需求,希望一个背景图能「根据标题内容的高度,智能调整展示位置」:

Image

「当标题内容较少时」,背景图要「靠右居中」展示,并根据区域上下裁剪,「从中间部分开始显示」:

Image
Image
Image

「当标题内容较多时」,背景图要「靠右底部对齐」展示:

Image

标题内容继续增大,图片的位置尺寸不变,固定在右下角。

Image

简单来说,就是内容小于图片高度时,用于从图片中心开始展示,上下截断。

简单理解就是:「内容少,图居中裁;内容多,图靠下贴边。」

老板说这个要下午给客户演示用,我上个厕所,回来你发我。

我内心一万个泥马奔腾而过,老板觉得这是很简单的一句代码的事儿啊!

「看来,只能借助 AI 的力量了!」

❝

本文使用 Trae 编译器完成示例

Image
❞

基础回顾

由于图片作为内容展示区(div 元素)的一个背景图,那它的位置一定是通过background的相关属性控制的。

先通过 Tare 回顾下:

Image
属性
作用
常用值示例
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 吧:

Image「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+

关注更多AI编程资讯请去AI Coding专区:https://juejin.cn/aicoding

图片
点击"阅读原文"了解详情~