เริ่มต้นใช้งานรูปร่าง CSS

การรวมเนื้อหารอบเส้นทางที่กำหนดเอง

เป็นเวลานานแล้วที่นักออกแบบเว็บต้องสร้างงานภายใต้ข้อจำกัดของสี่เหลี่ยมผืนผ้า เนื้อหาส่วนใหญ่บนเว็บยังคงอยู่ในกล่องสี่เหลี่ยมจัตุรัสธรรมดาๆ เนื่องจากครีเอทีฟโฆษณาส่วนใหญ่ที่ลองใช้เลย์เอาต์ที่ไม่ใช่สี่เหลี่ยมผืนผ้ามักจะจบลงด้วยความหงุดหงิด แต่สถานการณ์นี้กำลังจะเปลี่ยนไปด้วยการเปิดตัวรูปร่าง CSS ซึ่งพร้อมใช้งานใน Chrome 37 รูปร่าง CSS ช่วยให้นักออกแบบเว็บจัดวางเนื้อหารอบเส้นทางที่กำหนดเองได้ เช่น วงกลม วงรี และรูปหลายเหลี่ยม ซึ่งช่วยให้หลุดพ้นจากข้อจำกัดของสี่เหลี่ยมผืนผ้า

คุณกำหนดรูปร่างด้วยตนเองหรือจะอนุมานจากรูปภาพก็ได้

มาดูตัวอย่างง่ายๆ กัน

บางทีคุณอาจไร้เดียงสาเหมือนเราเมื่อลอยรูปภาพที่มีส่วนที่โปร่งใสเป็นครั้งแรกโดยคาดหวังว่าระบบจะตัดเนื้อหาให้พอดีและเติมเต็มช่องว่าง แต่กลับผิดหวังกับรูปร่างการตัดสี่เหลี่ยมผืนผ้าที่ยังคงอยู่รอบๆ องค์ประกอบ คุณใช้รูปร่าง CSS เพื่อแก้ปัญหานี้ได้

แยกรูปร่างออกจากรูปภาพ
<img class="element" src="image.png" />
<p>Lorem ipsum…</p>

<style>
.element{
  shape-outside: url(image.png);
  shape-image-threshold: 0.5;
  float: left;
}
</style>

การประกาศ CSS shape-outside: url(image.png) บอกให้เบราว์เซอร์ดึงรูปร่างออกจากรูปภาพ

พร็อพเพอร์ตี้ shape-image-threshold จะกำหนดระดับความทึบแสงขั้นต่ำของพิกเซลที่จะใช้สร้างรูปร่าง ค่าต้องอยู่ในช่วงระหว่าง 0.0 (โปร่งใสทั้งหมด) ถึง 1.0 (ทึบแสงทั้งหมด) ดังนั้น shape-image-threshold: 0.5 หมายความว่าระบบจะใช้เฉพาะพิกเซลที่มีความทึบ 50% ขึ้นไปเพื่อสร้างรูปร่าง

พร็อพเพอร์ตี้ float เป็นกุญแจสำคัญ แม้ว่าพร็อพเพอร์ตี้ shape-outside จะกำหนดรูปร่างของพื้นที่รอบๆ ที่จะตัดเนื้อหา แต่หากไม่มี float คุณจะไม่เห็นผลของรูปร่าง

องค์ประกอบมีพื้นที่ลอยอยู่ฝั่งตรงข้ามกับค่า float ตัวอย่างเช่น หากองค์ประกอบที่มีรูปภาพถ้วยกาแฟลอยไปทางซ้าย ระบบจะสร้างพื้นที่ลอยทางด้านขวาของถ้วย แม้ว่าคุณจะออกแบบรูปภาพให้มีช่องว่างทั้ง 2 ด้านได้ แต่เนื้อหาจะตัดขึ้นรูปตามรูปร่างที่ด้านตรงข้ามซึ่งระบุโดยพร็อพเพอร์ตี้ float เท่านั้น ไม่ว่าจะด้านซ้ายหรือขวา

ในอนาคต คุณจะใช้ shape-outside ในองค์ประกอบที่ไม่ได้ลอยได้ด้วยการเปิดตัวการยกเว้น CSS

การสร้างรูปร่างด้วยตนเอง

นอกจากการดึงรูปร่างจากรูปภาพแล้ว คุณยังเขียนโค้ดรูปร่างด้วยตนเองได้ด้วย คุณเลือกจากค่าฟังก์ชันต่อไปนี้เพื่อสร้างรูปร่างได้ circle(), ellipse(), inset() และ polygon() ฟังก์ชันรูปร่างแต่ละรายการจะยอมรับชุดพิกัดและจับคู่กับกล่องอ้างอิงซึ่งสร้างระบบพิกัด เราจะพูดถึงกล่องข้อมูลอ้างอิงเพิ่มเติมในอีกสักครู่

ฟังก์ชัน circle()

ภาพค่ารูปร่าง circle()

