以伪元素为中心

时间:2013-05-29 16:03:58

标签: css pseudo-element

第一次真正使用伪:after选择器。不确定我遇到的问题是否是一个限制,或者我只是遗漏了一些明显的东西。

Here's my live code

li.current:after {
    border-width: 1px 1px 0 0;
    content: ' ';
    background: #256f9e;
    display: block;
    height: 13px;
    position: absolute;
    width: 10px;
    top: 6;
    margin:0px auto;
    z-index: 99;
    transform: rotate(-224deg);
    -webkit-transform: rotate(-224deg);
    -moz-transform: rotate(-224deg);
    -ms-transform: rotate(-224deg);
    -o-transform: rotate(-224deg);
    transform-origin: 50% 50%;
    -webkit-transform-origin: 50% 50%;
    -moz-transform-origin: 50% 50%;
    -ms-transform-origin: 50% 50%;
    -o-transform-origin: 50% 50%;
    text-align: center;
    float: center;
}

我创建了一个小三角形(或者更确切地说是一个旋转成三角形的框)。我希望它在<li></li>中居中,但无法使用我的常规方法解决它。 失败的事情(没有特别的顺序):

text-align: center;
float: center;
margin: 0 auto;
margin-right: 0;
margin-left: 0;

我错过了什么?我怀疑这很重要,但我正在使用AngularJS。以为我会提到它,以防Angular&amp; amp;伪选择器(我怀疑)。 感谢。

6 个答案:

答案 0 :(得分:87)

问题在于您使用absolute定位&amp;你用来试图使它居中的方法。如果你绝对定位一个元素,那么ol'margin: 0 auto;方法将无法使该东西居中。我指出一个解释,为什么这是问题的最后,但如果你只是想让它工作,让我们首先找到解决方案。

这是一些有效的代码。 View it on JSFiddle

#tool-menu li {
  ...
  position: relative;
}

li.current:after {
  ...
  position: absolute;
  width: 10px;
  top: 6;
  left: 50%;
  margin-left: -5px;
}

让我们分解这里发生的事情。

设置新的包含块

在原始小提琴中,伪元素绝对相对于视口定位。一个例子可能是显示这意味着什么的最佳方式,以及为什么我们不想要这个。考虑将其设置为top: 0。这将使其锁定在浏览器窗口的顶部(或者,在本例中为JSFiddle框架),而不是父级(li)。因此,如果我们的菜单恰好位于页面底部,甚至四处移动,那么伪元素将独立于其中浮动,停留在页面顶部。

当您未在任何父元素上显式设置位置时,这是绝对定位元素的默认行为。我们想要的是相对于父级定义其位置。如果我们这样做,那么伪元素就会与父母一起,无论它在哪里。

要实现这一点,您需要将父#tool-menu li设置为显式定位(这意味着将其设置为position: static以外的任何其他内容)。如果您选择使用position: relative;,它将不会更改页面上父级的计算位置,并且会执行我们想要的操作。这就是我使用那个的原因。

在技术方面,我们在这里做的是为孩子创建一个新的containing block

定位Pseudoelement

现在我们的绝对定位将与父母相关,我们可以利用这一事实,即我们可以使用百分比来定义孩子的位置。在这种情况下,您希望它居中,因此我将其设置为left: 50%

但是,如果你这样做的话,你会发现这会将伪元素的左边缘排成50%。这不是我们想要的 - 我们希望伪元素的中心位于中间。这就是我添加负面margin-left的原因。这会将它略微划过来,将中间的线与父母的中心对齐。

一旦我们这样做,它就集中了!辉煌!

为什么我的margin: auto;没有工作?

边距的自动值是从相当复杂的算法计算出来的。有时,它计算为0.我从经验中知道,这是发生这种情况的一个例子,尽管我还没有通过算法追踪我的方式来确切找到原因。如果你想要完成它,take a look at the spec most browsers have most likely implemented.

答案 1 :(得分:8)

使用calc居中

您还可以使用css中的calc函数将伪元素居中。

注意:IE8及以下版本(caniuse)不支持此功能,但您可以为旧版浏览器提供后备功能。

在此code pen上查看。我也使用MarkP的css边框方法绘制三角形。

li.current:after {
  content: '';
  display: block;
  height: 0;
  position: absolute;
  width: 0;
  overflow: hidden;
  bottom: -5px;
  left: calc(50% - 5px);
  z-index: 2;
  border-top: 5px #256f9e solid;
  border-left: 5px transparent solid;
  border-right: 5px transparent solid;
}

答案 2 :(得分:3)

没有直接相关(已经投了jmeas)但你也可能会发现使用CSS边框技巧制作三角形更容易。例如

li.current:after {
    content: '';
    display: block;
    height: 0;
    position: absolute;
    width: 0;
    overflow:hidden;
    bottom: 0;
    left: 50%;
    margin: 0 0 -5px -5px;
    z-index: 99;
    border-top: 5px #256f9e solid;
    border-left: 5px transparent solid;
    border-right: 5px transparent solid;
}

关于jmeas对垂直定位的建议,采取了类似的策略。我们对齐底部,然后使用负边距底部将其推出到所需位置。

答案 3 :(得分:3)

将宽度定义为百分比,将其作为块元素并将其文本对齐在中心是不是更好?

“float:center;”无效,无效。混合浮动和绝对定位元素是一种可靠的方法来解决布局问题,因为它们并没有真正发挥作用。

尝试这样的事情:

li.current:after {
content: 'YOUR CONTENT';
display: block;
width: 100%;
text-align: center; }

答案 4 :(得分:1)

使用margin:auto居中

只要元素声明了宽度,就可以使用绝对居中方法。

要使用此方法,必须将rightleft属性设置为0才能使margin: auto生效。

此方法也可以扩展为实现水平居中。

请参阅完整信息链接:

http://www.smashingmagazine.com/2013/08/09/absolute-horizontal-vertical-centering-css/

li.current:after {
  display: block;
  position: absolute;
  right: 0;
  bottom: -5px;
  left: 0;
  margin: auto;
  border-width: 5px;
  border-style: solid;
  border-color: transparent;
  border-top-color: #256f9e;
  width: 0;
  height: 0;
  content: "";
}

答案 5 :(得分:0)

带有伪元素:使用后或使用前显示:inline-block;

尝试这样的事情:

content: url(../images/no-result.png);
display: inline-block;
width: 100%;
text-align: center;