it-swarm.com.de

Positionieren von Inhalten in: nach Pseudoelementen absolut relativ zu einer Inline-Element-Oberkante

Ich suche nach einer Nur-CSS-Methode, um Inhalte in einem :after-Pseudoelement absolut relativ zu der oberen Kante eines anderen - möglicherweise mehrzeiligen - Elements zu positionieren. Das Ergebnis sollte ungefähr so ​​aussehen:

Result demonstration

Normalerweise ist keine Raketenwissenschaft beteiligt, um dies zu archivieren, aber ich möchte eine Lösung finden, die auch die folgenden Kriterien erfüllt:

  • Verwenden Sie nicht das Pseudoelement :before (dies wird bereits benötigt, um eine andere unabhängige Sache zu erreichen),
  • verwenden Sie display: block/inline-block; nicht für das Inline-Element (da es hässliche Löcher im Textfluss erzeugt).
  • erlauben, die Breite der Elemente als Prozentsatz des enthaltenen Elements zu definieren (zumindest nach Anwendung der Dreierregel),
  • codieren Sie die obere Position/den Rand/das Auffüllen des :after- Pseudo-Elements nicht in einer Weise, die es von der Position des übergeordneten Elements innerhalb des übergeordneten Elements, der Höhe des übergeordneten Elements oder der tatsächlichen Höhe des Elements abhängig macht (oder um es kurz zu machen: machen Sie nichts vom Inhalt abhängig),
  • fügen Sie keine zusätzlichen HTML-Elemente ein
  • jS nicht hinzufügen.

Ich habe einen Codepen erstellt, der es hoffentlich einfacher macht zu verstehen, was ich hier vorhabe.

Ich weiß, dass es leicht möglich ist, zum Ergebnis zu gelangen, wenn eine der oben aufgeführten Einschränkungen verletzt wird (wie im Codepen gezeigt), aber ich suche nach einer eleganten Lösung für dieses Problem, wo dies nicht der Fall ist erforderlich.

Nachdem ich eine Weile damit herumgespielt habe, würde ich sagen, dass es nicht möglich ist, aber es wäre großartig, wenn mich jemand vom Gegenteil überzeugen könnte - oder zumindest formal beweist, dass es tatsächlich unmöglich ist. Vielen Dank für jede Hilfe im Voraus.

11
bfncs

Nun, die einzig mögliche Lösung mit der gewünschten Methode könnte dies sein.

- Damit dies funktioniert, müssen Sie zunächst ::aftercontentdirekt in CSS definieren, nicht über data-. (Ich weiß nicht warum, aber es scheint ein Parsing-Problem zu sein.)

- Setze position:relative auf .wrapper. Wenn Sie ::afterleft-right basierend auf dem übergeordneten Element (nicht dem direkten Element) verschieben möchten.

- Setze width: 100% auf ::after (100% der Eltern)

- Setze white-space: pre auf ::after - das ist wichtig

- Schreiben Sie die contentdirekt mit \A (Escape-Zeichen), um das Wort an bestimmten Stellen zu brechen.

- Setze top: 0 und gib ihm eine negative rightPosition (wie weit du willst)

Hinweis: Bei bestimmten Elementen muss möglicherweise Word-wrap: break-Word eingestellt werden, wenn der zusätzliche Text aus dem Wrapper herausläuft.

Grundsätzlich ist dies die Ergänzung/Modifikation für Ihr 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 */
}

Hinweis: Ich weiß nicht, wie gut diese Methode für responsive Designs ist, habe es aber noch nie so ausprobiert.

Getestet auf FF und Chrome.
Live-Beispiel

BEARBEITEN:
Hm, ja, ich habe mit ::after angefangen und dann versehentlich auf ::before gewechselt =)

Okay, kleinere Änderungen am CSS:

- Anstelle von width: 100% set width: auto

- Anstelle von top: 0 müssen Sie margin-top: -(number)px manuell (sorry) reduzieren. - Verwenden Sie nicht topname__, da dies die oberste Position basierend auf dem Wrapper selbst festlegt.

- right: -(number)% auf right: -(number)px umschalten

CSS Modifikation:

.accent::after{
    width: auto;
    right: -50px;
    margin-top: -40px;
    /* and remove "top" property completely */
}

Live-Beispiel

ANDERE BEARBEITUNG
Sauberere Arbeitslösung, in der Sie content: attr(data-meta) verwenden können (white-space: pre wurde entfernt und widthauf die gewünschte prozentuale Größe festgelegt:

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

Live-Beispiel

3
Davion

Mit diesen Anforderungen habe ich versucht:

  • verwenden Sie die Eigenschaft bottom [?] am Element ::after, oder
  • mit translateY [?] property

Zum Beispiel: 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
Giannis Grivas