รูปแบบเต็มของค่ารูปร่างวงกลมคือ circle(r at cx cy) โดยที่ r คือรัศมีของวงกลม ส่วน cx และ cy คือพิกัดของจุดศูนย์กลางวงกลมบนแกน X และแกน Y พิกัดของจุดศูนย์กลางวงกลมเป็นตัวเลือกที่ไม่บังคับ หากไม่ระบุ ระบบจะใช้จุดศูนย์กลางขององค์ประกอบ (จุดตัดของเส้นทแยงมุม) เป็นค่าเริ่มต้น

.element{
  shape-outside: circle(50%);
  width: 300px;
  height: 300px;
  float: left;
}

ในตัวอย่างด้านบน เนื้อหาจะแสดงรอบๆ ขอบนอกของเส้นทางวงกลม อาร์กิวเมนต์เดี่ยว 50% จะระบุรัศมีของวงกลม ซึ่งในกรณีนี้จะมีค่าเท่ากับครึ่งหนึ่งของความกว้างหรือความสูงขององค์ประกอบ การเปลี่ยนแปลงขนาดขององค์ประกอบจะส่งผลต่อรัศมีของรูปร่างวงกลม นี่เป็นตัวอย่างพื้นฐานที่แสดงให้เห็นว่ารูปร่าง CSS สามารถตอบสนองได้อย่างไร

ก่อนไปต่อ โปรดทราบว่ารูปร่าง CSS จะส่งผลต่อรูปร่างของพื้นที่ลอยรอบองค์ประกอบเท่านั้น หากองค์ประกอบมีพื้นหลัง พื้นหลังจะไม่ถูกตัดโดยรูปร่าง หากต้องการใช้เอฟเฟกต์ดังกล่าว คุณต้องใช้พร็อพเพอร์ตี้จากการมาสก์ CSS ซึ่งก็คือ clip-path หรือ mask-image พร็อพเพอร์ตี้ clip-path มีประโยชน์มากเนื่องจากใช้เครื่องหมายเดียวกับรูปร่าง CSS คุณจึงนำค่ามาใช้ซ้ำได้

ภาพรูปร่าง `circle()` + clip-path

ภาพประกอบตลอดทั้งเอกสารนี้ใช้การครอบตัดเพื่อไฮไลต์รูปร่างและช่วยให้คุณเข้าใจเอฟเฟกต์

กลับไปที่รูปร่างวงกลม

เมื่อใช้เปอร์เซ็นต์เป็นรัศมีของวงกลม ระบบจะคํานวณค่าด้วยสูตรที่ซับซ้อนกว่าเล็กน้อย ซึ่งก็คือ sqrt(width^2 + height^2) / sqrt(2) การทําความเข้าใจเรื่องนี้มีประโยชน์เนื่องจากจะช่วยให้คุณจินตนาการได้ว่ารูปร่างของวงกลมที่ได้จะเป็นอย่างไรหากขนาดขององค์ประกอบไม่เท่ากัน

หน่วย CSS ทุกประเภทสามารถใช้ในพิกัดฟังก์ชันรูปร่างได้ เช่น px, em, rem, vw, vh และอื่นๆ คุณเลือกรูปแบบที่ยืดหยุ่นหรือเข้มงวดได้ตามต้องการ

คุณสามารถปรับตําแหน่งของวงกลมได้โดยกําหนดค่าที่ชัดเจนสําหรับพิกัดของจุดศูนย์กลาง

.element{
  shape-outside: circle(50% at 0 0);
}

ซึ่งจะวางตำแหน่งจุดศูนย์กลางของวงกลมไว้ที่จุดเริ่มต้นของระบบพิกัด ระบบพิกัดคืออะไร เราจึงขอแนะนำกล่องข้อมูลอ้างอิง

กล่องข้อมูลอ้างอิงสำหรับรูปร่าง CSS

กล่องอ้างอิงคือกล่องเสมือนรอบๆ องค์ประกอบ ซึ่งจะสร้างระบบพิกัดที่ใช้วาดและวางตำแหน่งรูปร่าง จุดเริ่มต้นของระบบพิกัดอยู่ที่มุมซ้ายบน โดยแกน X จะชี้ไปทางขวาและแกน Y จะชี้ลง

ระบบพิกัดสำหรับรูปร่าง CSS

โปรดทราบว่า shape-outside จะเปลี่ยนรูปร่างของพื้นที่ลอยรอบๆ ซึ่งเนื้อหาจะตัดขึ้นบรรทัดใหม่ พื้นที่ลอยจะขยายไปถึงขอบด้านนอกของกล่องที่กําหนดโดยพร็อพเพอร์ตี้ margin ซึ่งเรียกว่า margin-box และเป็นกล่องอ้างอิงเริ่มต้นของรูปร่างหากไม่มีการระบุไว้อย่างชัดเจน

