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

การตัดข้อความรอบเส้นทางที่กำหนดเอง

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

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

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

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

การดึงรูปร่างออกจากรูปภาพ
<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 ตัวอย่างเช่น หากองค์ประกอบที่มีรูปภาพถ้วยกาแฟลอยอยู่ทางซ้าย ระบบจะสร้างพื้นที่ลอยทางด้านขวาของถ้วย แม้ว่าคุณจะออกแบบรูปภาพที่มีช่องว่างทั้ง 2 ด้านได้ แต่เนื้อหาจะตัดขึ้นบรรทัดใหม่ตามรูปร่างในด้านตรงข้ามที่กำหนดโดยพร็อพเพอร์ตี้ Float เท่านั้น ไม่ว่าจะเป็นด้านซ้ายหรือขวา แต่จะไม่ใช่ทั้ง 2 ด้าน

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

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

นอกจากการดึงรูปร่างจากรูปภาพแล้ว คุณยังเขียนโค้ดรูปร่างด้วยตนเองได้ด้วย คุณเลือกค่าฟังก์ชันได้ 2-3 ค่าเพื่อสร้างรูปร่าง ได้แก่ 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

ระบบพิกัด 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 ช่วยให้เนื้อหาเว็บเป็นอิสระจากกล่องสี่เหลี่ยมธรรมดาๆ อาจเป็นไปได้ ฉันยังไม่พบ Use Case สำหรับ inset() ที่ไม่สามารถทำได้ด้วย Float และ Margin หรือด้วย 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 จนถึงตอนนี้ก็ยังไม่มีอะไรแปลกใหม่ นั่นคือวิธีการทำงานของ Float อยู่แล้ว แต่การใช้เทคนิคนี้จะช่วยให้คุณนำรูปทรงเรขาคณิตขององค์ประกอบมาใช้ซ้ำได้ มาดูพร็อพเพอร์ตี้ border-radius กัน

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

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

แน่นอนว่าคุณสามารถใช้ช่องอ้างอิงทั้งหมดในลักษณะนี้ได้ นี่คืออีกวิธีหนึ่งในการใช้รูปร่างที่ได้มา - การดึงข้อความอ้างอิงแบบออฟเซ็ต

การสร้างข้อความที่ดึงมาแบบออฟเซ็ตโดยใช้กล่องอ้างอิง content-box

คุณสามารถสร้างเอฟเฟกต์ข้อความดึงดูดสายตาแบบเยื้องได้โดยใช้เฉพาะพร็อพเพอร์ตี้ 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 โดยรอบ) หากรูปร่างมีขนาดใหญ่กว่าและล้นออกมา รูปร่างจะถูกตัดให้พอดีกับ margin-box และคุณจะได้รูปร่างสี่เหลี่ยมผืนผ้า

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

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

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

  Lorem ipsum...
</div>

ตำแหน่งขององค์ประกอบสตรัท .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

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

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

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

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

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

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

เริ่มต้นด้วยการสมมติว่าเบราว์เซอร์ไม่รองรับรูปร่าง CSS และสร้างขึ้นจากสมมติฐานนั้นเมื่อคุณตรวจพบฟีเจอร์ Modernizr เป็นโซลูชันที่ดีในการตรวจหาฟีเจอร์ และมีการทดสอบ CSS Shapes ในส่วน "Non-core detects"

เบราว์เซอร์บางตัวมีการตรวจหาฟีเจอร์ใน CSS ผ่านกฎ @supports โดยไม่ต้องใช้ไลบรารีภายนอก Google Chrome ซึ่งรองรับ CSS Shapes ด้วยจะเข้าใจกฎ @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 ได้เขียนข้อมูลเพิ่มเติมเกี่ยวกับวิธีใช้กฎ CSS @supports

การแก้ความกำกวมจากการยกเว้น CSS

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

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

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

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

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

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

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

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

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

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

บทสรุป

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

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

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