我正在寻找一种仅 CSS 的方法来将
:after
伪元素中的内容绝对相对于另一个 - 可能是多行 - 元素的顶部边缘定位。结果应该类似于这样:
通常不需要任何火箭科学来实现这一点,但我想找到一个也满足以下标准的解决方案:
:before
伪元素(这已经是实现其他一些独立事物所必需的),display: block/inline-block;
(因为它会在文本流中产生丑陋的漏洞),:after
伪元素的顶部位置/边距/填充进行硬编码,使其依赖于父元素在祖父元素内的位置、父元素的高度或实际元素的高度(或者使简而言之:不要做任何依赖于内容的事情),我创建了一个 Codepen ,希望它能让我更容易地掌握我在这里要做什么。
我知道通过违反上面列出的限制之一很容易得到结果(如 Codepen 中所示),但我正在寻找一个优雅的解决方案来解决这个问题,但不需要这样做。
在玩了很长一段时间后,我会说这是不可能的,但如果有人能够说服我相反的观点,或者至少正式证明这实际上是不可能的,那就太好了。非常感谢您提前提供的任何帮助。
嗯,唯一可能的解决方案可能就是这个。
- 首先要提到的是,要实现此功能,您需要直接在 CSS 中定义
::after
content
,而不是通过 data-
属性。 (我不知道为什么,但似乎是一个解析问题。)position:relative
设置为 .wrapper
。因为您要根据该父级(而不是直接父级)移动 ::after
left-right
。width: 100%
设置为 ::after
(父级的 100%)white-space: pre
设置为 ::after
- 这很重要content
,并使用 \A
(转义字符)在特定位置断开单词。top: 0
并给它一个负 right
位置(你想要多远)注意: 如果附加文本溢出包装器,您可能需要在某些元素上设置
word-wrap: break-word
。基本上,这是对 CSS 的添加/修改:
.wrapper {
position: relative;
}
.accent::before{
position: absolute;
width: 100%;
content: "Unfortunately \A it is aligned with \A the last line of said span.";
white-space: pre;
right: -70%;
}
.content p {
word-wrap: break-word; /* in my example <p> was problematic */
}
注意:我不知道这种方法对于响应式设计有多好,从来没有尝试过。
在 FF 和 Chrome 上测试。
实例
编辑:
嗯,是的,我一开始是
::after
然后不小心切换到了 ::before
=)好吧,对 CSS 进行一些小修改:
- 代替
width: 100%
设置 width: auto
top: 0
,而不是margin-top: -(number)px
- 不要使用top
,因为它将根据包装器本身设置顶部位置。right: -(number)%
至 right: -(number)px
CSS修改:
.accent::after{
width: auto;
right: -50px;
margin-top: -40px;
/* and remove "top" property completely */
}
另一个编辑
更干净的工作解决方案,您可以使用
content: attr(data-meta)
(删除 white-space: pre
并将 width
设置为所需的百分比大小:
.accent::after{
position: absolute;
width: 30%;
content: attr(data-meta);
right: -50px;
margin-top: -40px;
}
根据这些要求,我尝试了:
例如:http://jsfiddle.net/csdtesting/w4zvmbjh/
<div class="wrapper">
<div class="content">
<h2>1-Unfortunately it doesn't work with multline content</h2>
<p>Pellentesque ultrices sed quam pellentesque, eu ultricies nulla semper.
<label for="pretty" class="accent" data-meta="Unfortunately it is aligned with the last line of said span.">Etiam leo ligula, laoreet eget urna et, dignissim facilisis nisi ante.</label>Duis gravida lectus tellus, sed rutrum nisi ultricies a. Aliquam pellentesque ante at ipsum convallis porta.</p>
<h2>2-Unfortunately it doesn't work with multline content</h2>
<p>Pellentesque ultrices sed quam pellentesque, eu ultricies nulla semper. <span class="accent-bottom" data-meta="Unfortunately it is aligned with the last line of said span.">Etiam leo ligula, laoreet eget urna et, dignissim facilisis nisi ante.</span> Duis gravida lectus tellus, sed rutrum nisi ultricies a. Aliquam pellentesque ante at ipsum convallis porta.</p>
</div>
</div>
label
{
color:red !important;
}
/* Basic typo (not problem related) */
body {
font-family: Georgia, serif;
font-size: 82.5%;
line-height: 1.167;
color: #555;
}
h1, h2 {
color: #222;
}
h1 {
font-size: 1.167em;
}
h2 {
font-size: 1em;
}
/* Problem related styles */
.wrapper {
position: relative;
width: 580px;
margin: 2em auto;
}
.content p {
width: 62.069%;
}
.accent {
color: cornflowerblue;
&:after {
content: attr(data-meta);
position: absolute;
right: 0;
width: 31.035%;
transform:translateY(-50%)
}
}
.accent-bottom {
color: cornflowerblue;
&:after {
content: attr(data-meta);
position: absolute;
right: 0;
width: 31.035%;
bottom: 14%;
}
}
使用
display: flex
解决这个问题的方法,这里是例子:
&::after {
content: 'PLAY';
position: absolute;
left: 50%;
top: 50%;
width: 6rem;
height: 6rem;
transform: translate(-50%, -50%);
border-radius: 100rem;
background-color: black;
color: white;
display: flex;
justify-content: center;
align-items: center;
}