90 derece döndürmek istediğinizi varsayarsak, bu, metin olmayan öğeler için bile mümkündür - ancak CSS'deki birçok ilginç şey gibi, biraz kurnazlık gerektirir. Çözümüm aynı zamanda teknik olarak CSS 2 spesifikasyonuna göre tanımlanmamış davranışa neden oluyor - bu yüzden Chrome, Firefox, Safari ve Edge'de çalıştığını test edip onaylarken, size gelecekte bozulmayacağına söz veremem tarayıcı sürümü.
Kısa cevap
Bunun gibi HTML verildiğinde, döndürmek istediğiniz yer .element-to-rotate
...
<div id="container">
<something class="element-to-rotate">bla bla bla</something>
</div>
... döndürmek istediğiniz öğenin etrafına iki sarmalayıcı öğe ekleyin:
<div id="container">
<div class="rotation-wrapper-outer">
<div class="rotation-wrapper-inner">
<something class="element-to-rotate">bla bla bla</something>
</div>
</div>
</div>
... ve ardından saat yönünün tersine döndürmek için aşağıdaki CSS'yi kullanın (veya transform
saat yönünde dönüşe çevirmenin bir yolu için açıklamaya bakın ):
.rotation-wrapper-outer {
display: table;
}
.rotation-wrapper-inner {
padding: 50% 0;
height: 0;
}
.element-to-rotate {
display: block;
transform-origin: top left;
/* Note: for a CLOCKWISE rotation, use the commented-out
transform instead of this one. */
transform: rotate(-90deg) translate(-100%);
/* transform: rotate(90deg) translate(0, -100%); */
margin-top: -50%;
/* Not vital, but possibly a good idea if the element you're rotating contains
text and you want a single long vertical line of text and the pre-rotation
width of your element is small enough that the text wraps: */
white-space: nowrap;
}
Yığın snippet demosu
p {
/* Tweak the visuals of the paragraphs for easier visualiation: */
background: pink;
margin: 1px 0;
border: 1px solid black;
}
.rotation-wrapper-outer {
display: table;
}
.rotation-wrapper-inner {
padding: 50% 0;
height: 0;
}
.element-to-rotate {
display: block;
transform-origin: top left;
/* Note: for a CLOCKWISE rotation, use the commented-out
transform instead of this one. */
transform: rotate(-90deg) translate(-100%);
/* transform: rotate(90deg) translate(0, -100%); */
margin-top: -50%;
/* Not vital, but possibly a good idea if the element you're rotating contains
text and you want a single long vertical line of text and the pre-rotation
width of your element is small enough that the text wraps: */
white-space: nowrap;
}
<div id="container">
<p>Some text</p>
<p>More text</p>
<div class="rotation-wrapper-outer">
<div class="rotation-wrapper-inner">
<p class="element-to-rotate">Some rotated text</p>
</div>
</div>
<p>Even more text</p>
<img src="https://i.stack.imgur.com/ih8Fj.png">
<div class="rotation-wrapper-outer">
<div class="rotation-wrapper-inner">
<img class="element-to-rotate" src="https://i.stack.imgur.com/ih8Fj.png">
</div>
</div>
<img src="https://i.stack.imgur.com/ih8Fj.png">
</div>
Bu nasıl çalışıyor?
Yukarıda kullandığım büyülü sözler karşısında kafa karışıklığı makul; Devam eden çok şey var ve genel strateji basit değil ve anlamak için biraz CSS trivia bilgisi gerekiyor. Adım adım ilerleyelim.
Karşılaştığımız sorunun özü, transform
CSS özelliğini kullanarak bir öğeye uygulanan dönüşümlerin hepsinin düzen gerçekleştikten sonra gerçekleşmesidir. Başka bir deyişle, transform
bir öğede kullanmak , üst öğesinin veya diğer öğelerin boyutunu veya konumunu hiçbir şekilde etkilemez. Nasıl transform
çalıştığına dair bu gerçeği değiştirmenin kesinlikle bir yolu yok . Bu nedenle, bir öğeyi döndürme etkisini yaratmak ve üst öğenin yüksekliğinin dönüşe uygun olmasını sağlamak için aşağıdakileri yapmamız gerekir:
- Her nasılsa , yüksekliği nesnenin genişliğine eşit olan başka bir öğe inşa edin.
.element-to-rotate
- Dönüşümümüzü,
.element-to-rotate
tam olarak 1. adımdaki öğenin üzerine gelecek şekilde yazın.
1. adımdaki öğe olacaktır .rotation-wrapper-outer
. Ama nasıl biz onun neden olabilir yüksekliği eşit olacak şekilde .element-to-rotate
'ın genişliği ?
Buradaki stratejimizin temel bileşeni padding: 50% 0
açık .rotation-wrapper-inner
. Bu istismar , spesifikasyonun eksantrik bir detayıdırpadding
: bu yüzde dolgular, padding-top
ve için bile padding-bottom
, her zaman öğenin kapsayıcısının genişliğinin yüzdeleri olarak tanımlanır . Bu, aşağıdaki iki adımlı numarayı gerçekleştirmemizi sağlar:
- Biz set
display: table
üzerinde .rotation-wrapper-outer
. Bu , sığdırmak için daralan genişliğe sahip olmasına neden olur ; bu, genişliğinin, içeriğinin iç genişliğine, yani iç genişliğine dayalı olarak ayarlanacağı anlamına gelir .element-to-rotate
. (Tarayıcıları destekleyerek, biz daha temiz olan bu elde edebiliriz width: max-content
, ancak Aralık 2017 tarihi itibariyle, max-content
olduğu hala Kenar desteklenmez .)
- Belirlenen
height
bir .rotation-wrapper-inner
daha sonra için doldurma ayarlamak, 0 50% 0
(olup,% 50 ve üst% 50 altında). Bu, üst öğesinin genişliğinin% 100'üne eşit dikey alanı kaplamasına neden olur - bu, 1. adımdaki hile ile genişliğine eşittir .element-to-rotate
.
Daha sonra, geriye kalan tek şey, alt öğenin gerçek dönüşünü ve konumlandırmasını gerçekleştirmektir. Doğal olarak transform: rotate(-90deg)
rotasyon yapar; transform-origin: top left;
Döndürmenin, döndürülen öğenin sol üst köşesi etrafında gerçekleşmesine neden olmak için kullanırız , bu, döndürülen öğeyi, aksi takdirde çizileceği yerin hemen üzerinde bıraktığı için, sonraki çevirmenin mantıklı olmasını kolaylaştırır. Daha sonra kullanabiliriztranslate(-100%)
, öğeyi dönüş öncesi genişliğine eşit bir mesafe kadar aşağı doğru sürüklemek için .
Bu hala konumlandırmayı tam olarak doğru yapmıyor, çünkü yine de% 50 üst dolgu için dengelememiz gerekiyor .rotation-wrapper-outer
. Bunu, .element-to-rotate
sahip display: block
olduğundan emin olarak (böylece kenar boşlukları üzerinde düzgün çalışacak) ve ardından margin-top
- % 50 uygulayarak başarırız - yüzde kenar boşluklarının da ana öğenin genişliğine göre tanımlandığını unutmayın .
Ve bu kadar!
Bu neden tamamen spesifikasyonlara uygun değil?
Spesifikasyondaki yüzde dolguları ve marjların tanımındaki aşağıdaki not nedeniyle (kalın benim):
Yüzde, 'padding-top' ve 'padding-bottom' için bile , oluşturulan kutunun içeren bloğunun genişliğine göre hesaplanır . İçeren bloğun genişliği bu elemana bağlıysa, ortaya çıkan düzen CSS 2.1'de tanımsızdır.
Tüm hile, iç sarma elemanının dolgusunun, daha sonra çocuğun genişliğine bağlı olan kabının genişliğine göre olmasını sağlamak etrafında döndüğü için, bu koşula ulaşıyor ve tanımsız davranışı çağırıyoruz. Şu anda 4 ana tarayıcının hepsinde çalışıyor - denediğim yaklaşım .rotation-wrapper-inner
için .element-to-rotate
, bir ebeveyn yerine kardeş olmak gibi, görünüşte spesifikasyonlara uygun bazı ince ayarların aksine .