为何未设置display:flex时无法看到::after和::before伪元素?
我跟着YouTube教程做汉堡菜单,在视频6分23秒卡壳了:不给.hamburger-menu设置display:flex的话,就看不到::after和::before伪元素的黑色块。教程说这是因为.hamburger-menu默认是inline元素,但我搞不懂——为啥只有把父元素设为flex/grid,或者给content填文本才能看到这些黑色块?哪怕把父元素设为block也没用。
代码
CSS
.hamburger-menu{ display:flex; } .hamburger-menu:after, .hamburger-menu:before, .hamburger-menu input{ width:60px; height:7px; content:""; background-color:rgb(30,30,30); border-radius:10000px; }
HTML
<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="style.css"/> </head> <body> <label class="hamburger-menu"> <input type="checkbox"></label> </label> </body> </html>
问题原因及解决
核心原因是伪元素的默认display属性是inline,而你给伪元素设置了固定宽高——inline元素的宽高是由内容撑起来的,你给content:""是空值,所以默认情况下哪怕父元素是block,伪元素也会因为没有内容、本身是inline而无法显示你设置的宽高。
那为啥父元素设为flex/grid就有用?因为flex/grid容器里的子元素(包括伪元素)会默认变成flex item/grid item,这类元素的宽高设置是有效的,哪怕内容为空也能显示你设定的尺寸。
给content填文本也能显示的原因是:inline元素有了内容后,宽高会被内容撑开(虽然你设置的宽高对inline元素其实不生效,但背景色会跟着内容区域显示,看起来就有块了)。
至于你说设父元素为block没用,那是因为父元素是block时,伪元素还是inline状态,空content+inline+自定义宽高=无法显示。要让父元素是block时也能看到伪元素,你需要给伪元素单独设置display:block或者display:inline-block,这样它们的宽高设置才会生效,空content也能显示出黑色块:
.hamburger-menu{ display:block; /* 父元素设为block */ } .hamburger-menu:after, .hamburger-menu:before, .hamburger-menu input{ width:60px; height:7px; content:""; background-color:rgb(30,30,30); border-radius:10000px; display:block; /* 给伪元素添加这个属性 */ }
简单总结:
- inline元素不支持自定义宽高,空content的inline伪元素自然看不到
- flex/grid容器会强制子元素(含伪元素)变成能支持宽高的元素类型
- 给伪元素设block/inline-block,哪怕父元素是block,也能让宽高生效显示色块
内容的提问来源于stack exchange,提问作者Michael

