Skip to content
Go back

css`transition-behavior:allow-discrete`

transition-behavior: allow-discrete 是 CSS 的一个新属性值,用于控制离散属性(discrete properties)的过渡行为。它让原本不支持过渡的离散属性能够有平滑的动画效果。

Table of contents

Open Table of contents

什么是离散属性?

离散属性是指值变化时没有中间状态的属性,例如:

/* 显示/隐藏 - 只有两个状态 */
display: none → display: block

/* 布尔属性 - 只有 true/false */
content-visibility: hidden → content-visibility: visible

/* 整数值 - 跳变而非连续变化 */
z-index: 1 → z-index: 100

/* 枚举值 - 从一个选项跳到另一个 */
color: red → color: blue

传统问题

传统上,这些属性变化时是瞬间切换的:

.element {
  display: none;
  opacity: 0;
  transition: opacity 0.5s;
}

.element.show {
  display: block; /* 瞬间显示,没有过渡 */
  opacity: 1; /* 有过渡效果 */
}

allow-discrete 的作用

基础用法

.element {
  /* 允许离散属性参与过渡 */
  transition-behavior: allow-discrete;
  /* 或指定特定属性 */
  transition:
    opacity 0.5s,
    display 0.5s allow-discrete;
}

.element.hidden {
  display: none;
  opacity: 0;
}

.element.visible {
  display: block;
  opacity: 1;
}

具体应用示例

1. 显示/隐藏过渡

<div class="card">可平滑显示/隐藏的卡片</div>
<button onclick="toggleCard()">切换</button>

<style>
  .card {
    display: none;
    opacity: 0;

    /* 关键:允许 display 参与过渡 */
    transition:
      opacity 0.5s,
      display 0.5s allow-discrete;

    /* 更简洁的写法 */
    transition: all 0.5s;
    transition-behavior: allow-discrete;
  }

  .card.show {
    display: block;
    opacity: 1;
  }
</style>

<script>
  function toggleCard() {
    document.querySelector(".card").classList.toggle("show");
  }
</script>

2. 配合 CSS 新特性:@starting-style

allow-discrete 通常与 @starting-style 规则配合使用,定义元素首次出现时的起始样式:

.dialog {
  opacity: 0;
  display: none;
  transform: scale(0.8);

  transition:
    opacity 0.3s,
    transform 0.3s,
    overlay 0.3s allow-discrete,
    display 0.3s allow-discrete;

  /* 使用 top-layer API 的对话框 */
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

/* 定义动画起始状态 */
@starting-style {
  .dialog {
    opacity: 0;
    transform: scale(0.8) translate(-50%, -50%);
  }
}

.dialog.open {
  display: block;
  opacity: 1;
  transform: scale(1) translate(-50%, -50%);
}

3. 配合 content-visibility

.collapsible-section {
  content-visibility: hidden;
  height: 0;
  overflow: hidden;

  transition:
    height 0.3s,
    content-visibility 0.3s allow-discrete;
}

.collapsible-section.expanded {
  content-visibility: visible;
  height: 200px;
}

4. 配合 overlay 属性(弹层控制)

.dialog {
  /* 使用新的 overlay 属性 */
  overlay: none;

  transition:
    opacity 0.3s,
    overlay 0.3s allow-discrete,
    display 0.3s allow-discrete;
}

.dialog.open {
  overlay: auto; /* 进入顶层 */
  opacity: 1;
}

支持的离散属性

目前支持的主要离散属性包括:

属性描述典型用途
display显示/隐藏模态框、下拉菜单
content-visibility内容可见性虚拟列表、懒加载
overlay顶层控制对话框、弹出层
position定位类型fixed 定位切换
float浮动布局变化
z-index层叠顺序层叠上下文切换

回退方案

.element {
  /* 现代浏览器 */
  transition:
    opacity 0.3s,
    display 0.3s allow-discrete;

  /* 传统写法作为回退 */
  animation: fadeIn 0.3s;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* 或者使用 JS 补间动画 */

最佳实践

1. 渐进增强

.menu {
  display: none;
  opacity: 0;

  /* 现代浏览器:完整过渡 */
  transition:
    opacity 0.3s,
    display 0.3s allow-discrete,
    overlay 0.3s allow-discrete;

  /* 传统浏览器:至少有不透明度过渡 */
  @supports not (transition-behavior: allow-discrete) {
    transition: opacity 0.3s;
  }
}

2. 性能考虑

/* 良好:只动画必要的属性 */
.menu {
  transition:
    opacity 0.3s,
    display 0.3s allow-discrete;
}

/* 避免:动画所有属性 */
.menu {
  transition: all 0.3s;
  transition-behavior: allow-discrete; /* 可能影响性能 */
}

3. 组合使用

.modal {
  /* 1. 隐藏元素 */
  display: none;

  /* 2. 定义过渡 */
  transition:
    opacity 0.4s ease-out,
    transform 0.4s ease-out,
    display 0.4s allow-discrete,
    overlay 0.4s allow-discrete;

  /* 3. 定义起始样式 */
  @starting-style {
    .modal {
      opacity: 0;
      transform: translateY(-20px);
    }
  }
}

.modal.open {
  display: block;
  opacity: 1;
  transform: translateY(0);
}

与 JavaScript 配合

// 动态添加 allow-discrete
element.style.transition = `
  opacity 0.3s,
  display 0.3s allow-discrete
`;

// 显示元素
element.style.display = "block";
element.style.opacity = "1";

// 或者使用 class
element.classList.add("show");

总结

transition-behavior: allow-discrete 的主要价值:

  1. 解决传统难题:让 display: none/block 等属性可以平滑过渡
  2. 提升用户体验:消除视觉上的”跳变”,让界面更自然
  3. 简化代码:不再需要复杂的 JavaScript 动画补丁
  4. 配合新标准:与 @starting-styleoverlay 等新特性完美配合

虽然目前浏览器支持还在推进中,但这代表了 CSS 动画能力的重大进步,未来会成为构建平滑 UI 过渡的重要工具。


Share this post on:

Previous Post
overscroll-behavior-x
Next Post
js String.raw