使用transform skew做3D设计时li::before实际高度超出设置值
问题:使用transform skew制作3D效果时,伪元素高度显示异常
我在使用transform skew属性制作3D设计,但为li::before伪元素设置高度后,实际显示的高度远大于设定值。代码里设置的高度为98.4px,但浏览器Box Model中显示为135px。
代码片段
CSS代码
@import url('https://fonts.googleapis.com/css2?family=Oswald:wght@500&display=swap'); *,*::before,*::after{ margin:0; padding:0; box-sizing:border-box; color:white; font-family: 'Oswald', sans-serif; } a{ text-decoration: none; } html, body { height: 100%; width: 100%; } body{ background-color:#434750; display:flex; justify-content: center; align-items:center; } ul{ font-size:1.2rem; transform: skewY(-15deg); } li{ background-color: #3e3f46; list-style:none; padding:1em; position: relative; } li::before{ content: ""; position:absolute; width:50px; height:98.4px; background-color:#3e3f46; filter: brightness(0.7); top:0; left: -50px; display: block; transform-origin: right; transform: skewY(45deg); }
HTML代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <link rel="stylesheet" href="style.css"> </head> <body> <ul> <li><a href = "#">Whats App</a></li> <li><a href = "#">Instagram</a></li> <li><a href = "#">Facebook</a></li> <li><a href = "#">Twitter</a></li> </ul> </body> </html>
Box Model截图

原因分析
这是变换叠加+继承导致的问题:
- 父元素
ul设置了transform: skewY(-15deg),这个斜切效果会传递给所有子元素(包括li和它的伪元素)。 - 伪元素自身又叠加了
transform: skewY(45deg),两次斜切让元素被拉伸变形,浏览器计算的实际高度自然和你硬编码的98.4px不符。 - 另外,硬写死高度本身就不灵活,只要字体大小、padding稍有变化,高度就会错位。
修复方案
- 放弃硬编码高度,让伪元素继承
li的高度,设置height: 100%。 - 调整伪元素的变换原点和斜切角度,抵消父元素的skew影响,同时保持3D视觉效果。
- 优化文字显示,避免斜切导致文字倾斜。
修改后的CSS代码
@import url('https://fonts.googleapis.com/css2?family=Oswald:wght@500&display=swap'); *,*::before,*::after{ margin:0; padding:0; box-sizing:border-box; color:white; font-family: 'Oswald', sans-serif; } a{ text-decoration: none; } html, body { height: 100%; width: 100%; } body{ background-color:#434750; display:flex; justify-content: center; align-items:center; } ul{ font-size:1.2rem; } li{ background-color: #3e3f46; list-style:none; padding:1em; position: relative; transform: skewY(-15deg); margin: 0.5em 0; /* 增加间距强化3D感 */ } /* 反向斜切让文字保持水平 */ li a{ display: block; transform: skewY(15deg); } li::before{ content: ""; position:absolute; width:50px; height: 100%; /* 继承li高度,无需硬编码 */ background-color:#3e3f46; filter: brightness(0.7); top: calc(-50px * tan(15deg)); /* 精准计算顶部偏移,对齐li边缘 */ left: -50px; transform-origin: top right; /* 抵消父元素的-15deg,得到视觉上的45度斜面 */ transform: skewY(60deg); }
效果说明
- 伪元素高度跟随
li自动变化,再也不用手动调整数值。 - 通过变换原点和角度的计算,完美抵消父元素的斜切影响,3D斜面效果准确。
- 文字通过反向斜切保持水平,不影响可读性。
内容的提问来源于stack exchange,提问作者Gloryjaw
相关产品推荐
相关产品推荐

