使用flexbox和:after定位元素

3
在我正在处理的一个网站上,页面顶部有一个高度为300px的横幅,其中包含页面的标题和下划线。
这是标记。
<div class="container">
  <div id="banner">
        <div class="jumbotron">
            <div class="container">
                <h1>Terms and conditions</h1>
                <img class="center-block" src="assets/img/common/header-blue-underline.png" width="158" height="10" alt=""/> 
            </div>    
        </div>
    </div>

    <div id="banner-nav">
        <ul class="get-in-touch-links">
            <li><a href="/">Home</a></li>
        </ul>
    </div> 
</div>

这使得它具有样式(带标记)。

enter image description here

为了实现这个目标,我使用了边距来强制间距,但当标题变得更长时,这种方法很难维护。我宁愿使用Flexbox来对齐横幅内的文本,以便文本始终垂直居中,无论内容量多少。
例如,我可以将类应用于#banner,如下所示:
.flex{
    display: -webkit-box;
    display: -moz-box;
    display: -ms-flexbox;
    display: -webkit-flex;
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
}

问题是:使用这种方法时,图像不能自然地浮动在文本下方。
因此,我尝试了:
<div class="container">
  <div id="banner" class="flex">

      <h1>Nulla quis lo</h1>



    </div>

    <div id="banner-nav">
        <ul class="get-in-touch-links">
            <li><a href="/">Home</a></li>
        </ul>
    </div> 
</div>

#banner h1:after{
            content: url(assets/img/common/header-blue-underline.png);
        }

所以下划线应该自动放置在h1下方,但实际上它只会坐在h1元素旁边。

enter image description here

基本上,我正在努力停止把事情做得很随意,而是使用现代标准来精确地定位事物。


2
你能否创建一个可运行的示例,以便我们可以进行调整? 我猜你需要在 .flex {...} 中添加 flex-direction: column;,但我想尝试几个不同的想法。 - Raphael Rafatpanah
我应该创建一个 CodePen 还是其他什么东西?或者直接在这个页面上创建可运行的代码? - Jesse Orange
无论您最擅长的语言。 - Raphael Rafatpanah
2个回答

4
作为伪元素的默认显示方式是inline,因此您的::after将与文本并排对齐。
您可以将其设置为块级元素,给它一个宽度,并使用自动边距来居中。
#banner h1::after {
        content: url(assets/img/common/header-blue-underline.png);
        display: block;
        width: 40%;
        margin: 0 auto; 
    }

或者更简单的方法是,将你的 h1 设为弹性容器,这样它会将 ::after 推到自己的行。
#banner h1{
        display: flex;
        flex-wrap: wrap;
        justify-content: center;
    }

#banner h1:after{
        content: url(assets/img/common/header-blue-underline.png);
    }

一种可能的升级方法是使用伪元素 作为一条线,以避免加载图像。

.flex{
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
}

h1 {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
}

h1::after {
  content: '';
  width: 40%;
  height: 6px;
  margin-top: 15px;
  background: lightblue;
}
<div class='flex'>
  <h1> A header with a blue line </h1>
</div>


我将尝试这两个示例,并会回报结果。虽然感谢你详细的答复。 - Jesse Orange
@JesseOrange 我犯了一个错误,在我建议基于::after的解决方案是h1的兄弟时,实际上不是:) ... 我更新了我的答案,提供了一个正确的解决方案。 - Asons

2

如果主容器设置了height,您也可以从主容器中使用flex并使用margin来分配其子元素 (渐变色还可以部分地下划线标题)

.flex {
  color: rgb(253, 253, 254);
  display: flex;
  flex-direction: column;
  height: 250px;/* can be any heights and units */
  background: 
       linear-gradient(to left, rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.7))/* gradient used here to darken the bg image , demo purpose */,
       url(http://lorempixel.com/800/200/technics/6) center / cover;
}

#banner {
  margin: auto;/* center in the container and push others to the the edges */
}

#banner h1 {
  background: linear-gradient(to left, rgba(18, 153, 221, 0.9), rgba(18, 153, 221, 0.9)) no-repeat bottom center / 90px 5px;
  padding-bottom: 1em;
}

#banner-nav {
  background: rgba(18, 153, 221, 0.8);
}


/* quick bad reset*/

ul,
li,
a {
  color: inherit;
  list-style-type: none;
  display: flex;
  margin: 0 1em;
  padding: 0.25em;
}
<div class="container flex">
  <div id="banner">
    <h1>Nulla quis lotest</h1>
  </div>
  <div id="banner-nav">
    <ul class="get-in-touch-links">
      <li><a href="/">Home</a></li>
    </ul>
  </div>
</div>

CodePen演示,可以试玩一下。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接