Mehrzeiliger aufgepolsterter Text

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Dies ist eines dieser kniffligen CSS-Dinge, die mir alle paar Monate wieder begegnen. Ich schätze, wo könnte man es besser ansprechen als bei CSS-Tricks, oder?

Die Situation betrifft linksbündig umbrochenen Zeichensatz. Wie wenn ein Absatz Text in die nächste Zeile umbrochen wird, sobald das nächste Wort nicht mehr passt (d.h. die meisten Texte im Internet). Sie möchten einen Hintergrund hinter diesem Text hinzufügen, der

  1. Dem unregelmäßigen rechten Rand folgt
  2. Auf beiden Seiten, links und rechts, jeder Zeile gepolstert ist

Was Sie nicht tun können, ist einfach einen Hintergrund und Polsterung auf z.B. das <p> Element anzuwenden. Absätze sind Block-Level-Elemente, daher ist der Hintergrund einfach ein Rechteck und folgt nicht der linksbündigen Kante.

Sie können auch nicht einfach den Hintergrund und die Polsterung auf ein <span> oder ein Inline-Element anwenden. Die linke und rechte Polsterung gelten nur für die allererste und allerletzte Zeile. Auf jeder der mittleren Zeilen schließt der Hintergrund direkt an den Text an.

Das zu beschreiben ist ein wenig vergeblich. Hier ist das Problem visuell

Was wir wollen, ist, dass jede Zeile wie der Anfang der ersten Zeile und das Ende der letzten Zeile gepolstert ist. Wir wollen nichts Ekelerregendes wie das Umwickeln jeder Zeile in ihren eigenen Span (wo Zeilen umbrechen ist zu unvorhersehbar). Und es gibt leider kein :nth-line leider.

Es gibt jedoch einige Lösungen!

Harry Roberts Pseudo-Element / white-space Methode

Der große Trick hier ist die Verwendung von white-space: pre-wrap; Das gibt uns die Polsterung bei den linksbündigen Zeilen. Um die Polsterung links zu erhalten, wird ein Pseudo-Element am linken Rand hinzugefügt. Hier ist das Original und dann mein Fork, um die Elemente in Aktion zu zeigen

Siehe den Pen BtpGo von Chris Coyier (@chriscoyier) auf CodePen

Leider mag Firefox die Art und Weise nicht, wie das Pseudo-Element in dieser Technik positioniert ist. Wahrscheinlich behebbar, aber vielleicht gibt es einen besseren Weg...

Fabien Doirons Box-Shadow-Methode

Es stellt sich heraus, dass Sie eine Box-Shadow mit Null-Streckung auf einem Inline-Element nur auf der x-Achse verwenden können, um jede Zeile zu polstern. Im Wesentlichen

.padded-multi-line {
  display: inline;
  background: orange;
  box-shadow: 10px 0 0 orange, -10px 0 0 orange;
}

Hier ist das Original und dann mein Fork, um zu zeigen, wie es funktioniert

Siehe den Pen Wrapping Highlighted Text von Chris Coyier (@chriscoyier) auf CodePen

Hinweis: Ich musste diesen Code aktualisieren, als Firefox 32 veröffentlicht wurde. Firefox benötigt box-decoration-break: clone; da der Standardwert box-decoration-break: split; ist.

Dave Ruperts JavaScript / Unicode-Methode

Warnung: Dave sagt, benutzen Sie das nicht. Ich nehme es auf, weil ich es clever finde und es sich auf eine seltsame Weise für mich sogar weniger hacky anfühlt. Die Idee ist, den Text jedes Elements zu durchlaufen und die Leerzeichen durch das Unicode-Zeichen \u205f zu ersetzen, das MEDIUM MATHEMATICAL SPACE Zeichen. Das funktioniert aus irgendeinem Grund besser mit der Polsterung am rechten Rand. Für den linken Rand verwenden Sie einfach einen border-left am Block-Level-Elternelement.

Hier ist das Original und mein abgespeckter Fork

Siehe den Pen Wrapping Highlighted Text von Chris Coyier (@chriscoyier) auf CodePen

Es ist etwas knifflig, die Zeilenhöhe genau richtig einzustellen, damit der Rand mit der Polsterung übereinstimmt, aber ich bin sicher, Sie können das herausfinden. Es gibt wahrscheinlich sogar einige schicke Berechnungen, um sicherzustellen, dass es richtig ist.

Wenn JavaScript für Sie funktioniert, gibt es auch ein jQuery-Plugin wraplines, mit dem Sie dann die Polsterung auf jede einzelne Zeile anwenden können. Demo.

Matthew Pennells Dreielement-Methode

Es stellt sich heraus, dass Sie dies mit fast keiner ausgefallenen CSS oder JS tun können, sondern durch die Verwendung von drei Elementen. Sie benötigen ein Block-Level-Elternelement für einen linken Rand. Dann ein Inline-Element, um die Polsterung und den Hintergrund darauf anzuwenden. Dann ein weiteres Inline-Element, um den Text nach links zu schieben, um die Polsterung an den rechten Rändern zu erhalten.

<div class="padded-multiline">
  <h1>
    <strong>
      How do I add padding to subsequent lines of an inline text element?
    </strong>
  </h1>
</div>
.padded-multiline { 
  line-height: 1.3; 
  padding: 2px 0; 
  border-left: 20px solid #c0c;
  width: 400px;
  margin: 20px auto;
}
.padded-multiline h1 { 
  background-color: #c0c;
  padding: 4px 0;
  color: #fff; 
  display: inline;
  margin: 0; 
}
.padded-multiline h1 strong { 
  position: relative;
  left: -10px; 
}

Das Original befindet sich in diesem Thread und meine Demo

Siehe den Pen pvBFg von Chris Coyier (@chriscoyier) auf CodePen

Wenn Sie dies in Firefox betrachten, kann es zu einigen Zeilenhöhe-Problemen kommen. Ich habe im Grunde keine Ahnung, warum das so ist, es ist ziemlich frustrierend, besonders in solchen Situationen.

Adam Campbells box-decoration-break Methode

Während einer Diskussion, die sich um dieses Thema drehte, wies Adam darauf hin, dass es eine neue CSS-Eigenschaft gibt, die (soweit ich weiß) speziell dafür gedacht ist. Dies macht die Notwendigkeit von drei Elementen überflüssig. Technisch gesehen brauchen Sie nur eines, das Inline-Element, aber wahrscheinlich werden Sie dies bei einer Überschrift tun, so dass Sie am Ende wahrscheinlich trotzdem ein Block-Elternelement haben werden, was für die Abstände am besten ist.

Hier ist das Original und meine abgespeckte Demo

Siehe den Pen hIvFe von Chris Coyier (@chriscoyier) auf CodePen

Dies funktioniert in Chrome und Safari, aber nicht in Firefox funktioniert jetzt in Firefox 32+, in meinen schnellen Tests. Chrome und Safari benötigen dafür -webkit-box-decoration-break.

Vorherige Kunst

Die Personen, denen ich in diesem Artikel Credits gebe, waren die Personen, von denen ich die Technik zuerst gesehen habe. Aber sie repräsentieren nicht unbedingt die absolut erste Person, die jemals darauf gekommen ist™. In den Kommentaren unten kamen ein paar ältere Blogbeiträge auf, die sich mit demselben Problem befassten. Einer von Sergey Chikuyonok (Russisch) und einer von HTeuMeuLeu (Französisch).