CSS 用户界面 10

106 阅读11分钟

梳理一下 CSS 中与用户界面 (User Interface - UI) 外观和交互直接相关的属性及其属性值。这个范畴比较广,主要包括影响元素交互反馈、外观控制、表单元素样式、滚动行为等方面的属性。

(注意:不包括基础的布局、颜色、背景、字体、文本属性,假设那些已单独了解。这里侧重于更偏向 UI 交互和特定控件样式的属性。)

  1. cursor

    • 作用: 设置鼠标指针悬停在元素上时显示的光标样式

    • 值:

      • 通用: auto (浏览器默认), default (平台默认箭头), none (无光标)。
      • 链接/状态: context-menu, help, pointer (手形,常用), progress (忙碌,程序后台运行), wait (忙碌,程序正忙)。
      • 选择: cell, crosshair, text, vertical-text。
      • 拖放: alias, copy, move, no-drop, not-allowed, grab, grabbing。
      • 调整大小: all-scroll, col-resize, row-resize, n-resize, e-resize, s-resize, w-resize, ne-resize, nw-resize, se-resize, sw-resize, ew-resize, ns-resize, nesw-resize, nwse-resize。
      • 缩放: zoom-in, zoom-out。
      • url() [ ]?, auto | : 使用自定义图片作为光标,可以指定热点 (x, y 坐标) 和后备关键字。
    • 示例: cursor: pointer;, cursor: not-allowed;, cursor: url(mycursor.png) 8 8, auto;

  2. outline (简写属性)

    • 作用: 在元素周围绘制一条轮廓线,通常用于指示键盘焦点状态。它不占据空间,不会影响布局(与 border 不同)。
    • 值: 组合 outline-width, outline-style, outline-color 的值。
    • 示例: outline: 2px solid blue;, outline: none; (常用于移除默认焦点轮廓,但需提供替代方案保证可访问性)
  3. outline-width

    • 作用: 设置轮廓线的宽度。
    • 值: (关键字 thin, medium, thick) 或 (如 2px)。
    • 示例: outline-width: medium;
  4. outline-style

    • 作用: 设置轮廓线的样式。
    • 值: auto (浏览器定义), none, dotted, dashed, solid, double, groove, ridge, inset, outset。
    • 示例: outline-style: dotted;
  5. outline-color

    • 作用: 设置轮廓线的颜色。
    • 值: , invert (执行颜色反转,很少用且支持不佳)。
    • 示例: outline-color: invert;, outline-color: #ff0000;
  6. outline-offset

    • 作用: 设置轮廓线与其元素边框之间的间距。可以是负值,使轮廓线绘制在元素内部。
    • 值: (如 3px, -2px)。
    • 示例: outline: 2px solid blue; outline-offset: 3px;
  7. resize

    • 作用: 控制用户是否可以以及如何调整元素的尺寸。通常应用于 textarea 或设置了 overflow (非 visible) 的元素。

    • 值:

      • none: (默认) 不允许用户调整大小。
      • both: 允许用户在水平和垂直方向调整大小。
      • horizontal: 只允许用户在水平方向调整大小。
      • vertical: 只允许用户在垂直方向调整大小。
      • block, inline: (实验性) 基于块轴或内联轴调整。
    • 示例: textarea { resize: vertical; }

  8. appearance (或带前缀 -webkit-appearance, -moz-appearance)

    • 作用: 允许改变元素基于操作系统主题的平台原生外观。最常见的用途是移除表单元素(如按钮、输入框、下拉列表)的默认样式,以便完全自定义它们。

    • 值:

      • none: 移除平台原生外观。 (最常用)
      • auto: (默认) 元素按其类型正常渲染。
      • 其他特定关键字(支持性不一,且正被标准化或废弃):button, textfield, searchfield, textarea, checkbox, radio, menulist, listbox, meter, progress-bar 等。
    • 示例: input[type="text"], select, button { appearance: none; -webkit-appearance: none; -moz-appearance: none; }

  9. accent-color

    • 作用: 为某些 UI 控件(如复选框 , 单选按钮 , 范围滑块 , 进度条 )设置强调色(或称主题色) ,影响选中状态、滑块轨迹等的颜色,而无需完全重置控件外观。
    • 值: auto (默认,浏览器/系统默认色), 。
    • 示例: input[type="checkbox"], input[type="radio"] { accent-color: deeppink; }
  10. caret-color

    • 作用: 设置可编辑元素(如 , , [contenteditable="true"] 元素)中文本插入光标(插入符)的颜色。
    • 值: auto (默认,浏览器通常使用 color 属性值), 。
    • 示例: input:focus { caret-color: red; }
  11. user-select (或带前缀)

    • 作用: 控制用户是否能够以及如何选择元素内的文本

    • 值:

      • auto: (默认) 浏览器决定,通常可选择。对于可编辑内容,总是 text。
      • none: 用户完全无法选择文本。
      • text: 用户可以选择文本。
      • all: 只需单击一次即可选择该元素的所有内容。
      • contain: (实验性) 允许选择从该元素开始,但选择范围限制在该元素内。
    • 示例: button { user-select: none; } (防止用户意外选择按钮文字)

  12. pointer-events

    • 作用: 定义元素在什么情况下可以成为鼠标/触摸事件的目标。可以用来“穿透”某个元素点击它下面的内容。

    • 值:

      • auto: (默认) 元素按预期响应指针事件(取决于 visibility 等)。
      • none: 元素永远不会成为指针事件的目标。事件会“穿透”该元素,作用于其下方的元素。
      • 其他 SVG 特定值: visiblePainted, visibleFill, visibleStroke, visible, painted, fill, stroke, all。
    • 示例: .overlay { pointer-events: none; } (让覆盖层不阻挡下方元素的点击)

  13. scroll-behavior

    • 作用: 指定当滚动操作是由导航或 CSSOM scrolling API 触发时(例如,点击锚链接 #top,或使用 element.scrollTo()),滚动是平滑的还是瞬时的。

    • 值:

      • auto: (默认) 瞬时滚动。
      • smooth: 平滑滚动。
    • 示例: html { scroll-behavior: smooth; } (全局启用平滑滚动)

  14. scrollbar-width (较新,部分浏览器支持)

    • 作用: 设置滚动条的宽度(厚度)。

    • 值:

      • auto: (默认) 平台默认滚动条宽度。
      • thin: 平台提供的更细的滚动条(如果没有则同 auto)。
      • none: 完全隐藏滚动条,但元素仍然可以滚动。
    • 示例: body { scrollbar-width: thin; }

  15. scrollbar-color (较新,部分浏览器支持)

    • 作用: 设置滚动条轨道和滑块的颜色。
    • 值: auto (默认) 或 (第一个颜色是滑块颜色,第二个是轨道颜色)。
    • 示例: body { scrollbar-color: darkgray lightgray; }
  16. overscroll-behavior (简写属性)

    • 作用: 控制当滚动到滚动区域的边界时,浏览器的行为(例如,是否触发父级滚动或页面刷新/导航)。

    • 值: [ overscroll-behavior-x | overscroll-behavior-y ] 或单个值用于双轴。

      • auto: (默认) 默认滚动链行为(子元素滚动到头会带动父元素滚动)。
      • contain: 阻止滚动链。当前元素的滚动不会传递给父元素。
      • none: 既阻止滚动链,也阻止默认的导航行为(如下拉刷新、左右滑动导航)。
    • 示例: .modal { overscroll-behavior: contain; } (防止模态框内部滚动时带动页面滚动)

  17. overscroll-behavior-x, overscroll-behavior-y

    • 作用: 分别控制水平和垂直方向的过滚动行为。
    • 值: auto, contain, none。
  18. touch-action

    • 作用: 控制触摸屏用户如何操作元素区域(例如,是否允许平移、缩放)。用于优化触摸交互,防止浏览器默认手势(如滚动、缩放)与自定义交互冲突。

    • 值:

      • auto: (默认) 浏览器处理所有平移和缩放手势。
      • none: 禁用所有浏览器默认的平移和缩放手势。
      • pan-x, pan-left, pan-right: 只允许水平平移。
      • pan-y, pan-up, pan-down: 只允许垂直平移。
      • pinch-zoom: 只允许缩放。
      • manipulation: 允许平移和缩放 (pan-x pan-y pinch-zoom),但不允许双击缩放等其他可能干扰自定义手势的行为。常用。
    • 示例: canvas { touch-action: none; } (在画布上禁用所有默认触摸手势,以便自定义绘制)

  19. object-fit (应用于替换元素,如 , )

    • 作用: 指定替换元素的内容(如图片或视频)应该如何适应到其容器的尺寸。

    • 值:

      • fill: (默认) 拉伸内容以填充容器,不保持宽高比。
      • contain: 保持宽高比,缩放内容以完整适应容器,可能有空白。
      • cover: 保持宽高比,缩放内容以完全覆盖容器,可能裁剪内容。
      • none: 内容保持原始尺寸,不缩放。
      • scale-down: 类似 none 或 contain 中尺寸较小的那个。
    • 示例: img.avatar { object-fit: cover; width: 100px; height: 100px; }

  20. object-position (应用于替换元素)

    • 作用: 指定替换元素的内容在其容器内的对齐方式(当 object-fit 不是 fill 时)。语法类似 background-position。
    • 值: (关键字、长度、百分比组合)。
    • 示例: img.banner { object-fit: cover; object-position: center bottom; } (让图片底部居中显示)

相关概念(非属性,但与 UI 密切相关):

  • 伪类 (Pseudo-classes): 如 :hover, :focus, :active, :disabled, :checked, :focus-visible 等,用于根据元素的状态应用样式,是实现交互反馈的关键。
  • 伪元素 (Pseudo-elements): 如 ::before, ::after 可用于添加装饰性 UI 元素; ::placeholder 用于样式化输入框占位符; ::-webkit-scrollbar 系列 (非标准但常用) 用于自定义 Webkit 浏览器滚动条外观。

案例

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS 用户界面属性示例</title>
    <link rel="stylesheet" href="111.css">
    <style>
        /* 仅用于平滑滚动示例 */
        html {
            scroll-behavior: smooth; /* 全局启用平滑滚动 */
        }
    </style>
</head>
<body>

    <nav class="top-nav">
        <a href="#section1">区域 1</a> |
        <a href="#section2">区域 2</a> |
        <a href="#section3">区域 3 (锚点)</a>
    </nav>

    <h1>CSS 用户界面 (UI) 属性演示</h1>

    <section id="section1">
        <h2>交互指针 (<code>cursor</code>) 与 轮廓 (<code>outline</code>)</h2>

        <button class="cursor-pointer">指针 (pointer)</button>
        <button class="cursor-help">帮助 (help)</button>
        <button class="cursor-wait">等待 (wait)</button>
        <button class="cursor-not-allowed" disabled>禁止 (not-allowed)</button>
        <span class="cursor-text" style="border: 1px solid #ccc; padding: 5px;">文本选择 (text)</span>

        <br><br>

        <input type="text" class="focus-outline" placeholder="聚焦时看蓝色轮廓">
        <button class="focus-outline-offset">轮廓带偏移</button>
        <button class="no-outline">移除默认轮廓 (不推荐)</button>
    </section>

    <section id="section2">
        <h2>元素调整与外观 (<code>resize</code>, <code>appearance</code>, <code>accent-color</code>)</h2>

        <textarea class="resizable-box" placeholder="我可以垂直调整大小"></textarea>
        <div class="resizable-div">这个 div 可以双向调整大小</div>

        <div class="form-elements">
            <p>移除默认外观的表单元素:</p>
            <select class="appearance-none">
                <option>选项 1</option>
                <option>选项 2</option>
            </select>
            <input type="text" class="appearance-none text-input" placeholder="无原生外观输入框">
            <button class="appearance-none custom-button">自定义按钮</button>

            <p style="margin-top: 20px;">使用 <code>accent-color</code> 美化的控件:</p>
            <label><input type="checkbox" class="accented" checked> 复选框</label>
            <label><input type="radio" name="radio-group" class="accented" checked> 单选按钮 1</label>
            <label><input type="radio" name="radio-group" class="accented"> 单选按钮 2</label>
            <input type="range" class="accented" min="0" max="100" value="50">
        </div>
    </section>

    <section id="section3">
        <h2>文本交互与滚动 (<code>caret-color</code>, <code>user-select</code>, <code>pointer-events</code>, <code>scroll-behavior</code>)</h2>

        <input type="text" class="custom-caret" placeholder="聚焦时光标是红色的">

        <p class="no-select">这段文字无法被选中 (user-select: none)。</p>
        <button class="no-select-button">按钮文字也无法选中</button>

        <div class="pointer-events-container">
            <div class="overlay-div">这个覆盖层设置了 pointer-events: none,你可以点击它下面的按钮。</div>
            <button class="underneath-button" onclick="alert('按钮被点击了!')">点击我</button>
        </div>

        <p>点击导航栏的 "区域 3 (锚点)" 会平滑滚动到这里 (因为 html 设置了 <code>scroll-behavior: smooth;</code>)。</p>
        <div style="height: 80vh;"></div> <!-- 增加一些高度方便滚动 -->
        <a href="#" class="back-to-top">回到顶部</a>

    </section>

</body>
</html>
    body {
    font-family: "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
    line-height: 1.6;
    margin: 0; /* 确保平滑滚动能到顶部 */
    padding: 20px;
    padding-top: 60px; /* 为固定导航留出空间 */
}

h1, h2 {
    color: #333;
    margin-bottom: 1em;
}
h1 { text-align: center; }
h2 { border-bottom: 1px solid #eee; padding-bottom: 0.3em; margin-top: 1.5em;}

section {
    background-color: #fff;
    padding: 20px;
    margin-bottom: 30px;
    border-radius: 5px;
    box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}

/* --- 导航栏,演示平滑滚动 --- */
.top-nav {
    position: fixed; /* 固定导航 */
    top: 0;
    left: 0;
    width: 100%;
    background-color: #333;
    padding: 10px 20px;
    box-shadow: 0 2px 5px rgba(0,0,0,0.2);
    z-index: 100;
}
.top-nav a {
    color: white;
    text-decoration: none;
    margin: 0 10px;
}
.top-nav a:hover {
    text-decoration: underline;
}

/* --- 示例 1: cursor & outline --- */
.cursor-pointer { cursor: pointer; }
.cursor-help { cursor: help; }
.cursor-wait { cursor: wait; }
.cursor-not-allowed { cursor: not-allowed; }
.cursor-text { cursor: text; }

.focus-outline:focus {
    outline: 3px solid dodgerblue; /* 聚焦时显示蓝色实线轮廓 */
    outline-offset: 2px; /* 轮廓稍微离开边框 */
}
.focus-outline-offset:focus {
    outline: 2px dashed orange;
    outline-offset: -4px; /* 轮廓向内偏移 */
}
.no-outline:focus {
    outline: none; /* 移除默认轮廓,需要提供其他视觉反馈,如背景色变化 */
    background-color: #eee; /* 提供替代的焦点指示 */
}
button { /* 默认按钮样式 */
    padding: 8px 15px;
    margin: 5px;
    border: 1px solid #ccc;
    border-radius: 4px;
    background-color: #f0f0f0;
    cursor: pointer; /* 默认给按钮加手形指针 */
}
button:disabled { /* 禁用按钮样式 */
    background-color: #ddd;
    color: #888;
}

/* --- 示例 2: resize, appearance, accent-color --- */
.resizable-box {
    display: block; /* textarea 默认是 inline-block */
    width: 300px;
    height: 80px;
    border: 1px solid #ccc;
    padding: 5px;
    resize: vertical; /* 只允许垂直调整 */
    overflow: auto; /* 调整大小需要 overflow 不是 visible */
}
.resizable-div {
    width: 200px;
    height: 100px;
    border: 1px solid steelblue;
    padding: 10px;
    resize: both; /* 允许双向调整 */
    overflow: auto;
    margin-top: 10px;
}

.form-elements { margin-top: 20px; }
.appearance-none {
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    /* 移除默认外观后,需要自己添加样式 */
    padding: 8px 10px;
    border: 1px solid #aaa;
    border-radius: 4px;
    background-color: white;
    margin: 5px;
}
.text-input { width: 200px; }
.custom-button {
    background-color: mediumseagreen;
    color: white;
    font-weight: bold;
}
.custom-button:hover { background-color: darkseagreen; }

.accented {
    accent-color: crimson; /* 设置强调色 */
    margin-right: 5px;
    vertical-align: middle; /* 对齐 */
}
input[type="range"].accented {
    width: 200px; /* 给滑块一个宽度 */
}

/* --- 示例 3: caret-color, user-select, pointer-events --- */
.custom-caret:focus {
    caret-color: red; /* 聚焦时光标变红 */
    border-color: red; /* 同时改变边框颜色 */
}

.no-select {
    user-select: none; /* 禁止选择文本 */
    -webkit-user-select: none; /* 兼容旧版 Webkit */
    -moz-user-select: none; /* 兼容旧版 Firefox */
    background-color: lightyellow;
    padding: 10px;
}
.no-select-button {
    user-select: none;
    -webkit-user-select: none;
    -moz-user-select: none;
}

.pointer-events-container {
    position: relative; /* 为绝对定位的覆盖层提供容器 */
    margin-top: 20px;
    border: 1px dashed grey;
    padding: 20px;
    height: 100px; /* 给容器一些高度 */
}
.overlay-div {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 128, 0, 0.3); /* 半透明绿色覆盖层 */
    display: flex;
    justify-content: center;
    align-items: center;
    color: white;
    font-weight: bold;
    pointer-events: none; /* 关键:让鼠标事件穿透这个层 */
}
.underneath-button {
    position: absolute; /* 按钮也定位,确保在覆盖层下方 */
    top: 30px;
    left: 50%;
    transform: translateX(-50%);
}

.back-to-top {
    display: block; /* 让链接独占一行 */
    text-align: center;
    margin-top: 20px;
    color: steelblue;
    text-decoration: none;
}
.back-to-top:hover { text-decoration: underline; }