การประกาศ CSS 2 รายการต่อไปนี้ให้ผลลัพธ์เหมือนกัน

.element{
  shape-outside: circle(50% at 0 0);
  /* identical to: */
  shape-outside: circle(50% at 0 0) margin-box;
}

เรายังไม่ได้ตั้งค่าระยะขอบในองค์ประกอบ ในตอนนี้ เราอาจถือว่าจุดเริ่มต้นของระบบพิกัดและจุดศูนย์กลางของวงกลมอยู่ที่มุมซ้ายบนของพื้นที่เนื้อหาขององค์ประกอบ การดำเนินการต่อไปนี้จะเปลี่ยนแปลงเมื่อคุณตั้งค่าระยะขอบ

.element{
  shape-outside: circle(50% at 0 0) margin-box;
  margin: 100px;
}

ตอนนี้จุดเริ่มต้นของระบบพิกัดอยู่นอกพื้นที่เนื้อหาขององค์ประกอบ (100 พิกเซลขึ้นและ 100 พิกเซลไปทางซ้าย) เช่นเดียวกับจุดศูนย์กลางของวงกลม ค่าที่คำนวณของรัศมีวงกลมจะเพิ่มขึ้นด้วยเพื่อพิจารณาถึงพื้นผิวที่เพิ่มขึ้นของระบบพิกัดที่กำหนดโดยmargin-boxกล่องอ้างอิง

ระบบพิกัดกล่องที่มีและไม่มีระยะขอบ
มีตัวเลือกกล่องอ้างอิง 2-3 รายการให้เลือก ได้แก่ `margin-box`, `border-box`, `padding-box` และ `content-box` ชื่อของตัวเลือกเหล่านี้บอกถึงขอบเขตของตัวเลือก ก่อนหน้านี้เราได้อธิบายเกี่ยวกับ `margin-box` แล้ว ส่วน `border-box` ถูกจำกัดโดยขอบด้านนอกของเส้นขอบองค์ประกอบ ส่วน `padding-box` ถูกจำกัดโดยระยะห่างจากขอบขององค์ประกอบ ส่วน `content-box` จะเหมือนกับพื้นที่ผิวจริงที่เนื้อหาภายในองค์ประกอบใช้
ภาพกล่องข้อมูลอ้างอิงทั้งหมด

คุณใช้กล่องข้อมูลอ้างอิงได้เพียง 1 กล่องในแต่ละครั้งพร้อมกับประกาศ shape-outside กล่องอ้างอิงแต่ละกล่องจะส่งผลต่อรูปร่างในลักษณะที่แตกต่างกันและบางครั้งก็แทบมองไม่เห็น มีบทความอีกบทความหนึ่งที่เจาะลึกและช่วยให้คุณเข้าใจกล่องอ้างอิงสำหรับรูปร่าง CSS

ฟังก์ชัน ellipse()

ภาพค่ารูปร่าง ellipse()

วงรีมีลักษณะคล้ายวงกลมที่ถูกบีบ ซึ่งกำหนดเป็น ellipse(rx ry at cx cy) โดยที่ rx และ ry คือรัศมีของวงรีบนแกน X และแกน Y ส่วน cx และ cy คือพิกัดของจุดศูนย์กลางของวงรี

.element{
  shape-outside: ellipse(150px 300px at 50% 50%);
  width: 300px;
  height: 600px;
}

ระบบจะคํานวณค่าเปอร์เซ็นต์จากมิติข้อมูลของระบบพิกัด ไม่ต้องคำนวณอะไรให้ยุ่งยาก คุณละเว้นพิกัดของจุดศูนย์กลางของรูปไข่ได้ ระบบจะอนุมานพิกัดจากจุดศูนย์กลางของระบบพิกัด

คุณยังกำหนดรัศมีบนแกน X และ Y ด้วยคีย์เวิร์ดได้ด้วย โดย farthest-side จะให้รัศมีเท่ากับระยะทางระหว่างจุดศูนย์กลางของรูปไข่กับด้านของกล่องอ้างอิงที่ไกลที่สุดจากจุดศูนย์กลาง ส่วน closest-side หมายความว่าให้ใช้ระยะทางที่สั้นที่สุดระหว่างจุดศูนย์กลางกับด้าน

.element{
  shape-outside: ellipse(closest-side farthest-side at 50% 50%);
  /* identical to: */
  shape-outside: ellipse(150px 300px at 50% 50%);
  width: 300px;
  height: 600px;
}

ซึ่งอาจมีประโยชน์เมื่อขนาดขององค์ประกอบ (หรือกล่องอ้างอิง) อาจเปลี่ยนแปลงในลักษณะที่คาดเดาไม่ได้ แต่คุณต้องการให้รูปร่างรูปไข่ปรับเปลี่ยน

นอกจากนี้ คุณยังใช้คีย์เวิร์ด farthest-side และ closest-side เดียวกันกับรัศมีในฟังก์ชันรูปร่าง circle() ได้ด้วย

