Katakanlah saya memiliki beberapa kolom, yang beberapa di antaranya ingin saya putar nilainya:
<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>
Dengan CSS ini:
.statusColumn b {
writing-mode: tb-rl;
white-space: nowrap;
display: inline-block;
overflow: visible;
transform: rotate(-90deg);
transform-origin: 50% 50%;
}
Hasilnya akan terlihat seperti ini:
Apakah mungkin untuk menulis CSS yang akan menyebabkan elemen yang dirotasi memengaruhi tinggi induknya, sehingga teks tidak akan tumpang tindih dengan elemen lainnya? Sesuatu seperti ini:
css
css-transforms
Chris
sumber
sumber
writing-mode
adalah tersedia untuk sebagian besar browser, tapi mengerikan kereta. Atas pertanyaan terkait, saya melewati beberapa iterasi untuk mencoba mengatasi bug khusus browser sebelum menyerah; Anda dapat melihat suksesi kegagalan saya di stackoverflow.com/posts/47857248/revision , tempat saya memulai dengan sesuatu yang berfungsi di Chrome tetapi tidak di Firefox atau Edge, kemudian merusak Chrome dalam proses memperbaiki dua lainnya, dan akhirnya mengembalikan menjawab dan memberi label sebagai khusus Chrome. Berhati-hatilah, jika Anda ingin menempuh jalan ini. (Perhatikan juga bahwa ini tidak ada gunanya dengan elemen non-teks.)Jawaban:
Dengan asumsi Anda ingin memutar 90 derajat, hal ini dimungkinkan, bahkan untuk elemen non-teks - tetapi seperti banyak hal menarik lainnya di CSS, ini membutuhkan sedikit kecerdikan. Solusi saya juga secara teknis memanggil perilaku tidak terdefinisi sesuai dengan spesifikasi CSS 2 - jadi sementara saya telah menguji dan mengonfirmasi bahwa ini berfungsi di Chrome, Firefox, Safari, dan Edge, saya tidak dapat menjanjikan kepada Anda bahwa itu tidak akan rusak di masa mendatang rilis browser.
Jawaban singkat
Diberikan HTML seperti ini, dimana Anda ingin merotasi
.element-to-rotate
...... perkenalkan dua elemen pembungkus di sekitar elemen yang ingin Anda putar:
... lalu gunakan CSS berikut, untuk memutar berlawanan arah jarum jam (atau lihat komentar
transform
untuk cara mengubahnya menjadi rotasi searah jarum jam):Demo cuplikan tumpukan
Tampilkan cuplikan kode
Bagaimana cara kerjanya?
Kebingungan dalam menghadapi mantra yang saya gunakan di atas adalah wajar; ada banyak hal yang terjadi, dan keseluruhan strategi tidak langsung dan membutuhkan pengetahuan tentang CSS trivia untuk memahaminya. Mari kita bahas langkah demi langkah.
Inti dari masalah yang kita hadapi adalah bahwa transformasi yang diterapkan ke elemen menggunakan
transform
properti CSS -nya semuanya terjadi setelah tata letak dilakukan. Dengan kata lain, penggunaantransform
pada elemen sama sekali tidak mempengaruhi ukuran atau posisi induknya atau elemen lainnya. Sama sekali tidak ada cara untuk mengubah fakta tentang caratransform
kerja ini. Jadi, untuk membuat efek memutar elemen dan tinggi induknya mengikuti rotasi, kita perlu melakukan hal-hal berikut:.element-to-rotate
.element-to-rotate
seperti untuk melapisinya persis pada elemen dari langkah 1.Elemen dari langkah 1 harus
.rotation-wrapper-outer
. Tapi bagaimana kita bisa menyebabkan nya tinggi untuk menjadi sama dengan.element-to-rotate
's lebar ?Komponen kunci dalam strategi kami di sini adalah
padding: 50% 0
aktif.rotation-wrapper-inner
. Eksploitasi ini adalah detail eksentrik dari spesifikasi untukpadding
: padding persentase itu, bahkan untukpadding-top
danpadding-bottom
, selalu ditentukan sebagai persentase lebar wadah elemen . Ini memungkinkan kami untuk melakukan trik dua langkah berikut:display: table
pada.rotation-wrapper-outer
. Ini menyebabkannya memiliki lebar menyusut agar pas , yang berarti lebarnya akan diatur berdasarkan lebar intrinsik isinya - yaitu, berdasarkan lebar intrinsik.element-to-rotate
. (Pada mendukung browser, kita bisa mencapai hal ini lebih bersih denganwidth: max-content
, tetapi sebagai Desember 2017,max-content
yang masih belum didukung di Ujung .)height
of.rotation-wrapper-inner
ke 0, lalu mengatur paddingnya ke50% 0
(yaitu, 50% atas dan 50% bawah). Ini menyebabkannya mengambil ruang vertikal sama dengan 100% lebar induknya - yang, melalui trik di langkah 1, sama dengan lebarnya.element-to-rotate
.Selanjutnya, yang tersisa hanyalah melakukan rotasi dan pemosisian elemen turunan yang sebenarnya. Secara alami,
transform: rotate(-90deg)
melakukan rotasi; kita gunakantransform-origin: top left;
untuk menyebabkan rotasi terjadi di sekitar sudut kiri atas elemen yang diputar, yang membuat terjemahan selanjutnya lebih mudah untuk dipikirkan, karena ia meninggalkan elemen yang diputar tepat di atas tempat yang seharusnya digambar. Kita kemudian dapat menggunakantranslate(-100%)
untuk menyeret elemen ke bawah dengan jarak yang sama dengan lebar pra-rotasinya.Itu masih belum mendapatkan posisi yang benar, karena kita masih perlu mengimbangi untuk 50% padding atas
.rotation-wrapper-outer
. Kami mencapai itu dengan memastikan bahwa.element-to-rotate
hasdisplay: block
(sehingga margin akan bekerja dengan baik di atasnya) dan kemudian menerapkan -50%margin-top
- perhatikan bahwa persentase margin juga ditentukan relatif terhadap lebar elemen induk.Dan itu dia!
Mengapa ini tidak sepenuhnya sesuai dengan spesifikasi?
Karena berikut catatan dari definisi persentase paddings dan margin di spec (bolding mine):
Karena seluruh trik berputar di sekitar membuat bantalan elemen pembungkus bagian dalam menjadi relatif terhadap lebar wadahnya yang pada gilirannya bergantung pada lebar anaknya, kami mencapai kondisi ini dan menjalankan perilaku yang tidak ditentukan. Saat ini bekerja di semua 4 browser utama, meskipun - tidak seperti beberapa tweak yang tampaknya sesuai dengan spesifikasi untuk pendekatan yang saya coba, seperti mengubah
.rotation-wrapper-inner
menjadi saudara kandung.element-to-rotate
alih-alih orang tua.sumber
writing-mode
solusi akan menjadi pendekatan yang terbaik jika IE 11 tidak perlu didukung.Seperti yang ditunjukkan oleh komentar G-Cyr dengan benar, dukungan saat
writing-mode
ini lebih dari layak . Dikombinasikan dengan rotasi sederhana, Anda mendapatkan hasil yang Anda inginkan. Lihat contoh di bawah ini.sumber
writing-mode: vertical-lr; transform: rotate(180deg);
Sayangnya (?) Ini adalah cara kerjanya meskipun Anda memutar elemen Anda, ia masih memiliki lebar dan tinggi tertentu, yang tidak berubah setelah rotasi. Anda mengubahnya secara visual, tetapi tidak ada kotak pembungkus yang tidak terlihat yang mengubah ukurannya saat Anda memutar sesuatu.
Bayangkan memutarnya kurang dari 90 ° (misalnya
transform: rotate(45deg)
): Anda harus memasukkan kotak tak terlihat yang sekarang memiliki dimensi ambigu berdasarkan dimensi asli dari objek yang Anda putar dan nilai rotasi sebenarnya.Tiba-tiba, Anda tidak hanya memiliki
width
danheight
dari objek yang telah diputar, tetapi Anda juga memilikiwidth
danheight
dari "kotak tak terlihat" di sekitarnya. Bayangkan meminta lebar luar objek ini - apa yang akan dikembalikannya? Lebar benda, atau kotak baru kita? Bagaimana kita membedakan keduanya?Oleh karena itu, tidak ada CSS yang dapat Anda tulis untuk memperbaiki perilaku ini (atau harus saya katakan, "otomatiskan"). Tentu saja Anda dapat meningkatkan ukuran penampung induk Anda dengan tangan, atau menulis beberapa JavaScript untuk menanganinya.
(Untuk memperjelas, Anda dapat mencoba menggunakan
element.getBoundingClientRect
untuk mendapatkan persegi panjang yang disebutkan sebelumnya).Seperti yang dijelaskan dalam spesifikasi :
Ini berarti bahwa tidak ada perubahan yang akan dilakukan pada konten di sekitar objek yang Anda ubah, kecuali Anda melakukannya dengan tangan.
Satu-satunya hal yang diperhitungkan saat Anda mengubah objek adalah area luapan:
Lihat jsfiddle ini untuk mempelajari lebih lanjut.
Sebenarnya cukup bagus untuk membandingkan situasi ini dengan objek yang diimbangi menggunakan:
position: relative
- konten di sekitarnya tidak berubah, meskipun Anda sedang memindahkan objek ( contoh ).Jika Anda ingin menangani ini menggunakan JavaScript, lihat pertanyaan ini .
sumber
Gunakan persentase untuk
padding
dan elemen pseudo untuk mendorong konten. Di JSFiddle saya membiarkan elemen semu merah untuk menunjukkannya dan Anda harus mengkompensasi pergeseran teks tetapi saya pikir itulah cara yang harus dilakukan.http://jsfiddle.net/MTyFP/7/
Artikel tentang solusi ini dapat ditemukan di sini: http://kizu.ru/en/fun/rotated-text/
sumber
Silakan lihat versi terbaru di jawaban saya yang lain . Jawaban ini tidak lagi valid dan tidak berfungsi lagi. Saya akan meninggalkannya di sini karena alasan sejarah.
Pertanyaan ini sudah cukup lama, tetapi dengan dukungan saat ini untuk
.getBoundingClientRect()
objek dan nilainyawidth
sertaheight
nilainya, dalam kombinasi dengan kemampuan untuk menggunakan metode rapi ini bersama-samatransform
, saya pikir solusi saya harus disebutkan juga.Lihat aksinya di sini . (Diuji di Chrome 42, FF 33 & 37.)
getBoundingClientRect
menghitung lebar dan tinggi kotak aktual dari elemen. Sederhananya, kita dapat mengulang semua elemen dan menyetel min-heightnya ke tinggi kotak sebenarnya dari anak-anaknya.(Dengan beberapa modifikasi Anda dapat mengulang melalui anak-anak dan mencari tahu mana yang tertinggi dan mengatur tinggi induk ke anak tertinggi. Namun, saya memutuskan untuk membuat contoh lebih lugas. Anda juga dapat menambahkan bantalan induk ke tinggi jika Anda mau, atau Anda dapat menggunakan
box-sizing
nilai yang relevan di CSS.)Namun, perhatikan bahwa saya menambahkan
translate
dantransform-origin
ke CSS Anda untuk membuat pemosisian lebih fleksibel dan akurat.sumber
Saya tahu ini adalah posting lama tetapi saya menemukannya saat berjuang dengan masalah yang persis sama. Solusi yang berhasil untuk saya adalah metode "berteknologi rendah" yang agak kasar dengan hanya mengelilingi div yang saya putar 90deg dengan banyak
Mengetahui perkiraan lebar (yang menjadi tinggi setelah rotasi) div, saya dapat mengkompensasi perbedaan dengan menambahkan br di sekitar div ini sehingga konten di atas dan di bawah didorong sesuai.
sumber