ทำขอบเฉียงด้วย CSS3 Gradient

ตามที่สัญญากันไว้ครับ

หลายท่านอาจเคยเห็นบางเว็บไซต์ทำขอบเฉียงๆ กันมาบ้างแล้ว อาจจะใช้คุณสมบัติของ CSS Border ทำให้ขอบบางส่วนใส หรือการดัดด้วย transform: skew, SVG element เป็นต้น แต่ด้วยข้อเสียบางอย่างของวิธีการดังกล่าว เช่น CSS Border จำเป็นต้องรู้ขนาดตายตัวเป็น pixel หรือหน่วยที่สัมพันธ์เหมือนกัน (em, rem, vh, vw เป็นต้น) หรือ transform: skew ก็ต้องดัด element นั้นจริงๆ หากต้องใส่ใน element อื่นต้องคำนวนระยะมุมด้วย เป็นต้น

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

มันทำได้อย่างไรกันนี่!?

เทคนิค linear gradient ที่เราจะใช้ก็คือการใส่พื้นหลังแบบไล่สีง่ายๆ นี่แหละครับ ตาม syntax ของ W3C linear-gradient() ซึ่งเป็นมาตรฐานที่สรุปแน่นอนแล้ว จะสามารถใช้คำสั่ง to <หัวมุมที่ให้ไปสุด> เพื่อไล่สีจากมุมตรงข้ามไปยังมุมที่เรากำหนดไว้ ดังนั้น เราก็เลยกำหนดให้ไล่สีตามใจฉันยังไงก็ได ไปจนถึงจุด 50% ซึ่งอยู่ตรงมุมตรงข้ามแนวตั้งพอดี (สมมติเราไล่สีจากมุมซ้ายบนไปขวาล่าง ที่จุด 50% นี้จะตัดที่มุมขวาบนกับซ้ายล่างพอดีตามตัวอย่างข้างบนนั่นเลย) แล้วก็สั่งให้ต่อไปลากสีใสยาวจนครบ 100% เลย (หรือจะใส่เงาก็ได้ โดยแทรกไปในช่วง 50% นั่นได้เลย) แบบนี้ :


#w3c-gradient{

background: linear-gradient(to right top, rgba(0,0,56,1) 0%, rgba(0,0,97,1) 50%, transparent 51%, rgba(0,0,0,0) 71%, rgba(255,55,8,0) 100%);

}

จากข้างบน ตั้งแต่ 50% ไปก็จะเป็นสีใสหมดแลยครับ จะ transparent, rgba(0,0,0,0), rgba(สี,ไร,หว่า,0) ก็ใช้ได้เหมือนกันครับ

ประเด็นมันมีอยู่ว่า…

ถ้าเราใช้ linear-gradient ได้มันก็ไม่มีปัญหาอะไรครับ แต่ไม่ใช่ทุก version ที่รองรับ W3C เสมอไป CSS Gradient รุ่นเก่าๆ ที่มี prefix ส่วนใหญ่ไม่รองรับการไล่สีจากมุมไปมุม ได้แต่ใช้มุมองศาแทน Javascript จะมีบทบาทก็คราวนี้แหละครับ

วิธีการก็คือ เราต้องคำนวนหาองศาของเส้นทแยงมุมด้วยความรู้มัธยมต้น…

ใช่แล้วครับ ตรีโกณมิตินั่นเอง

สามเหลี่ยมตรีโกณมิติ

สามเหลี่ยมตรีโกณมิติ (ที่มา: http://destiny-ask.exteen.com/20091213/entry)

จากภาพ เราสามารถหาความสูงกับความกว้างของ element ได้ด้วย .width() และ .height() การหามุมจึงใช้ arctan(height/width) ด้วย Math.atan() แต่เนื่องจาก Math.atan มันให้ค่ามาเป็น radians จึงต้องคูณ 180/Math.PI (180 องศา = Π radian) เข้าไปให้กลายเป็นอาศา แล้วก็แทรกลงไปในลักษณะเดียวกันครับ


#prefixed-gradient{

background: -webkit-linear-gradient([angle] deg, rgba(0,0,56,1) 0%, rgba(0,0,97,1) 50%, transparent 51%, rgba(0,0,0,0) 71%, rgba(255,55,8,0) 100%);

}

โดยแทน [angle] ด้วยองศาที่ได้จากการคำนวน แล้วก็ .css ได้เลยครับ

ถ้าอยากพลิกไปด้านอื่นบ้าง ก็บวกหรือลบ 90 องศาต่อการหมุน 1 มุมเทานั้นเองครับ

ข้อดี

  • เปลืองทรัพยากรน้อยกว่าการนำ SVG Element หรือรูปสามเหลี่ยมมาวาง
  • เคลื่อนย้ายได้อย่างอิสระ ยืดยุบก็ยังได้สามเหลี่ยมจากมุมไปมุม
  • ถ้าใช้แต่ W3C linear-gradient สามารถใช้กับ pseudo element (before, after) ได้

ข้อเสีย

  • ถ้าใช้กับ version เก่าๆ จำเป็นต้องใช้ javascript เข้าช่วย
  • การใส่รูปภาพพื้นหลังจำเป็นต้องคำนวนดีๆ (ซึ่งใช้ canvas วาดง่ายกว่า)

แม้จะไม่ใช่วิธีที่ดีที่สุด แต่ก็นับว่าน่าสนใจนะครับ ใครมีข้อเสนอแนะหรือไอเดียอยากแชร์ก็ comment กันด้วยนะครับ

สวัสดีครับ