ฟังก์ชัน polygon()

ภาพค่ารูปร่าง polygon()

หากวงกลมและวงรีมีข้อจำกัดมากเกินไป ฟังก์ชันรูปร่างรูปหลายเหลี่ยมจะเปิดโลกแห่งตัวเลือกให้คุณ รูปแบบคือ polygon(x1 y1, x2 y2, ...) ซึ่งคุณระบุคู่พิกัด x y สําหรับจุดยอด (จุด) แต่ละจุดของรูปหลายเหลี่ยม จำนวนคู่ขั้นต่ำในการระบุรูปหลายเหลี่ยมคือ 3 คู่ ซึ่งเป็นรูปสามเหลี่ยม

.element{
  shape-outside: polygon(0 0, 0 300px, 300px 600px);
  width: 300px;
  height: 600px;
}

วางจุดยอดในระบบพิกัด สำหรับรูปหลายเหลี่ยมที่ปรับขนาดได้ คุณสามารถใช้ค่าเปอร์เซ็นต์สำหรับพิกัดบางส่วนหรือทั้งหมด

.element{
  /* polygon responsive to font-size*/
  shape-outside: polygon(0 0, 0 100%, 100% 100%);
  width: 20em;
  height: 40em;
}

พารามิเตอร์ fill-rule (ไม่บังคับ) ซึ่งนําเข้าจาก SVG จะบอกวิธีการพิจารณา "ความอยู่ภายใน" ของรูปหลายเหลี่ยมในกรณีที่มีเส้นทางที่ตัดกันเองหรือรูปร่างที่ปิดล้อม Joni Trythall อธิบายวิธีการทำงานของพร็อพเพอร์ตี้ fill-rule ใน SVG ได้อย่างดีมาก หากไม่ได้กําหนด fill-rule จะมีค่าเริ่มต้นเป็น nonzero

.element{
  shape-outside: polygon(0 0, 0 100%, 100% 100%);
  /* identical to: */
  shape-outside: polygon(nonzero, 0 0, 0 100%, 100% 100%);
}

ฟังก์ชัน inset()

ฟังก์ชันรูปร่าง inset() ช่วยให้คุณสร้างรูปร่างสี่เหลี่ยมผืนผ้าเพื่อตัดเนื้อหาได้ เรื่องนี้อาจฟังดูขัดแย้งกับหลักการเริ่มต้นที่ว่า CSS Shapes ช่วยสร้างเนื้อหาเว็บที่อิสระจากกล่องธรรมดา อาจเป็นเช่นนั้น เรายังไม่พบกรณีการใช้งานของ inset() ที่ทำได้โดยใช้การลอยและระยะขอบหรือ polygon() อยู่แล้ว แม้ว่า inset() จะให้นิพจน์ที่อ่านง่ายกว่าสำหรับรูปร่างสี่เหลี่ยมผืนผ้ากว่า polygon()

โน้ตเต็มสำหรับฟังก์ชันรูปร่างที่ฝังคือ inset(top right bottom left border-radius) อาร์กิวเมนต์ตำแหน่ง 4 รายการแรกคือระยะห่างที่เลื่อนเข้ามาจากขอบขององค์ประกอบ อาร์กิวเมนต์สุดท้ายคือรัศมีเส้นขอบของรูปสี่เหลี่ยมผืนผ้า ข้อมูลนี้ไม่บังคับ คุณจึงไม่ต้องใส่ก็ได้ โดยเป็นไปตามเครื่องหมายย่อ border-radius ที่คุณใช้อยู่แล้วใน CSS

.element{
  shape-outside: inset(100px 100px 100px 100px);
  /* yields a rectangular shape which is 100px inset on all sides */
  float: left;
}

การสร้างรูปร่างจากกล่องอ้างอิง

หากไม่ได้ระบุฟังก์ชันรูปร่างให้กับพร็อพเพอร์ตี้ shape-outside คุณสามารถอนุญาตให้เบราว์เซอร์ดึงข้อมูลรูปร่างจากช่องอ้างอิงขององค์ประกอบได้ กล่องอ้างอิงเริ่มต้นคือ margin-box ไม่มีอะไรแปลกใหม่ ฟลอยท์ก็ทำงานแบบนี้อยู่แล้ว แต่การใช้เทคนิคนี้จะช่วยให้คุณนําเรขาคณิตขององค์ประกอบมาใช้ซ้ำได้ มาดูพร็อพเพอร์ตี้ border-radius

หากใช้เพื่อปัดมุมขององค์ประกอบที่ลอย คุณจะได้รับเอฟเฟกต์การตัด แต่พื้นที่ลอยจะยังคงเป็นรูปสี่เหลี่ยมผืนผ้า เพิ่ม shape-outside: border-box เพื่อตัดรอบรูปทรงที่ border-radius สร้างขึ้น

