Angenommen, ich habe einige Spalten, von denen einige die Werte von:
<div class="container">
<div class="statusColumn"><span>Normal</span></div>
<div class="statusColumn"><a>Normal</a></div>
<div class="statusColumn"><b>Rotated</b></div>
<div class="statusColumn"><abbr>Normal</abbr></div>
</div>
Mit diesem CSS:
.statusColumn b {
writing-mode: tb-rl;
white-space: nowrap;
display: inline-block;
overflow: visible;
transform: rotate(-90deg);
transform-origin: 50% 50%;
}
Am Ende sieht es so aus:
Ist es möglich, CSS zu schreiben, das bewirkt, dass das gedrehte Element die Höhe des übergeordneten Elements beeinflusst, sodass der Text die anderen Elemente nicht überlappt? Etwas wie das:
css
css-transforms
Chris
quelle
quelle
writing-mode
ist verfügbar für die meisten Browser, aber schrecklich fehlerhaft. Bei einer verwandten Frage habe ich mehrere Iterationen durchlaufen, in denen ich versucht habe, browserspezifische Fehler zu umgehen, bevor ich aufgegeben habe. Sie können meine Abfolge von Fehlern unter stackoverflow.com/posts/47857248/revisions sehen , wo ich mit etwas beginne , das in Chrome funktioniert, aber nicht in Firefox oder Edge, und dann Chrome bei der Behebung der beiden anderen Probleme kaputt mache und am Ende meine zurücksetze Beantworten und kennzeichnen Sie es als "Nur Chrome". Seien Sie vorsichtig, wenn Sie diesen Weg gehen möchten. (Beachten Sie auch, dass es für Nicht-Text-Elemente nicht von Nutzen ist.)Antworten:
Angenommen, Sie möchten um 90 Grad drehen, ist dies auch für Nicht-Text-Elemente möglich - aber wie viele interessante Dinge in CSS erfordert es ein wenig List. Meine Lösung ruft auch technisch undefiniertes Verhalten gemäß der CSS 2-Spezifikation auf. Während ich getestet und bestätigt habe, dass es in Chrome, Firefox, Safari und Edge funktioniert, kann ich Ihnen nicht versprechen, dass es in Zukunft nicht mehr funktioniert Browser-Release.
Kurze Antwort
Bei HTML wie diesem, wo Sie drehen möchten
.element-to-rotate
...... führen Sie zwei Wrapper-Elemente um das Element ein, das Sie drehen möchten:
... und verwenden Sie dann das folgende CSS, um gegen den Uhrzeigersinn zu drehen (oder lesen Sie im Kommentar aus
transform
, wie Sie es in eine Drehung im Uhrzeigersinn ändern können):Stack-Snippet-Demo
Code-Snippet anzeigen
Wie funktioniert das?
Verwirrung angesichts der Beschwörungsformeln, die ich oben verwendet habe, ist vernünftig; Es ist viel los, und die Gesamtstrategie ist nicht einfach und erfordert einige Kenntnisse der CSS-Trivia, um sie zu verstehen. Lassen Sie uns Schritt für Schritt durchgehen.
Der Kern des Gesichts Problem , das wir ist , dass Transformationen auf ein Element angewendet unter Verwendung seiner
transform
CSS - Eigenschaft alle geschehen , nachdem das Layout stattgefunden hat. Mit anderen Worten, die Verwendungtransform
eines Elements wirkt sich überhaupt nicht auf die Größe oder Position seines übergeordneten Elements oder anderer Elemente aus. Es gibt absolut keine Möglichkeit, diese Tatsache zu ändern, wie estransform
funktioniert. Um den Effekt des Drehens eines Elements zu erzielen und die Höhe seines Elternteils der Drehung zu entsprechen, müssen wir die folgenden Dinge tun:.element-to-rotate
.element-to-rotate
so auf, dass sie genau aus Schritt 1 auf das Element gelegt wird.Das Element aus Schritt 1 muss sein
.rotation-wrapper-outer
. Aber wie können wir veranlassen , seine Höhe gleich zu sein.element-to-rotate
‚s Breite ?Die Schlüsselkomponente unserer Strategie ist hier die
padding: 50% 0
auf.rotation-wrapper-inner
. Dieser Exploit ist ein exzentrisches Detail der Spezifikation fürpadding
: Diese prozentualen Auffüllungen, auch fürpadding-top
undpadding-bottom
, werden immer als Prozentsätze der Breite des Containers des Elements definiert . Dies ermöglicht es uns, den folgenden zweistufigen Trick auszuführen:display: table
auf.rotation-wrapper-outer
. Dies führt dazu, dass es eine Schrumpfbreite hat , was bedeutet, dass seine Breite basierend auf der intrinsischen Breite seines Inhalts festgelegt wird - dh basierend auf der intrinsischen Breite von.element-to-rotate
. (Bei der Unterstützung von Browsern könnten wir dies sauberer erreichenwidth: max-content
, aber ab Dezember 2017max-content
wird dies in Edge immer noch nicht unterstützt .)height
von.rotation-wrapper-inner
auf 0 und dann das Auffüllen auf50% 0
( dh 50% oben und 50% unten). Dies führt dazu, dass es einen vertikalen Raum einnimmt, der 100% der Breite seines übergeordneten Elements entspricht - was durch den Trick in Schritt 1 gleich der Breite von ist.element-to-rotate
.Als nächstes müssen nur noch die eigentliche Drehung und Positionierung des untergeordneten Elements durchgeführt werden. Natürlich
transform: rotate(-90deg)
macht die Rotation; Wir verwendentransform-origin: top left;
, um die Drehung um die obere linke Ecke des gedrehten Elements zu veranlassen, wodurch die nachfolgende Übersetzung leichter zu begründen ist, da das gedrehte Element direkt über der Stelle verbleibt, an der es sonst gezeichnet worden wäre. Wir können danntranslate(-100%)
das Element um einen Abstand nach unten ziehen, der seiner Vorrotationsbreite entspricht.Das bringt die Positionierung immer noch nicht ganz richtig, da wir immer noch die 50% ige obere Polsterung ausgleichen müssen
.rotation-wrapper-outer
. Dies erreichen wir, indem wir sicherstellen, dass dies der Fall.element-to-rotate
istdisplay: block
(damit die Ränder ordnungsgemäß funktionieren) und dann einen Wert von -50% anwenden.margin-top
Beachten Sie, dass die prozentualen Ränder auch relativ zur Breite des übergeordneten Elements definiert sind.Und das ist es!
Warum ist dies nicht vollständig spezifikationskonform?
Aufgrund des folgenden Hinweises aus der Definition der prozentualen Auffüllungen und Ränder in der Spezifikation (fettgedruckte Mine):
Da sich der gesamte Trick darum drehte, das Auffüllen des inneren Wrapper-Elements relativ zur Breite seines Containers zu machen, was wiederum von der Breite seines untergeordneten Elements abhängt, treffen wir diese Bedingung und rufen undefiniertes Verhalten auf. Derzeit funktioniert es jedoch in allen vier gängigen Browsern - im Gegensatz zu einigen scheinbar spezifikationskonformen Änderungen
.rotation-wrapper-inner
, die ich versucht habe, wie zum Beispiel ein Geschwister.element-to-rotate
anstelle eines Elternteils zu werden.quelle
writing-mode
Lösungen sind der beste Ansatz, wenn IE 11 nicht unterstützt werden muss.Wie der Kommentar von G-Cyr zu Recht hervorhebt, ist die derzeitige Unterstützung für
writing-mode
mehr als anständig . In Kombination mit einer einfachen Drehung erhalten Sie genau das gewünschte Ergebnis. Siehe das folgende Beispiel.quelle
writing-mode: vertical-lr; transform: rotate(180deg);
Leider (?) Ist es so, dass es funktioniert, obwohl Sie Ihr Element drehen, es hat immer noch eine bestimmte Breite und Höhe, die sich nach dem Drehen nicht ändert. Sie ändern es visuell, aber es gibt keine unsichtbare Verpackungsbox, die ihre Größe ändert, wenn Sie Dinge drehen.
Stellen Sie sich vor, Sie drehen es um weniger als 90 ° (z. B.
transform: rotate(45deg)
): Sie müssten eine solche unsichtbare Box einführen, die jetzt mehrdeutige Abmessungen aufweist, die auf den ursprünglichen Abmessungen des zu drehenden Objekts und dem tatsächlichen Drehwert basieren.Plötzlich haben Sie nicht nur das
width
undheight
des Objekts, das Sie gedreht haben, sondern auch daswidth
undheight
der "unsichtbaren Box" um sich herum. Stellen Sie sich vor, Sie fordern die äußere Breite dieses Objekts an - was würde es zurückgeben? Die Breite des Objekts oder unsere neue Box? Wie würden wir zwischen beiden unterscheiden?Daher gibt es kein CSS, das Sie schreiben können, um dieses Verhalten zu beheben (oder sollte ich sagen, "automatisieren"). Natürlich können Sie den übergeordneten Container von Hand vergrößern oder JavaScript schreiben, um dies zu handhaben.
(
element.getBoundingClientRect
Um ganz klar zu sein, können Sie versuchen , das zuvor erwähnte Rechteck zu erhalten).Wie in der Spezifikation beschrieben :
Dies bedeutet, dass keine Änderungen am Inhalt des zu transformierenden Objekts vorgenommen werden, es sei denn, Sie führen diese manuell aus.
Das einzige, was bei der Transformation Ihres Objekts berücksichtigt wird, ist der Überlaufbereich:
Sehen Sie diese jsfiddle, um mehr zu erfahren.
Es ist eigentlich ganz gut, diese Situation mit einem Objektversatz zu vergleichen, indem Sie:
position: relative
- den umgebenden Inhalt nicht ändern, obwohl Sie Ihr Objekt bewegen ( Beispiel ).Wenn Sie dies mit JavaScript behandeln möchten, werfen Sie einen Blick auf diese Frage.
quelle
Verwenden Sie Prozentsätze für
padding
und ein Pseudoelement, um den Inhalt zu verschieben. In der JSFiddle habe ich das Pseudoelement rot gelassen, um es anzuzeigen, und Sie müssen die Verschiebung des Textes kompensieren, aber ich denke, das ist der richtige Weg.http://jsfiddle.net/MTyFP/7/
Eine Beschreibung dieser Lösung finden Sie hier: http://kizu.ru/en/fun/rotated-text/
quelle
Bitte beachten Sie die aktualisierte Version in meiner anderen Antwort . Diese Antwort ist nicht mehr gültig und funktioniert einfach nicht mehr. Ich werde es aus historischen Gründen hier lassen.
Diese Frage ist ziemlich alt, aber mit der aktuellen Unterstützung für das
.getBoundingClientRect()
Objekt und seinewidth
undheight
Werte in Kombination mit der Fähigkeit, diese saubere Methode zusammen mit zu verwendentransform
, denke ich, dass meine Lösung auch erwähnt werden sollte.Sehen sie in Aktion hier . (Getestet in Chrome 42, FF 33 und 37.)
getBoundingClientRect
berechnet die tatsächliche Kastenbreite und -höhe des Elements. Ganz einfach können wir also alle Elemente durchlaufen und ihre Mindesthöhe auf die tatsächliche Kastenhöhe ihrer Kinder einstellen.(Mit einigen Änderungen können Sie die Kinder durchlaufen und herausfinden, welches das größte ist, und die Größe des Elternteils auf das größte Kind einstellen. Ich habe mich jedoch entschlossen, das Beispiel einfacher zu gestalten. Sie können auch das Polster des Elternteils zum hinzufügen Höhe, wenn Sie möchten, oder Sie können eine relevante verwenden
box-sizing
Wert in CSS verwenden.)Beachten Sie jedoch, dass ich Ihrem CSS ein
translate
und hinzugefügt habetransform-origin
, um die Positionierung flexibler und genauer zu gestalten.quelle
Ich weiß, dass es ein alter Beitrag ist, aber ich habe ihn gefunden, als ich mit genau dem gleichen Problem zu kämpfen hatte. Die Lösung, die für mich funktioniert, ist eine ziemlich grobe "Low-Tech" -Methode, bei der einfach die Div, die ich um 90 Grad drehe, mit viel umgeben wird
Wenn ich die ungefähre Breite (die nach der Drehung zur Höhe wird) von div kenne, kann ich den Unterschied ausgleichen, indem ich brs um dieses div hinzufüge, damit der Inhalt oben und unten entsprechend verschoben wird.
quelle