垂直居中:before/:after伪元素的内容

75

我正在尝试实现类似于这张图片的效果:

enter image description here

我有一个包含图片幻灯片的 div,使用 :before 和 :after 伪元素,在其上方和下方显示两个控制按钮,用来切换到下一张 (>>) 或上一张 (<<) 幻灯片图片。

到目前为止,我已经完成了以下代码:

div {
  position: relative;
}

div:before {
  display:block;
  height: 100%;
  content: "stuff";
  position:absolute;
  top: 0; left: 0;
  text-align: center;
}

然而,我无法居中伪元素的内容,文本显示如下:

输入图像描述

这个可行吗?如果不行,最具语义化的解决方法是什么? 我不想居中元素本身,只想居中其内容。我更喜欢将该元素拉伸到100%的高度。

编辑: http://jsfiddle.net/rdy4u/

编辑2: 此外,img是液体/流体,div/img的高度未知,宽度设置为800px和max-width为80%。


你确定那是你的代码吗?(请查看http://jsfiddle.net/RLccx/) - 0b10011
2
我认为伪元素不允许在空元素(如img或input...)上使用。 - Fabrizio Calderan
“IMG” 不能有 before 和 after,不过很明显他可能使用了 div。这只是一个例子。 - dfsq
2
@dfsq,魔鬼就在细节中。特别是在处理更复杂的布局时,具体细节非常重要。 - 0b10011
你是绝对正确的,我道歉!实际上我把img包装在一个div里,并将伪元素应用于该div。我现在不在家,所以这是我根据记忆写的,非常抱歉。 - dcastro
6个回答

117
假设您的元素不是一个 <img> 元素(因为伪元素不允许在自闭合元素上使用),我们假设它是一个 <div> 元素,那么一种方法可以是:
假设您的元素不是一个<img>元素(因为伪元素不能应用于自闭合元素),我们假设它是一个<div>元素,则一种方法可能如下:
div {
    height: 100px ;
    line-height: 100px;
}
div:before, div:after {
    content: "";
    ...
    display: inline-block;
    vertical-align: middle;
    height: ...;
    line-height: normal;
}

如果您无法更改div的行高,另一种方法是:

div {
    position: relative;
}
div:before, div:after {
    position: absolute;
    display: block;
    top: 50%;
    -webkit-transform: translateY(-50%);
    -moz-transform: translateY(-50%);
    -ms-transform: translateY(-50%);
    transform: translateY(-50%);
    content: "";
    width: ...
}
否则,将指示器放置在背景中心位置。

6
第一种解决方案不可行,因为 div 的高度是未知的,第二种也不可行,因为我不想像你使用 top: 50% 那样将整个伪元素居中,我只想让它的内容居中。 - dcastro
@dcastro,你的控件 >><< 是文本还是两个图像? - Fabrizio Calderan
我现在只是使用虚拟的“lorem ipsum”,但我认为我会选择使用CSS或图标字体来生成符号。几乎可以肯定,我不会使用图片。 - dcastro
除非使用图像可以使这种情况成为可能,否则我想我会考虑使用图像。 - dcastro
1
使用图像作为背景,只需将background-position设置为center即可。 - Fabrizio Calderan
嗯,有趣的想法,我会在几个小时后尝试并回复你。 - dcastro

48

使用伪元素的 CSS 中的 flex 非常容易:

.parent::after {
  content: "Pseudo child text";
  position: absolute;
  top: 0;
  right: 0;
  width: 30%;
  height: 100%;
  border: 1px solid red;
  display:flex;
  flex-direction:row;
  align-items: center;
  justify-content: center;
}

请查看 https://jsfiddle.net/w408o7cq/


2
抢我答了。如果有 flexbox 选项,这应该是被接受的答案。 - Alex W
这将使得后置内容重叠在父元素上方。 - robx
@robx 重叠父级实际上就是这个想法...(请参见原帖中的图片) - david
完美答案。在我的情况下,其他答案没有起作用,这个确实帮了我。 - Sagar V

9
使用弹性盒模型时,应首先在父元素中设置固定的宽度和高度,然后再在子元素中指定其他属性。
div::after {
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

1
这很完美 - 简短而简洁。虽然对我来说 height:100% 不是必需的。 - Nuhman

6

我知道我来晚了,但这个简单的弹性布局解决方案对我非常有效,如果对你们有帮助,那就太好了。

.main-div {
    display: flex;
    align-items: center;
}

.my-div-name:before, .my-div-name:after {
    /* This content will be vertically centered with the attributes of the main-div */
}

3

您可以不使用图像来实现这一点。(有时无法做到,例如在:before或:after中使用字体图标)。

div {
   position: relative;
   overflow:hidden;
}

div:before, div:after {
   position: absolute;
   display: block;
   top: 50%;
   -webkit-transform: translateY(-50%);
   -moz-transform: translateY(-50%);
   -ms-transform: translateY(-50%);
   transform: translateY(-50%);

   height:20000px;
   line-height:20000px;

   content: ">>";
}

毋庸置疑,如果你的div将会比20000px更大,那么使用20000px有点儿冒险。只需增加像素即可。

在你的情况下,你的div内部有一张图片,所以需要使用display:block来显示该图片(默认情况下,图片不会显示为display:block)

以下是针对你特殊情况的更新后的fiddle链接。http://jsfiddle.net/rdy4u/56/


1
这是一种使用:before和:after伪元素创建下一个和上一个控件的方法。结合边框技巧为上一个/下一个按钮创建三角形。它不能给您一个100%高度的区域进行单击,但如果您使三角形(箭头)足够大,它应该可以弥补这一点。
div {
  position: relative;
  width: 800px;
  max-width: 80%;
  border: 1px solid red;
  text-align: center;
  margin: 0 auto;
}

div:before, div:after {
  opacity: 0.5;
  display:block;
  content: "";
  position:absolute;
  width: 0; 
  height: 0;
  }

div:before {
  top: 40%; left: 0;
  border-top: 25px solid transparent; 
  border-right: 50px solid blue; 
  border-bottom: 25px solid transparent;
}

div:after {
  top: 40%; right: 0;
  border-top: 25px solid transparent; 
  border-left: 50px solid blue; 
  border-bottom: 25px solid transparent;
}

这是代码的工作原理: http://jsfiddle.net/fiddleriddler/rPPMf/


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