ดึงข้อมูลรูปร่างจาก border-radius ขององค์ประกอบโดยใช้กล่องอ้างอิง border-box
.element{
  border-radius: 50%;
  shape-outside: border-box;
  float: left;
}

แน่นอนว่าคุณใช้กล่องข้อมูลอ้างอิงทั้งหมดในลักษณะนี้ได้ การใช้รูปร่างที่ดึงข้อมูลอีกอย่างหนึ่งคือข้อความไฮไลต์ที่ตัดออกจากเนื้อหา

การสร้างข้อความไฮไลต์แบบออฟเซตโดยใช้ช่องข้อมูลอ้างอิงกล่องเนื้อหา

คุณสามารถสร้างเอฟเฟกต์ข้อความไฮไลต์แบบออฟเซตได้โดยใช้เฉพาะพร็อพเพอร์ตี้ float และ margin แต่คุณจะต้องวางองค์ประกอบคำพูดในโครงสร้าง HTML ที่จุดที่ต้องการให้แสดงผล

วิธีสร้างเอฟเฟกต์ข้อความไฮไลต์แบบออฟเซตแบบเดียวกันแต่มีความยืดหยุ่นมากขึ้นมีดังนี้

.pull-quote{
  shape-outside: content-box;
  margin-top: 200px;
  float: left;
}

เราตั้งค่าช่องอ้างอิง content-box สำหรับระบบพิกัดของรูปร่างอย่างชัดเจน ในกรณีนี้ ปริมาณเนื้อหาในข้อความไฮไลต์จะเป็นตัวกำหนดรูปร่างของเนื้อหาภายนอกที่จะตัดขึ้นบรรทัดใหม่ ระบบใช้พร็อพเพอร์ตี้ margin-top ที่นี่เพื่อกำหนดตำแหน่ง (ออฟเซต) ข้อความไฮไลต์ โดยไม่คำนึงถึงตำแหน่งในต้นไม้ HTML

ระยะขอบของรูปร่าง

คุณจะเห็นว่าการตัดเนื้อหาให้อยู่รอบๆ รูปร่างอาจทำให้เนื้อหาแนบชิดกับองค์ประกอบมากเกินไป คุณเพิ่มระยะห่างรอบๆ รูปร่างได้ด้วยพร็อพเพอร์ตี้ shape-margin

.element{
  shape-outside: circle(40%);
  shape-margin: 1em;
  float: left;
}

ผลที่ได้จะคล้ายกับที่คุณคุ้นเคยจากการใช้พร็อพเพอร์ตี้ margin ปกติ แต่ shape-margin จะส่งผลต่อเฉพาะพื้นที่รอบๆ ค่า shape-outside เท่านั้น ระบบจะเพิ่มระยะห่างรอบๆ รูปร่างก็ต่อเมื่อมีที่ว่างสำหรับระยะห่างนั้นในระบบพิกัดเท่านั้น ด้วยเหตุนี้ ในตัวอย่างด้านบนจึงมีการกําหนดรัศมีของวงกลมเป็น 40% ไม่ใช่ 50% หากกำหนดรัศมีเป็น 50% วงกลมจะกินพื้นที่ทั้งหมดในระบบพิกัด โดยไม่มีพื้นที่เหลือสำหรับเอฟเฟกต์ของ shape-margin โปรดทราบว่ารูปร่างจะจำกัดอยู่ใน margin-box ขององค์ประกอบ (องค์ประกอบบวก margin-box รอบๆ) หากรูปร่างมีขนาดใหญ่กว่าและล้นออกมา ระบบจะตัดรูปร่างให้อยู่ใน margin-box และคุณจะเห็นรูปร่างสี่เหลี่ยมผืนผ้าmargin

โปรดทราบว่า shape-margin ยอมรับเฉพาะค่าบวกค่าเดียว โดยไม่มีเครื่องหมายแทนการเขียนแบบเต็ม shape-margin-top สำหรับวงกลมคืออะไร

การทำรูปทรงเคลื่อนไหว

คุณผสมรูปร่าง CSS เข้ากับฟีเจอร์ CSS อื่นๆ อีกมากมายได้ เช่น การเปลี่ยนและภาพเคลื่อนไหว อย่างไรก็ตาม เราขอเน้นย้ำว่าผู้ใช้รู้สึกรำคาญมากเมื่อเลย์เอาต์ข้อความเปลี่ยนแปลงขณะที่อ่าน โปรดให้ความสำคัญกับประสบการณ์การใช้งานหากคุณตัดสินใจที่จะใช้รูปร่างที่มีภาพเคลื่อนไหว

คุณทำให้รัศมีและจุดศูนย์กลางของรูปร่าง circle() และ ellipse() เคลื่อนไหวได้ ตราบใดที่กําหนดค่าไว้ในรูปแบบที่เบราว์เซอร์สามารถหาค่าเฉลี่ยระหว่างได้ เดินทางจาก circle(30%) ไป circle(50%) ได้ อย่างไรก็ตาม การแสดงภาพเคลื่อนไหวระหว่าง circle(closest-side) ถึง circle(farthest-side) จะทําให้เบราว์เซอร์ทำงานช้า

