สมมติว่าคุณต้องการหมุน 90 องศาซึ่งเป็นไปได้แม้กระทั่งสำหรับองค์ประกอบที่ไม่ใช่ข้อความ แต่ก็เหมือนกับสิ่งที่น่าสนใจมากมายใน CSS ก็ต้องใช้ไหวพริบเล็กน้อย วิธีแก้ปัญหาของฉันยังเรียกใช้พฤติกรรมที่ไม่ได้กำหนดตามข้อกำหนดของ CSS 2 ในทางเทคนิคดังนั้นในขณะที่ฉันทดสอบและยืนยันว่าใช้งานได้ใน Chrome, Firefox, Safari และ Edge ฉันไม่สามารถสัญญากับคุณได้ว่ามันจะไม่พังในอนาคต การเปิดตัวเบราว์เซอร์
คำตอบสั้น ๆ
กำหนด HTML แบบนี้คุณต้องการหมุนตรงไหน.element-to-rotate
...
<div id="container">
<something class="element-to-rotate">bla bla bla</something>
</div>
... แนะนำองค์ประกอบกระดาษห่อสองชิ้นรอบ ๆ องค์ประกอบที่คุณต้องการหมุน:
<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>
... จากนั้นใช้ CSS ต่อไปนี้เพื่อหมุนทวนเข็มนาฬิกา (หรือดูความคิดเห็นtransform
สำหรับวิธีเปลี่ยนเป็นการหมุนตามเข็มนาฬิกา):
.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;
}
การสาธิตตัวอย่างข้อมูลสแต็ก
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>
วิธีนี้ทำงานอย่างไร?
ความสับสนเมื่อเผชิญกับคาถาที่ฉันใช้ข้างต้นนั้นสมเหตุสมผล มีหลายอย่างเกิดขึ้นและกลยุทธ์โดยรวมไม่ตรงไปตรงมาและต้องใช้ความรู้เกี่ยวกับ CSS เล็กน้อยเพื่อทำความเข้าใจ ผ่านมันไปทีละขั้นตอน
หลักของปัญหาที่เราเผชิญคือการเปลี่ยนแปลงที่นำไปใช้กับองค์ประกอบโดยใช้transform
คุณสมบัติ CSS ทั้งหมดเกิดขึ้นหลังจากที่มีการจัดวาง กล่าวอีกนัยหนึ่งคือการใช้transform
กับองค์ประกอบจะไม่มีผลต่อขนาดหรือตำแหน่งของพาเรนต์หรือองค์ประกอบอื่น ๆ เลย ไม่มีวิธีใดที่จะเปลี่ยนแปลงข้อเท็จจริงเกี่ยวกับวิธีการtransform
ทำงานนี้ได้อย่างแน่นอน ดังนั้นในการสร้างเอฟเฟกต์ของการหมุนองค์ประกอบและการมีความสูงของพาเรนต์ตามการหมุนเราจำเป็นต้องทำสิ่งต่อไปนี้:
- สร้างองค์ประกอบอื่นที่มีความสูงเท่ากับความกว้างของไฟล์
.element-to-rotate
- เขียนการแปลงของเรา
.element-to-rotate
เช่นเพื่อซ้อนทับบนองค์ประกอบจากขั้นตอนที่ 1
องค์ประกอบจากขั้นตอนที่ 1 .rotation-wrapper-outer
จะเป็น แต่วิธีการที่เราสามารถทำให้เกิดของความสูงให้เท่ากับ.element-to-rotate
's กว้าง ?
องค์ประกอบสำคัญในกลยุทธ์ของเราอยู่ที่นี่ในpadding: 50% 0
.rotation-wrapper-inner
การใช้ประโยชน์นี้เป็นรายละเอียดที่ผิดปกติของข้อมูลจำเพาะสำหรับpadding
: เปอร์เซ็นต์การพายเรือแม้กระทั่งสำหรับpadding-top
และpadding-bottom
จะถูกกำหนดเป็นเปอร์เซ็นต์ของความกว้างของคอนเทนเนอร์ขององค์ประกอบเสมอ สิ่งนี้ช่วยให้เราสามารถใช้เคล็ดลับสองขั้นตอนต่อไปนี้:
- เราตั้งอยู่บน
display: table
.rotation-wrapper-outer
นี่เป็นสาเหตุให้มีการหดตัวเพื่อให้พอดีกับความกว้างซึ่งหมายความว่าความกว้างของมันจะตั้งอยู่บนพื้นฐานของความกว้างที่แท้จริงของเนื้อหา - .element-to-rotate
นั่นคือขึ้นอยู่กับความกว้างที่แท้จริงของ (บนเบราว์เซอร์ที่สนับสนุนเราสามารถบรรลุนี้มากขึ้นอย่างหมดจดด้วยwidth: max-content
แต่ ณ เดือนธันวาคมปี 2017 max-content
จะยังคงไม่ได้รับการสนับสนุนในขอบ .)
- เราตั้งค่า
height
ของ.rotation-wrapper-inner
เป็น 0 จากนั้นตั้งค่า padding เพื่อ50% 0
(นั่นคือด้านบน 50% และ 50% ล่าง) นี้ทำให้เกิดการใช้พื้นที่แนวตั้งเท่ากับ 100% ของความกว้างของแม่ - ซึ่งผ่านเคล็ดลับในขั้นตอนที่ 1 .element-to-rotate
จะมีค่าเท่ากับความกว้างของ
ต่อไปสิ่งที่เหลืออยู่คือการหมุนและการวางตำแหน่งขององค์ประกอบลูกที่แท้จริง ตามธรรมชาติแล้วtransform: rotate(-90deg)
การหมุนจะทำ; เราใช้transform-origin: top left;
เพื่อทำให้การหมุนเกิดขึ้นรอบ ๆ มุมซ้ายบนขององค์ประกอบที่หมุนซึ่งทำให้การแปลในภายหลังนั้นง่ายขึ้นในการหาเหตุผลเนื่องจากจะปล่อยให้องค์ประกอบที่หมุนอยู่ด้านบนโดยตรงซึ่งจะถูกดึงออกมา จากนั้นเราสามารถใช้translate(-100%)
เพื่อลากองค์ประกอบลงด้านล่างโดยมีระยะทางเท่ากับความกว้างก่อนการหมุน
ที่ยังคงไม่ได้ค่อนข้างได้รับการวางตำแหน่งที่เหมาะสมเพราะเรายังคงต้องชดเชยสำหรับชั้น padding .rotation-wrapper-outer
50% เราประสบความสำเร็จที่โดยมั่นใจว่า.element-to-rotate
ได้display: block
(เพื่อให้อัตรากำไรขั้นต้นจะทำงานอย่างถูกต้องในนั้น) และจากนั้นใช้ -50% margin-top
- ทราบว่าอัตรากำไรขั้นต้นร้อยละจะยังกำหนดเทียบกับความกว้างขององค์ประกอบหลักที่
แค่นี้แหละ!
เหตุใดจึงไม่เป็นไปตามข้อกำหนดอย่างสมบูรณ์
เนื่องจากหมายเหตุต่อไปนี้จากคำจำกัดความของเปอร์เซ็นต์การพายและระยะขอบในข้อมูลจำเพาะ (ตัวหนาของฉัน):
เปอร์เซ็นต์ที่มีการคำนวณเกี่ยวกับความกว้างของสร้างกล่องที่มีบล็อกแม้สำหรับ'padding-top box'และ'ช่องว่างด้านล่าง' หากความกว้างของบล็อกที่มีขึ้นอยู่กับองค์ประกอบนี้เค้าโครงผลลัพธ์จะไม่ได้กำหนดไว้ใน CSS 2.1
เนื่องจากเคล็ดลับทั้งหมดวนเวียนอยู่กับการทำให้ส่วนขยายขององค์ประกอบ wrapper ด้านในสัมพันธ์กับความกว้างของคอนเทนเนอร์ซึ่งจะขึ้นอยู่กับความกว้างของลูกเราจึงเข้าสู่เงื่อนไขนี้และเรียกใช้พฤติกรรมที่ไม่ได้กำหนด ขณะนี้ใช้งานได้ในเบราว์เซอร์หลักทั้ง 4 เบราว์เซอร์ - ซึ่งแตกต่างจากการปรับแต่งตามข้อกำหนดบางอย่างที่ดูเหมือนว่าเป็นไปตามข้อกำหนดที่ฉันได้ลองใช้เช่นการเปลี่ยน.rotation-wrapper-inner
เป็นพี่น้อง.element-to-rotate
แทนผู้ปกครอง