You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CSS中实现卡片元素上的Hole Punch(打孔)效果?

实现Card上的CSS打孔(Hole Punch)效果

我想在CSS里实现打孔效果,类似裁剪但能穿透上层元素。当背景铺满整个视口时能伪造出这个效果,但背景放在卡片(card)元素上时,一直没找到可行方案。

期望实现的效果示例

html {
  height: 100%;
  --backround: linear-gradient(15deg, red, blue);
}

body {
  background-image: var(--backround);
  background-repeat: no-repeat;
  background-size: contain;
  background-attachment: fixed;
}

article {
  display: block;
  background-color: white;
  width: fit-content;
  height: 505px;
  margin: auto;
}

h1 {
  display: block;
  box-sizing: content-box;
  position: static;
  background: var(--backround) fixed;
  color: transparent;
  text-transform: capitalize;
  width: 100%;
  background-clip: text;
  font-weight: bolder;
}
<body>
  <main>
    <div class="card">
      <article>
        <h1>01AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
        <h1>02AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
        <h1>03AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
        <h1>04AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
        <h1>05AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
        <h1>06AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
        <h1>07AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
        <h1>08AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
        <h1>09AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
        <h1>10AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
        <h1>11AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
        <h1>12AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
      </article>
    </div>
  </main>
</body>

尝试后的问题效果

但在card上尝试时,只能得到如下效果,文本颜色和卡片背景明显错位,调整后错位更严重:

html {
  height: 100%;
  --backround: linear-gradient(15deg, red, blue);
}

.card {
  display: block;
  padding: 5em 10em;
  margin: 0 auto;
  width: fit-content;
  background-image: var(--backround);
}

article {
  display: block;
  background-color: white;
  width: fit-content;
  height: 505px;
  margin: auto;
}

h1 {
  display: block;
  box-sizing: content-box;
  position: static;
  background: var(--backround) fixed;
  color: transparent;
  background-clip: text;
  font-weight: bolder;
}
<main>
  <div class="card">
    <article>
      <h1>01AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
      <h1>02AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
      <h1>03AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
      <h1>04AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
      <h1>05AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
      <h1>06AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
      <h1>07AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
      <h1>08AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
      <h1>09AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
      <h1>10AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
      <h1>11AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
      <h1>12AAAAAAAAAAAAAAAAAAAAAAAAAA</h1>
    </article>
  </div>
</main>

问题在于文本的fixed背景基于视口缩放,而非card容器。


解决方案

核心思路是让文本的背景与card的背景使用相同的坐标系统,去掉fixed定位,通过调整background-position抵消容器的内边距偏移,实现背景对齐:

修改后的CSS代码

html {
  height: 100%;
  --backround: linear-gradient(15deg, red, blue);
}

.card {
  display: block;
  padding: 5em 10em;
  margin: 0 auto;
  width: fit-content;
  background-image: var(--backround);
  background-size: cover; /* 确保背景铺满card容器 */
}

article {
  display: block;
  background-color: white;
  width: fit-content;
  height: 505px;
  margin: auto;
}

h1 {
  display: block;
  box-sizing: content-box;
  background: var(--backround); /* 移除fixed,使用默认的scroll定位 */
  color: transparent;
  background-clip: text;
  font-weight: bolder;
  background-size: cover; /* 和card背景保持一致的尺寸 */
  /* 抵消card的padding偏移,让文本背景与card背景完全对齐 */
  background-position: -10em -5em;
}

关键说明

  1. 移除h1的background-attachment: fixed,让背景跟随容器滚动,而非绑定视口。
  2. 给.card和h1添加background-size: cover,保证渐变背景的尺寸一致。
  3. 通过background-position: -10em -5em抵消.card的padding:5em 10em,让文本的渐变背景与card的渐变背景位置完全重合,实现“穿透”白色article的打孔效果。

如果后续调整card的padding值,只需要同步修改h1的background-position数值即可(水平偏移为负的左右padding,垂直偏移为负的上下padding)。


内容的提问来源于stack exchange,提问作者tbeest

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 15:48:16