CSS 提供了丰富的属性来控制用户与页面的交互方式。从鼠标光标到文本选择,从触摸行为到滚动控制,这些属性直接影响用户体验。
cursor 鼠标光标#
常用光标类型#
.default { cursor: default;} /* 默认箭头 */.pointer { cursor: pointer;} /* 手型,表示可点击 */.text { cursor: text;} /* 文本输入 */.move { cursor: move;} /* 移动 */.not-allowed { cursor: not-allowed;} /* 禁止 */.wait { cursor: wait;} /* 等待/加载 */.progress { cursor: progress;} /* 后台处理中 */.help { cursor: help;} /* 帮助 */.crosshair { cursor: crosshair;} /* 十字准心 */.grab { cursor: grab;} /* 抓取 */.grabbing { cursor: grabbing;} /* 抓取中 */调整大小光标#
.resize-ew { cursor: ew-resize;} /* 左右 */.resize-ns { cursor: ns-resize;} /* 上下 */.resize-nwse { cursor: nwse-resize;} /* 左上-右下 */.resize-nesw { cursor: nesw-resize;} /* 右上-左下 */.col-resize { cursor: col-resize;} /* 列调整 */.row-resize { cursor: row-resize;} /* 行调整 */缩放光标#
.zoom-in { cursor: zoom-in;}.zoom-out { cursor: zoom-out;}自定义光标#
.custom { cursor: url('/cursors/custom.png'), auto;}
/* 带热点位置 */.custom-hotspot { cursor: url('/cursors/crosshair.png') 16 16, crosshair;}
/* 多个回退 */.with-fallback { cursor: url('/cursors/fancy.cur'), url('/cursors/fancy.png'), pointer;}实用示例#
/* 可点击元素 */button,a,[role='button'] { cursor: pointer;}
/* 禁用状态 */button:disabled,.disabled { cursor: not-allowed; opacity: 0.5;}
/* 拖拽元素 */.draggable { cursor: grab;}
.draggable:active { cursor: grabbing;}
/* 可调整大小 */.resizable { cursor: nwse-resize;}pointer-events 指针事件#
控制元素是否响应鼠标/触摸事件:
.clickable { pointer-events: auto;} /* 默认:响应事件 */
.non-clickable { pointer-events: none;} /* 不响应事件,事件穿透 */实用场景#
/* 禁用按钮但保持样式 */.button-disabled { pointer-events: none; opacity: 0.5;}
/* 遮罩层允许点击穿透 */.overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.5); pointer-events: none; /* 遮罩不阻挡点击 */}
.overlay .modal { pointer-events: auto; /* 弹窗可点击 */}
/* 装饰元素不阻挡交互 */.decoration { position: absolute; pointer-events: none;}
/* 加载中禁止交互 */.loading { pointer-events: none; opacity: 0.7;}SVG 专用值#
.svg-element { pointer-events: fill; /* 只响应填充区域 */ pointer-events: stroke; /* 只响应描边 */ pointer-events: visible; /* 可见部分响应 */ pointer-events: painted; /* 填充和描边响应 */}user-select 文本选择#
控制用户是否可以选择文本:
.selectable { user-select: auto;} /* 默认 */
.select-all { user-select: all;} /* 点击全选 */
.select-text { user-select: text;} /* 可选文本 */
.no-select { user-select: none;} /* 禁止选择 */
.select-contain { user-select: contain;} /* 选择限制在元素内 */实用场景#
/* 按钮文字不可选 */button { user-select: none;}
/* 代码块点击全选 */.code-block { user-select: all;}
/* 图标不可选 */.icon { user-select: none;}
/* 可复制的重要信息 */.copyable { user-select: all; background: #f3f4f6; padding: 8px 12px; border-radius: 4px; cursor: pointer;}
/* 防止拖拽时选中文字 */.draggable-area { user-select: none;}resize 可调整大小#
允许用户调整元素大小:
.resize-both { resize: both; overflow: auto; /* 必须 */}
.resize-horizontal { resize: horizontal; overflow: auto;}
.resize-vertical { resize: vertical; overflow: auto;}
.no-resize { resize: none;}文本框调整#
/* 只允许垂直调整 */textarea { resize: vertical; min-height: 100px; max-height: 500px;}
/* 禁止调整 */textarea.fixed { resize: none;}
/* 自由调整 */.resizable-box { resize: both; overflow: auto; min-width: 200px; min-height: 100px; max-width: 100%; border: 1px solid #d1d5db; padding: 16px;}touch-action 触摸操作#
控制元素的触摸行为:
.touch-auto { touch-action: auto;} /* 默认:允许所有 */
.touch-none { touch-action: none;} /* 禁止所有触摸操作 */
.pan-x { touch-action: pan-x;} /* 只允许水平平移 */
.pan-y { touch-action: pan-y;} /* 只允许垂直平移 */
.pinch-zoom { touch-action: pinch-zoom;} /* 只允许缩放 */
.manipulation { touch-action: manipulation;} /* 平移和缩放,禁止双击缩放 */实用场景#
/* 轮播/滑块 - 只允许水平滑动 */.carousel { touch-action: pan-x; overflow-x: auto;}
/* 垂直滚动列表 - 只允许垂直 */.vertical-list { touch-action: pan-y;}
/* 画布/地图 - 自定义手势处理 */.canvas { touch-action: none;}
/* 按钮 - 避免双击缩放延迟 */button { touch-action: manipulation;}
/* 图片画廊 - 允许缩放和平移 */.gallery-view { touch-action: pan-x pan-y pinch-zoom;}caret-color 光标颜色#
设置文本输入光标的颜色:
input { caret-color: #3b82f6;}
/* 透明光标(隐藏) */.hidden-caret { caret-color: transparent;}
/* 继承文字颜色 */.inherit-caret { caret-color: auto;}accent-color 强调色#
设置表单控件的主题色:
:root { accent-color: #3b82f6;}
/* 单独设置 */input[type='checkbox'] { accent-color: #10b981;}
input[type='radio'] { accent-color: #8b5cf6;}
input[type='range'] { accent-color: #f59e0b;}
progress { accent-color: #ef4444;}appearance 外观#
控制元素的原生外观:
/* 移除默认样式 */.custom-input { appearance: none; -webkit-appearance: none;}
/* 常见用法 */input[type='number'] { appearance: textfield; /* 移除箭头 */}
select.custom { appearance: none; background: url('arrow.svg') right center no-repeat;}自定义表单控件#
/* 自定义复选框 */input[type='checkbox'].custom { appearance: none; width: 20px; height: 20px; border: 2px solid #d1d5db; border-radius: 4px; cursor: pointer;}
input[type='checkbox'].custom:checked { background: #3b82f6; border-color: #3b82f6;}
input[type='checkbox'].custom:checked::after { content: '✓'; color: white; display: flex; justify-content: center; align-items: center;}
/* 自定义单选框 */input[type='radio'].custom { appearance: none; width: 20px; height: 20px; border: 2px solid #d1d5db; border-radius: 50%; cursor: pointer;}
input[type='radio'].custom:checked { border-color: #3b82f6; background: radial-gradient(#3b82f6 50%, transparent 50%);}可访问性媒体查询#
prefers-reduced-motion#
尊重用户的动画偏好:
/* 默认有动画 */.animated { transition: transform 0.3s ease;}
.animated:hover { transform: scale(1.05);}
/* 用户偏好减少动画 */@media (prefers-reduced-motion: reduce) { .animated { transition: none; }
.animated:hover { transform: none; }
/* 全局禁用动画 */ *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }}prefers-color-scheme#
响应系统主题:
:root { --bg: white; --text: #1f2937;}
@media (prefers-color-scheme: dark) { :root { --bg: #1f2937; --text: #f9fafb; }}
body { background: var(--bg); color: var(--text);}prefers-contrast#
响应对比度偏好:
@media (prefers-contrast: more) { :root { --border-color: black; --text-muted: #1f2937; }
button { border: 2px solid black; }}
@media (prefers-contrast: less) { :root { --border-color: #e5e7eb; --text-muted: #9ca3af; }}实战案例#
可拖拽卡片#
.draggable-card { cursor: grab; user-select: none; touch-action: none; transition: box-shadow 0.2s, transform 0.2s;}
.draggable-card:active { cursor: grabbing; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); transform: scale(1.02);}
.draggable-card.dragging { opacity: 0.8; pointer-events: none;}图片查看器#
.image-viewer { touch-action: pinch-zoom pan-x pan-y; cursor: zoom-in; user-select: none;}
.image-viewer.zoomed { cursor: zoom-out;}
.image-viewer.panning { cursor: grabbing;}代码复制按钮#
.code-wrapper { position: relative;}
.code-block { user-select: all; padding: 16px; background: #1f2937; border-radius: 8px; overflow-x: auto;}
.copy-button { position: absolute; top: 8px; right: 8px; cursor: pointer; opacity: 0; transition: opacity 0.2s;}
.code-wrapper:hover .copy-button { opacity: 1;}禁用状态表单#
fieldset:disabled { pointer-events: none; opacity: 0.6;}
fieldset:disabled * { cursor: not-allowed;}
.form-loading { position: relative; pointer-events: none;}
.form-loading::after { content: ''; position: absolute; inset: 0; background: rgba(255, 255, 255, 0.7); cursor: wait;}滑块组件#
.slider { touch-action: pan-x; user-select: none; cursor: pointer;}
.slider-thumb { cursor: grab;}
.slider-thumb:active { cursor: grabbing;}
.slider-track { pointer-events: none;}响应式可访问设计#
/* 基础样式 */.card { transition: transform 0.3s, box-shadow 0.3s;}
.card:hover { transform: translateY(-4px); box-shadow: 0 12px 24px rgba(0, 0, 0, 0.15);}
/* 减少动画 */@media (prefers-reduced-motion: reduce) { .card { transition: none; }
.card:hover { transform: none; box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15); }}
/* 高对比度 */@media (prefers-contrast: more) { .card { border: 2px solid currentColor; }
.card:hover { outline: 3px solid currentColor; }}常见问题#
🤔 pointer-events: none 后子元素也无法点击?
子元素需要单独设置 pointer-events: auto。
🤔 touch-action 设置后滚动不正常?
确保设置正确的值,pan-y 允许垂直滚动,pan-x 允许水平滚动。
🤔 cursor 自定义图片不显示?
- 检查图片格式(推荐
.png或.cur) - 图片尺寸不要超过 32x32
- 确保提供回退值
CSS 用户交互属性直接影响用户体验。合理使用这些属性,可以让你的界面更加友好、直观,同时也要注意可访问性,尊重用户的系统偏好设置。
至此,CSS 系列 25 篇文章全部完成!从选择器基础到现代布局,从动画效果到用户交互,希望这个系列能帮助你全面掌握 CSS 技术。