如何用CSS复刻Photoshop变换工具的8个小方块边框效果
嘿,这个需求我之前做类似的设计时刚好研究过,给你分享两种靠谱的实现方案,各有优劣,你可以根据自己的场景来选~
方案一:绝对定位小方块(适合需要交互的场景)
这个方案思路和你想的一致,用相对定位的容器+绝对定位的小方块来实现,好处是方块能单独加交互,比如拖拽调整容器大小。
实现代码
<div class="ps-selector"> <!-- 8个控制方块 --> <span class="handle top-left"></span> <span class="handle top-center"></span> <span class="handle top-right"></span> <span class="handle right-center"></span> <span class="handle bottom-right"></span> <span class="handle bottom-center"></span> <span class="handle bottom-left"></span> <span class="handle left-center"></span> <!-- 容器内部可放任意内容 --> <div class="content"> 这里是容器内的内容,尺寸会自适应 </div> </div>
:root { --handle-size: 10px; /* 统一控制方块大小,改这一个值就行 */ --border-color: #000; } .ps-selector { position: relative; border: 1px solid var(--border-color); padding: 20px; /* 内部内容的内边距,按需调整 */ display: inline-block; /* 让容器自适应内容宽度,固定宽高就换成width/height */ } .handle { position: absolute; width: var(--handle-size); height: var(--handle-size); background-color: var(--border-color); /* 可选:加白色边框更贴近PS选框效果 */ /* border: 1px solid #fff; */ } /* 逐个定位方块 */ .top-left { top: calc(-var(--handle-size)/2); left: calc(-var(--handle-size)/2); } .top-center { top: calc(-var(--handle-size)/2); left: 50%; transform: translateX(-50%); } .top-right { top: calc(-var(--handle-size)/2); right: calc(-var(--handle-size)/2); } .right-center { top: 50%; right: calc(-var(--handle-size)/2); transform: translateY(-50%); } .bottom-right { bottom: calc(-var(--handle-size)/2); right: calc(-var(--handle-size)/2); } .bottom-center { bottom: calc(-var(--handle-size)/2); left: 50%; transform: translateX(-50%); } .bottom-left { bottom: calc(-var(--handle-size)/2); left: calc(-var(--handle-size)/2); } .left-center { top: 50%; left: calc(-var(--handle-size)/2); transform: translateY(-50%); } .content { /* 内部内容样式按需调整 */ font-size: 16px; color: #333; }
优缺点
- ✅ 兼容性拉满,甚至低版本IE都能兼容(不用transform的话换固定margin值就行)
- ✅ 方块是独立DOM元素,轻松加hover、拖拽等交互事件
- ❌ 多了8个DOM元素,结构稍微有点冗余
方案二:多重背景实现(静态展示首选)
如果只是需要静态的选框效果,用CSS多重背景完全不用额外DOM元素,代码更简洁。
实现代码
<div class="ps-selector"> <div class="content"> 这里是容器内的内容,尺寸会自适应 </div> </div>
:root { --handle-size: 10px; --border-color: #000; } .ps-selector { position: relative; border: 1px solid var(--border-color); padding: 20px; display: inline-block; /* 用8个linear-gradient画方块作为背景 */ background-image: linear-gradient(var(--border-color), var(--border-color)), linear-gradient(var(--border-color), var(--border-color)), linear-gradient(var(--border-color), var(--border-color)), linear-gradient(var(--border-color), var(--border-color)), linear-gradient(var(--border-color), var(--border-color)), linear-gradient(var(--border-color), var(--border-color)), linear-gradient(var(--border-color), var(--border-color)), linear-gradient(var(--border-color), var(--border-color)); background-size: var(--handle-size) var(--handle-size); background-repeat: no-repeat; /* 定位每个方块的位置 */ background-position: calc(-var(--handle-size)/2) calc(-var(--handle-size)/2), /* 左上 */ 50% calc(-var(--handle-size)/2), /* 上中 */ calc(100% + var(--handle-size)/2) calc(-var(--handle-size)/2), /* 右上 */ calc(100% + var(--handle-size)/2) 50%, /* 右中 */ calc(100% + var(--handle-size)/2) calc(100% + var(--handle-size)/2), /* 右下 */ 50% calc(100% + var(--handle-size)/2), /* 下中 */ calc(-var(--handle-size)/2) calc(100% + var(--handle-size)/2), /* 左下 */ calc(-var(--handle-size)/2) 50%; /* 左中 */ } .content { font-size: 16px; color: #333; }
优缺点
- ✅ 零额外DOM元素,结构极其简洁
- ✅ 代码量少,维护方便(改方块大小只改CSS变量)
- ❌ 兼容性稍差,IE9及以下不支持多重背景和calc
- ❌ 方块是背景,没法直接加交互事件,适合纯静态场景
总结建议
如果你的项目需要兼容旧浏览器,或者要给方块加拖拽调整大小这类交互,选方案一;如果只是静态展示,且不用考虑低版本浏览器,方案二更省心。
内容的提问来源于stack exchange,提问作者drake035
相关产品推荐
相关产品推荐