.element{
  shape-outside: circle(30%);
  transition: shape-outside 1s;
  float: left;
}

.element:hover{
  shape-outside: circle(50%);
}
GIF ของวงกลมแบบเคลื่อนไหว

คุณสามารถสร้างเอฟเฟกต์ที่น่าสนใจยิ่งขึ้นได้เมื่อทำให้รูปร่าง polygon() เคลื่อนไหว โดยข้อควรทราบที่สำคัญคือรูปหลายเหลี่ยมต้องมีจุดยอดเท่ากันระหว่างสถานะภาพเคลื่อนไหว 2 สถานะ เบราว์เซอร์จะไม่สามารถหาค่าเฉลี่ยระหว่างจุดยอดได้หากคุณเพิ่มหรือนำจุดยอดออก

เคล็ดลับอย่างหนึ่งคือเพิ่มจำนวนจุดยอดสูงสุดที่ต้องการ แล้วจัดวางจุดยอดเหล่านั้นไว้ด้วยกันในสถานะภาพเคลื่อนไหวที่ต้องการให้รูปร่างมีขอบน้อยลง

.element{
  /* four vertices (looks like rectangle) */
  shape-outside: polygon(0 0, 100% 0, 100% 100%, 0 100%);
  transition: shape-outside 1s;
}

.element:hover{
  /* four vertices, but second and third overlap (looks like triangle) */
  shape-outside: polygon(0 0, 100% 50%, 100% 50%, 0 100%);
}
GIF ของสามเหลี่ยมที่เคลื่อนไหว

การรวมเนื้อหาภายในรูปทรง

ภาพหน้าจอของตัวอย่าง Alice in Wonderland ที่ใช้รูปร่าง CSS เพื่อตัดเนื้อหา

ฉบับร่างแรกของข้อกำหนดเกี่ยวกับรูปร่าง CSS มีพร็อพเพอร์ตี้ shape-inside ซึ่งช่วยให้คุณตัดเนื้อหาภายในรูปร่างได้ แม้แต่ใน Chrome และ Webkit ก็มีการใช้งานอยู่ช่วงหนึ่ง แต่การรวมเนื้อหาที่วางไว้อย่างไม่มีเหตุผลภายในเส้นทางที่กำหนดเองนั้นต้องใช้ความพยายามและการวิจัยมากกว่ามากเพื่อให้ครอบคลุมสถานการณ์ที่เป็นไปได้ทั้งหมดและหลีกเลี่ยงข้อบกพร่อง ด้วยเหตุนี้ เราจึงเลื่อนการใช้พร็อพเพอร์ตี้ shape-inside ไปใช้รูปร่าง CSS ระดับ 2 และยกเลิกการใช้งานพร็อพเพอร์ตี้ดังกล่าว

อย่างไรก็ตาม คุณยังคงสร้างเอฟเฟกต์การตัดเนื้อหาให้พอดีภายในรูปร่างที่กำหนดเองได้ด้วยการพยายามและประนีประนอมบ้าง เคล็ดลับคือการใช้องค์ประกอบที่ลอยอยู่ 2 รายการที่มี shape-outside ซึ่งวางไว้ที่ด้านตรงข้ามของคอนเทนเนอร์ ข้อเสียคือคุณต้องใช้องค์ประกอบว่าง 1-2 รายการที่ไม่มีความหมายเชิงความหมาย แต่ทำหน้าที่เป็นโครงเพื่อสร้างภาพลวงตาของรูปทรงภายใน

<div>
  <div class='left-shape'></div>
  <div class='right-shape'></div>

  Lorem ipsum...
</div>

ตำแหน่งขององค์ประกอบ Strut .left-shape และ .right-shape ที่ด้านบนของคอนเทนเนอร์มีความสำคัญเนื่องจากองค์ประกอบเหล่านี้จะลอยไปทางซ้ายและขวาเพื่อขนาบข้างเนื้อหา

.left-shape{
  shape-outside: polygon(0 0, ...);
  float: left;
  width: 50%;
  height: 100%;
}

.right-shape{
  shape-outside: polygon(50% 0, ...);
  float: right;
  width: 50%;
  height: 100%;
}
ภาพแสดงวิธีแก้ปัญหาสำหรับ shape-inside ในการสาธิต Alice

การจัดสไตล์นี้ทําให้ Strut ที่ลอยอยู่ 2 รายการใช้พื้นที่ทั้งหมดภายในองค์ประกอบ แต่พร็อพเพอร์ตี้ shape-outside จะจัดสรรพื้นที่สําหรับเนื้อหาที่เหลือ

