【问题标题】:Positioning content in :after pseudo-element absolutely relative to an inline elements top edge将内容定位在 :after 伪元素绝对相对于内联元素的顶部边缘
【发布时间】:2014-10-14 12:22:32
【问题描述】:

我正在寻找一种纯 CSS 的方式来定位 :after 伪元素中的内容绝对相对于另一个元素 - 可能是多行 - 元素的顶部边缘。结果应如下所示:

通常不涉及任何火箭科学来实现这一点,但我想找到一个同时满足以下标准的解决方案:

  • 不要使用:before 伪元素(这已经是实现一些其他独立事物所必需的),
  • 不要在内联元素上使用display: block/inline-block;(因为它会在文本流中造成难看的漏洞),
  • 允许将元素的宽度定义为包含元素的百分比(至少在应用三规则之后),
  • 不要以任何方式硬编码:after-伪元素的顶部位置/边距/填充,使其依赖于父元素在祖父元素中的位置、父元素的高度或实际元素的高度(或简而言之:不要让任何内容依赖于内容),
  • 不要插入额外的 HTML 元素,并且
  • 不要添加JS。

我创建了一个Codepen ,希望它能让我更容易掌握我的目标。

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

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

【问题讨论】:

  • 对于位置敏感的东西也需要::before 吗?否则你可以使用它。
  • ::after 的宽度应该是相对于 <p> 而它的 top 应该相对于 <span>,对吗?我相信这是最难的部分......
  • 感谢您的 cmets。 @Terry:这个问题的想法是在不使用 :before 的情况下找到解决方案,例如如果这已经用于其他用途。 @Luizgrs:是的,我认为这是问题的本质。我很感兴趣是否有某种技巧或解决方法与这两个元素相关,一个用于宽度,另一个用于水平放置。
  • 为什么必须是::after 伪元素?不能是像codepen.io/HerrSerker/pen/GwJhu这样的真实元素吗?
  • 使用纯 CSS 无法满足您提出的要求

标签: css layout css-position pseudo-element


【解决方案1】:

嗯,想要的方法唯一可能的解决方案就是这个。

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

-position:relative 设置为.wrapper。因为您将根据该父级(而非直接父级)移动 ::after left-right

-width: 100% 设置为 ::after(100% 的parent)

-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 上测试。
Live example

编辑:
嗯,是的,我从 ::after 开始,然后意外切换到 ::before =)

好的,对 CSS 的小修改:

- 而不是width: 100% 设置width: auto

- 你需要手动(抱歉)减少margin-top: -(number)px 而不是top: 0 - 不要使用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

【讨论】:

  • 这不符合要求,因为您使用了::before 伪元素,而当使用::after 时,您的解决方案不再起作用:jsfiddle.net/3hvmq13k/2。无论如何,非常感谢您尝试一下。
  • 您新建议的两个解决方案都违反了要求,因为它们对顶部位置/边距进行了硬编码。在这两种修改中,这都与.accent 的高度相关(不允许元素内有其他行数,请参阅jsfiddle.net/9xunLj3t)。不过,感谢您的努力。
【解决方案2】:

我尝试了这些要求:

  • ::after元素处使用bottom [?]属性,或
  • 使用 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%;
  }
}

【讨论】:

  • 我认为您的解决方案仅适用于文本长度。如果您向span data-meta 元素添加其他文本,则定位将关闭。
  • 找不到其他解决方案摘录::before。没办法。
猜你喜欢
  • 2012-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-02
  • 1970-01-01
  • 2017-03-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多