将内容定位在:伪元素之后绝对相对于内联元素的上边缘

时间:2014-10-14 12:22:33

标签: css css3 layout css-position pseudo-element

我正在寻找一种仅限CSS的方式来定位:after伪元素中的内容绝对相对于另一个 - 可能是多行 - 元素的上边缘。结果应该类似于:

Result demonstration

通常没有武器科学参与其中,但我想找到一个符合以下标准的解决方案:

  • 不要使用:before伪元素(这是实现其他一些独立的东西所必需的),
  • 不要在内联元素上使用display: block/inline-block;(因为它会在文本流中创建丑陋的洞),
  • 允许将元素的宽度定义为包含元素的百分比(至少在应用三个规则之后),
  • 不要以任何方式硬编码:after - 伪元素的顶部位置/边距/填充,使其依赖于父元素在祖父元素内的位置,即父元素&#39 ; s高度或实际元素的高度(或使其变短:不要做任何依赖于内容的东西),
  • 不要插入其他HTML元素,
  • 不要添加JS。

我创建了一个Codepen ,希望能让我更容易理解我在这里的目标。

我知道很容易通过违反上面列出的一个限制(如Codepen中所示)来获得结果,但我正在寻找一个优雅的解决方案这个问题不需要这个。

在玩了很长一段时间之后我会说这是不可能的,但如果有人能说服我相反 - 或者至少正式证明它实际上是不可能的,那就太好了。非常感谢您提前提供任何帮助。

2 个答案:

答案 0 :(得分:3)

嗯,使用所需方法的唯一可行解决方案就是这样。

- 首先要提及的是,要实现这一点,您需要直接在CSS中定义::after content,而不是通过data-属性。 (我不知道为什么,但似乎是一个解析问题。)

- position:relative设置为.wrapper。因为您要根据父母(而不是直接父母)移动::after left-right

- width: 100%设为::after(父母的100%)

- white-space: pre设置为::after - 这很重要

- 直接使用content(转义字符)编写\A,以便在特定位置打破该字词。

- 设置top: 0并给它一个负right位置(你想要多远)

注意:如果附加文字溢出包装,您可能需要在某些elemenets上设置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上测试过 Live example

修改
嗯,是的,我从::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 */
}

Live example

另一个编辑
更清洁的工作解决方案,您可以使用content: attr(data-meta)(已移除white-space: pre并将width设置为所需的百分比大小:

.accent::after{
    position: absolute;
    width: 30%;
    content: attr(data-meta);
    right: -50px;
    margin-top: -40px;
}

Live example

答案 1 :(得分:0)

有了这些要求我试过了:

  • ::after元素处使用底部 [?]属性,或
  • 使用 translateY [?]属性

例如: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%;
  }
}