หากเบราว์เซอร์ไม่รองรับรูปร่าง CSS ผลลัพธ์ที่ได้จะดูไม่สวยงามเนื่องจากระบบจะดันเนื้อหาทั้งหมดลง คุณจึงควรใช้ฟีเจอร์นี้ในลักษณะที่ปรับปรุงอย่างต่อเนื่อง

ในตัวอย่างภาพเคลื่อนไหวของรูปร่างก่อนหน้านี้ คุณจะเห็นได้ว่าข้อความที่เลื่อนไปมาอาจสร้างความรำคาญ Use Case บางรายการไม่จำเป็นต้องใช้รูปร่างที่เคลื่อนไหว แต่คุณสามารถทำให้พร็อพเพอร์ตี้อื่นๆ เคลื่อนไหวซึ่งโต้ตอบกับรูปร่าง CSS เพื่อเพิ่มเอฟเฟกต์ตามความเหมาะสมได้

ในการแสดงตัวอย่างรูปร่าง CSS ของ Alice in Wonderland เราใช้ตําแหน่งการเลื่อนเพื่อเปลี่ยนระยะขอบด้านบนของเนื้อหา ข้อความถูกบีบอัดระหว่างองค์ประกอบที่ลอยอยู่ 2 รายการ เมื่อเลื่อนลง องค์ประกอบต้องจัดเรียงใหม่ตาม shape-outside ขององค์ประกอบที่ลอยอยู่ 2 รายการ วิธีนี้ทำให้ดูเหมือนว่าข้อความกำลังตกลงไปในโพรงกระต่ายและช่วยเพิ่มประสบการณ์การเล่าเรื่อง เนื้อหาที่เสี่ยงต่อการละเมิดหรือไม่ อาจจะได้ แต่ดูเท่ดี

เนื่องจากเบราว์เซอร์จะจัดวางเลย์เอาต์ข้อความเอง ประสิทธิภาพจึงดีกว่าการใช้โซลูชัน JavaScript แต่การเปลี่ยน margin-top เมื่อมีการเลื่อนจะทริกเกอร์เหตุการณ์การจัดเรียงใหม่และการวาดภาพจำนวนมาก ซึ่งอาจทำให้ประสิทธิภาพลดลงอย่างเห็นได้ชัด โปรดใช้ด้วยความระมัดระวัง อย่างไรก็ตาม การใช้รูปร่าง CSS โดยไม่ให้มีภาพเคลื่อนไหวจะไม่ส่งผลต่อประสิทธิภาพที่สังเกตได้

การเพิ่มประสิทธิภาพแบบต่อเนื่อง

เริ่มต้นด้วยการสมมติว่าเบราว์เซอร์ไม่รองรับรูปร่าง CSS แล้วค่อยพัฒนาต่อเมื่อตรวจพบฟีเจอร์ดังกล่าว Modernizr เป็นโซลูชันที่ยอดเยี่ยมในการตรวจหาฟีเจอร์ และมีชุดทดสอบสำหรับรูปร่าง CSS ในส่วน"การตรวจหาที่ไม่ใช่ส่วนสําคัญ"

บางเบราว์เซอร์มีการตรวจหาฟีเจอร์ใน CSS ผ่านกฎ @supports โดยไม่จำเป็นต้องใช้ไลบรารีภายนอก Google Chrome ซึ่งรองรับรูปร่าง CSS ด้วยจะเข้าใจกฎ @supports วิธีใช้เพื่อเพิ่มประสิทธิภาพแบบเป็นขั้นๆ มีดังนี้

.element{
  /* styles for all browsers */
}

@supports (shape-outside: circle(50%)){
  /* styles only for browsers which support CSS Shapes */
  .element{
    shape-outside: circle(50%);
  }
}

Lea Verou ได้เขียนเพิ่มเติมเกี่ยวกับวิธีใช้กฎ @supports ของ CSS

การตีความที่ชัดเจนจากการยกเว้น CSS

สิ่งที่เราเรียกว่ารูปร่าง CSS ในปัจจุบันเคยเรียกว่าการยกเว้นและรูปร่าง CSS ในช่วงแรกๆ ของสเปค การเปลี่ยนไปใช้ชื่อใหม่อาจดูไม่สำคัญเท่าไหร่ แต่จริงๆ แล้วสำคัญมาก การยกเว้น CSS ซึ่งตอนนี้เป็นข้อกำหนดแยกต่างหาก ช่วยให้คุณตัดเนื้อหารอบองค์ประกอบที่วางตำแหน่งแบบกำหนดเองได้โดยไม่ต้องใช้พร็อพเพอร์ตี้ float ลองจินตนาการถึงการตัดเนื้อหารอบๆ องค์ประกอบที่มีตำแหน่งสัมบูรณ์ นั่นคือกรณีการใช้งานสำหรับการยกเว้น CSS รูปร่าง CSS จะกำหนดเส้นทางที่เนื้อหาจะตัดขึ้นบรรทัดใหม่

