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

问题描述 投票:0回答:3

我正在寻找一种仅 CSS 的方法来将

:after
伪元素中的内容绝对相对于另一个 - 可能是多行 - 元素的顶部边缘定位。结果应该类似于这样:

Result demonstration

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

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

我创建了一个 Codepen ,希望它能让我更容易地掌握我在这里要做什么。

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

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

css layout css-position pseudo-element
3个回答
5
投票

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

- 首先要提到的是,要实现此功能,您需要直接在 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;
}

实例


1
投票

根据这些要求,我尝试了:

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

0
投票

使用

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;
}

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.