CSS 将伪元素居中
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16818792/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Center a Pseudo Element
提问by EnigmaRM
First time really using the pseudo :after
selector. Not sure if the problem I'm running into is a limitation of it or I'm just missing something obvious.
第一次真正使用伪: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;
}
I've created a little triangle (Or rather a box that has been rotated to look like a triangle). I want it centered within the <li></li>
but can't figure it out using my normal methods.
The things that have failed (in no particular order):
我创建了一个小三角形(或者更确切地说是一个旋转成三角形的盒子)。我希望它在 内居中,<li></li>
但无法使用我的常规方法弄清楚。失败的事情(排名不分先后):
text-align: center;
float: center;
margin: 0 auto;
margin-right: 0;
margin-left: 0;
What am I missing? I doubt it matters, but I'm using AngularJS. Thought I'd mention it in case there is a known conflict between Angular & Pseudo selectors (which I doubt). Thanks.
我错过了什么?我怀疑这很重要,但我使用的是 AngularJS。我想我会提到它以防 Angular 和 Pseudo 选择器之间存在已知的冲突(我对此表示怀疑)。谢谢。
回答by jamesplease
The issue is your use of absolute
positioning & the method you're using to try and center it. If you position an element absolutely, the ol' margin: 0 auto;
method won't work to center the thing. I point you to an explanation as to why this is at the end of the question, but in case you just want this to work let's get to the solution first.
问题在于您对absolute
定位的使用以及您用来尝试将其居中的方法。如果您绝对定位元素,则 ol'margin: 0 auto;
方法将无法使元素居中。我向您指出为什么会出现在问题的末尾,但如果您只是想让它起作用,让我们首先找到解决方案。
Here's some working code. View it on JSFiddle
这是一些工作代码。在 JSFiddle 上查看
#tool-menu li {
...
position: relative;
}
li.current:after {
...
position: absolute;
width: 10px;
top: 6;
left: 50%;
margin-left: -5px;
}
Let's break down what's going on here.
让我们分解一下这里发生了什么。
Setting up a new Containing Block
设置一个新的包含块
In your original Fiddle, the pseudoelement is positioned absolutely relative to the viewport. An example might be the best way to show what this means, and why we don't want this. Consider setting it to top: 0
. This would keep it latched to the top of the browser window (or, in this case, the JSFiddle frame), rather than the parent (the li
). So, if our menu happened to be at the bottom of the page, or even moving around, the pseudoelement would be floating independent from it, stuck to the top of the page.
在您的原始 Fiddle 中,伪元素绝对相对于视口定位。一个例子可能是展示这意味着什么的最好方式,以及为什么我们不想要这个。考虑将其设置为top: 0
. 这将使其锁定在浏览器窗口的顶部(或者,在这种情况下,是 JSFiddle 框架),而不是父级(li
)。因此,如果我们的菜单碰巧在页面底部,甚至四处移动,伪元素将独立于它浮动,粘在页面顶部。
This is the default behavior of an absolutely positioned element when you don't explicitly set the position on any parent elements. What we want is to have its position defined relative to the parent. If we do this then the pseudoelement sticks with the parent, no matter where it happens to be.
当您没有在任何父元素上显式设置位置时,这是绝对定位元素的默认行为。我们想要的是相对于父级定义它的位置。如果我们这样做,那么无论它碰巧在哪里,伪元素都会与父元素保持一致。
To make this happen, you need to set the parent, #tool-menu li
, to be explicitly positioned (which means setting it to be anything other than position: static
). If you choose to use position: relative;
, it won't change the computed location of the parent on the page, and does the thing we want. So that's why I used that one.
要实现这一点,您需要将父 , 设置#tool-menu li
为显式定位(这意味着将其设置为 以外的任何内容position: static
)。如果您选择使用position: relative;
,它不会更改页面上父项的计算位置,而是执行我们想要的操作。所以这就是我使用那个的原因。
In technical terms, what we're doing here is creating a new containing blockfor the child.
从技术角度来说,我们在这里所做的是为孩子创建一个新的包含块。
Positioning the Pseudoelement
定位伪元素
Now that our absolute positioning will be determined in relation to the parent, we can take advantage of the fact that we can use percentages to define where to place the child. In this case, you want it centered, so I set it be left: 50%
.
既然我们的绝对定位将相对于父级确定,我们可以利用我们可以使用百分比来定义放置子级的位置这一事实。在这种情况下,您希望它居中,所以我将其设置为left: 50%
.
If you do just this, though, you'll see that this lines up the left edge of the pseudoelement at 50%. This isn't what we want – we want the center of the pseudoelement to be at the middle. And that's why I added the negative margin-left
. This scoots it over a bit to line the middle up with the center of the parent.
但是,如果您只是这样做,您将看到它与伪元素的左边缘对齐 50%。这不是我们想要的——我们希望伪元素的中心在中间。这就是为什么我添加了负数margin-left
。这将它滑过一点以将中间与父级的中心对齐。
And once we do that, it's centered! Brilliance!
一旦我们这样做了,它就居中了!辉煌!
Why didn't my margin: auto;
work?
为什么我的margin: auto;
工作没有?
The auto value of a margin is calculated from a fairly complex algorithm. At times, it computes to 0. I know from experience that this is one such instance of that happening, though I haven't yet traced my way through the algorithm to see exactly why. If you'd like to run through it, take a look at the spec most browsers have most likely implemented.
保证金的自动值是根据相当复杂的算法计算出来的。有时,它计算为 0。我从经验中知道这是发生这种情况的一个这样的实例,尽管我还没有通过算法追踪我的方式以确切了解原因。如果您想通读一遍,请查看大多数浏览器最有可能实现的规范。
回答by Mark Reilly
Using calc
to center
使用calc
居中
You can also use the calc
function in css to center the pseudo element.
您还可以使用calc
css 中的函数将伪元素居中。
Note: This isn't supported in IE8 and below (caniuse) but you can provide a fallback for older browsers.
注意:这在 IE8 及更低版本 ( caniuse) 中不受支持,但您可以为旧浏览器提供后备。
View it on this code pen. I'm also using MarkP's css border method to draw the triangle.
在此代码笔上查看。我也在使用 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;
}
回答by Hexdom
Wouldn't be better to just define the width as a percentage, make it a block element and text-align it in the center?
将宽度定义为百分比,使其成为块元素并将其文本对齐在中心不是更好吗?
"float: center;" is invalid, and won't work. Mixing floated and absolute positioned elements are a sure way to get trouble with your layout as they don't really work that well togheter.
“浮动:中心;” 无效,将无法工作。混合浮动元素和绝对定位元素肯定会给你的布局带来麻烦,因为它们在一起并不能很好地工作。
Try something like this:
尝试这样的事情:
li.current:after {
content: 'YOUR CONTENT';
display: block;
width: 100%;
text-align: center; }
回答by MarkP
Not directly related (have already voted up jmeas) but you may also find it easier to use the CSS border trick to make the triangle. e.g.
不直接相关(已经投票支持 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;
}
Similar tactics as to what jmeas has suggested with regards to the vertical positioning. We align to the bottom and then use a negative margin-bottom to push this out to the desired location.
与 jmeas 就垂直定位提出的建议类似的策略。我们对齐到底部,然后使用负边距底部将其推出到所需的位置。
回答by user1095118
Using margin:auto
to center
使用margin:auto
居中
As long as the element has a width declared you can use the absolute centering method.
只要元素声明了宽度,您就可以使用绝对居中方法。
To use this method the right
and left
properties must be set to 0
for margin: auto
to be effective.
要使用此方法right
,left
必须将和属性设置为0
formargin: auto
才能生效。
This method can be expanded to implement horizontal centering as well.
此方法也可以扩展以实现水平居中。
see link for full info:
完整信息见链接:
http://www.smashingmagazine.com/2013/08/09/absolute-horizontal-vertical-centering-css/
http://www.smashingmagazine.com/2013/08/09/absolute-horizontal-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>
回答by ocram88
With pesudo element :after or :before use display: inline-block;
使用伪元素 :after 或 :before 使用 display: inline-block;
Try something like this:
尝试这样的事情:
content: url(../images/no-result.png);
display: inline-block;
width: 100%;
text-align: center;