61

第一次真正使用伪:after选择器。不确定我遇到的问题是它的限制还是我只是错过了一些明显的东西。

这是我的实时代码

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 和 Pseudo 选择器之间存在已知冲突(我对此表示怀疑)。谢谢。

4

8 回答 8

118

问题在于您对absolute定位的使用以及您尝试将其居中的方法。如果绝对定位元素,则 ol'margin: 0 auto;方法将无法使事物居中。我向您解释为什么这是问题的结尾,但如果您只是想让它起作用,让我们先找到解决方案。

这是一些工作代码。在 JSFiddle 上查看

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

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

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

设置新的包含块

在您原来的 Fiddle 中,伪元素的位置绝对相对于视口。一个例子可能是展示这意味着什么以及为什么我们不想要这个的最佳方式。考虑将其设置为top: 0. 这将使其锁定在浏览器窗口的顶部(或者,在这种情况下,JSFiddle 框架),而不是父级(li)。所以,如果我们的菜单碰巧在页面底部,或者甚至四处移动,伪元素就会独立于它浮动,粘在页面顶部。

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

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

用技术术语来说,我们在这里所做的是为孩子创建一个新的包含块

定位伪元素

既然我们的绝对定位将相对于父对象确定,我们可以利用这样一个事实,即我们可以使用百分比来定义放置子对象的位置。在这种情况下,您希望它居中,所以我将其设置为left: 50%.

但是,如果您这样做,您会看到它在 50% 处与伪元素的左边缘对齐。这不是我们想要的——我们希望伪元素的中心位于中间。这就是我添加负数的原因margin-left。这使它稍微移动了一点,以使中间与父母的中心对齐。

一旦我们这样做,它就会居中!辉煌!

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

保证金的自动值是通过相当复杂的算法计算得出的。有时,它的计算结果为 0。根据经验,我知道这是发生这种情况的一个例子,尽管我还没有通过算法找到确切的原因。如果您想了解它,请查看大多数浏览器最有可能实现的规范。

于 2013-05-29T16:11:03.233 回答
19

calc用于居中

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

注意:这在 IE8 及更低版本 ( caniuse ) 中不受支持,但您可以为旧版浏览器提供后备方案。

在此代码笔上查看。我也在使用 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;
}
于 2014-07-21T17:01:24.290 回答
11

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

“浮动:中心;” 是无效的,并且不会工作。混合浮动元素和绝对定位元素是给你的布局带来麻烦的可靠方法,因为它们并不能很好地协同工作。

尝试这样的事情:

li.current:after {
content: 'YOUR CONTENT';
display: block;
width: 100%;
text-align: center; }
于 2017-06-26T11:52:22.453 回答
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 关于垂直定位的建议类似的策略。我们与底部对齐,然后使用负边距底部将其推出到所需位置。

于 2013-05-29T16:32:33.603 回答
3

margin:auto用于居中

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

要使用此方法,必须将right和属性设置为才能生效。left0margin: auto

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

完整信息见链接:

http://www.smashingmagazine.com/2013/08/09/absolute-horizo​​ntal-vertical-centering-css/

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

ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
}
<div>
  <ul>
    <li class="current"></li>
  </ul>
</div>

于 2015-04-12T09:37:58.623 回答
0

使用 pesudo 元素 :after 或 :before 使用 display: inline-block;

尝试这样的事情:

content: url(../images/no-result.png);
display: inline-block;
width: 100%;
text-align: center;
于 2019-09-20T09:20:28.947 回答
0

这可能是最简单的方法:

.child_class::after{
    position: absolute;
    content: 'YourContentHere';
    width: 100%;
    text-align: center;
    top: 50%;
}

最简单的方法 -

于 2021-11-01T17:55:46.443 回答
0

transform: translate()无需固定尺寸即可完成定心。这是因为translate(<x>%)将使用(伪)元素自己的大小,而leftmargin-left使用容器的大小。因此,通过将它们一起使用,我们可以找到确切的中心点。

tl;博士

垂直居中:

.container {
  position: relative;
}

.container:after {
  top: 50%;
  transform: translateY(-50%);
}

水平居中:

.container {
  position: relative;
}

.container:after {
  left: 50%;
  transform: translateX(-50%);
}

完整示例

.container {
  position: relative;
  display: inline-block;
  background: #4aa;
  color: white;
  padding: .5ex 1ex; 
}

.container:after {
  content: ":after";
  position: absolute;
  background: #a4a;
  color: white;
  padding: .5ex 1ex; 

  /* position below container */
  top: 100%;

  /* move right by 50% of containers width */
  left: 50%;

  /* move left by 50% of own width */
  transform: translateX(-50%);
}
<p class="container">
  Container with content
</p>

于 2022-02-08T13:00:11.870 回答