ดังนั้น รูปร่างและการยกเว้นจึงไม่ใช่สิ่งเดียวกัน แต่ช่วยเสริมกันและกัน รูปร่าง CSS พร้อมใช้งานในเบราว์เซอร์แล้วในปัจจุบัน แต่การยกเว้น CSS ยังไม่พร้อมใช้งานกับการโต้ตอบของรูปร่าง

เครื่องมือสำหรับทำงานกับรูปร่าง CSS

คุณสร้างเส้นทางในเครื่องมือสร้างรูปภาพแบบคลาสสิกได้ แต่ ณ เวลาที่เขียนนี้ ไม่มีเครื่องมือใดส่งออกไวยากรณ์ที่จำเป็นสำหรับค่ารูปร่าง CSS แม้ว่าจะมี แต่การทำงานแบบนั้นก็คงไม่เป็นจริงมากนัก

รูปร่าง CSS มีไว้เพื่อใช้ในเบราว์เซอร์ ซึ่งจะโต้ตอบกับองค์ประกอบอื่นๆ ในหน้า ฟีเจอร์นี้มีประโยชน์มากในการดูภาพผลลัพธ์ของการตัดต่อรูปร่างบนเนื้อหาที่อยู่รอบๆ เครื่องมือที่จะช่วยคุณในเวิร์กโฟลว์นี้มีดังนี้

Brackets: ส่วนขยายเครื่องมือแก้ไขรูปร่าง CSS สำหรับ Brackets ใช้โหมดแสดงตัวอย่างแบบเรียลไทม์ของตัวแก้ไขโค้ดเพื่อวางซ้อนเครื่องมือแก้ไขแบบอินเทอร์แอกทีฟสำหรับการแก้ไขค่ารูปร่าง

Google Chrome: ส่วนขยายเครื่องมือแก้ไขรูปร่าง CSS สำหรับ Google Chrome ขยายเครื่องมือสําหรับนักพัฒนาซอฟต์แวร์ของเบราว์เซอร์ด้วยการควบคุมในการสร้างและแก้ไขรูปร่าง ซึ่งจะวางเครื่องมือแก้ไขแบบอินเทอร์แอกทีฟไว้ด้านบนขององค์ประกอบที่เลือก

เครื่องมือตรวจสอบใน Google Chrome รองรับการไฮไลต์รูปร่างในตัว วางเมาส์เหนือองค์ประกอบที่มีพร็อพเพอร์ตี้ shape-outside แล้วองค์ประกอบจะสว่างขึ้นเพื่อแสดงรูปร่าง

รูปร่างจากรูปภาพ: หากต้องการสร้างรูปภาพและต้องการให้เบราว์เซอร์ดึงรูปร่างจากรูปภาพ Rebecca Hauck ได้เขียนบทแนะนำสำหรับ Photoshop ที่เป็นประโยชน์ไว้

Polyfill: Google Chrome เป็นเบราว์เซอร์หลักรายแรกที่ให้บริการรูปร่าง CSS ฟีเจอร์นี้จะพร้อมใช้งานใน iOS 8 และ Safari 8 ของ Apple ในเร็วๆ นี้ ผู้ให้บริการเบราว์เซอร์รายอื่นๆ อาจพิจารณาเรื่องนี้ในอนาคต ในระหว่างนี้จะมี CSS Shapes polyfill ที่ให้การสนับสนุนขั้นพื้นฐาน

บทสรุป

ในเว็บที่เนื้อหาส่วนใหญ่ถูกจำกัดอยู่ในกล่องสี่เหลี่ยมธรรมดา รูปร่าง CSS เป็นวิธีสร้างเลย์เอาต์ที่สื่อความหมายได้ ซึ่งช่วยปิดช่องว่างความเที่ยงตรงระหว่างการออกแบบเว็บกับการออกแบบสิ่งพิมพ์ แต่การใช้รูปทรงอย่างไม่เหมาะสมอาจทำให้ผู้ชมเสียสมาธิได้ แต่หากใช้อย่างมีรสนิยมและพิจารณาอย่างรอบคอบ รูปร่างจะช่วยปรับปรุงการนำเสนอเนื้อหาและดึงดูดความสนใจของผู้ใช้ในแบบที่ไม่เหมือนใคร

มาดูคอลเล็กชันผลงานของผู้อื่นกัน ซึ่งส่วนใหญ่มาจากสิ่งพิมพ์ ซึ่งแสดงให้เห็นการใช้เลย์เอาต์ที่ไม่ใช่สี่เหลี่ยมผืนผ้าที่น่าสนใจ เราหวังว่าบทความนี้จะสร้างแรงบันดาลใจให้คุณลองใช้รูปร่าง CSS และทดสอบไอเดียการออกแบบใหม่ๆ

ขอขอบคุณ Pearl Chen, Alan Stearns และ Zoltan Horvath ที่ช่วยตรวจสอบบทความนี้และให้ข้อมูลเชิงลึกอันมีค่า