ตัวแปร CSS หรือที่เรียกว่าคุณสมบัติที่กำหนดเองของ CSS มาใช้ Chrome 49 กันแล้ว ซึ่งมีประโยชน์ในการลดการใช้คำซ้ำใน CSS และ สำหรับเอฟเฟกต์รันไทม์ที่มีประสิทธิภาพ เช่น การสลับธีม การขยาย/การใช้ฟีเจอร์ CSS ในอนาคต
ความไม่เป็นระเบียบของ CSS
ในการออกแบบแอปพลิเคชัน แนวทางปฏิบัติทั่วไปคือการแบ่งแยกแบรนด์ สีที่จะนำมาใช้ซ้ำเพื่อให้รูปลักษณ์ของแอปสอดคล้องกัน ขออภัย การทำซ้ำค่าสีเหล่านี้ซ้ำแล้วซ้ำอีกใน CSS ของคุณนั้น ไม่เพียงแต่เป็นเรื่องงานบ้าน แต่ยังมีโอกาสเกิดข้อผิดพลาดอีกด้วย หากมีสีใดสีหนึ่ง คุณต้องเปลี่ยนแปลง ด้วยการระวังลมและ "ค้นหาและแทนที่" ทำทุกอย่าง แต่ในโปรเจ็กต์ที่ใหญ่พอ สิ่งนี้อาจก่อให้เกิดอันตรายได้
ในช่วงนี้นักพัฒนาซอฟต์แวร์จำนวนมากหันมาใช้ CSS ประมวลผลล่วงหน้า เช่น SASS หรือ น้อยที่แก้ไขปัญหานี้ผ่านการใช้ตัวแปร Preprocessor ขณะที่ เครื่องมือเหล่านี้ช่วยเพิ่มประสิทธิภาพการทำงานของนักพัฒนาซอฟต์แวร์ได้อย่างมาก เผชิญประโยชน์จากข้อเสียหลักๆ ซึ่งก็คือความคงที่และไม่สามารถ ที่เปลี่ยนแปลงไปขณะรันไทม์ การเพิ่มความสามารถในการเปลี่ยนตัวแปรขณะรันไทม์ไม่เพียงแต่ ซึ่งเปิดประตูสู่สิ่งต่างๆ เช่น ธีมแอปพลิเคชันแบบไดนามิก แต่ก็มี ผลที่ตามมาสำหรับการออกแบบที่ตอบสนองตามอุปกรณ์และศักยภาพในการเติมเต็ม CSS ในอนาคต ใหม่ๆ หลังจากเปิดตัว Chrome 49 ความสามารถเหล่านี้ก็พร้อมใช้งานแล้วใน รูปแบบของคุณสมบัติที่กำหนดเองของ CSS
พร็อพเพอร์ตี้ที่กำหนดเองโดยสรุป
พร็อพเพอร์ตี้ที่กำหนดเองได้เพิ่มฟีเจอร์ใหม่ 2 รายการลงในกล่องเครื่องมือ CSS ดังนี้
- ความสามารถของผู้เขียนในการกำหนดมูลค่าที่กำหนดเองให้กับพร็อพเพอร์ตี้ที่มี ชื่อผู้แต่งที่เลือกเอง
- ฟังก์ชัน
var()
ซึ่งช่วยให้ผู้เขียนใช้ค่าเหล่านี้ในฟังก์ชันอื่นๆ พร็อพเพอร์ตี้
ลองดูตัวอย่างสั้นๆ เพื่อแสดงให้เห็น
:root {
--main-color: #06c;
}
#foo h1 {
color: var(--main-color);
}
--main-color
เป็นพร็อพเพอร์ตี้แบบกำหนดเองที่ผู้เขียนกำหนดซึ่งมีค่า #06c หมายเหตุ
คุณสมบัติที่กำหนดเองทั้งหมดจะขึ้นต้นด้วยขีดกลาง 2 ขีด
ฟังก์ชัน var()
จะดึงข้อมูลและแทนที่ตัวเองด้วยพร็อพเพอร์ตี้ที่กำหนดเอง
ซึ่งจะทำให้เป็น color: #06c;
ตราบใดที่มีการกำหนดคุณสมบัติที่กำหนดเอง
ที่ใดที่หนึ่งในสไตล์ชีตของคุณ ที่ควรจะมีในฟังก์ชัน var
ไวยากรณ์อาจดูแปลกเล็กน้อยในตอนแรก นักพัฒนาซอฟต์แวร์จำนวนมากถามว่า
ใช้ $foo
สำหรับชื่อตัวแปรก็ได้" เราเลือกวิธีการนี้โดยเฉพาะเพื่อให้
ให้ยืดหยุ่นมากที่สุดและอาจอนุญาตให้ใช้มาโคร $foo
ในอนาคต
สำหรับเรื่องราวเบื้องหลัง โปรดอ่านโพสต์นี้
จากหนึ่งในผู้เขียนข้อมูลจำเพาะอย่าง Tab Atkins
ไวยากรณ์พร็อพเพอร์ตี้ที่กำหนดเอง
ไวยากรณ์สําหรับพร็อพเพอร์ตี้ที่กําหนดเองไม่ซับซ้อน
--header-color: #06c;
โปรดทราบว่าพร็อพเพอร์ตี้ที่กำหนดเองจะพิจารณาตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ ดังนั้น --header-color
และ
--Header-Color
เป็นพร็อพเพอร์ตี้ที่กำหนดเองที่แตกต่างกัน แม้อาจดูเรียบง่าย
ไวยากรณ์ที่ใช้ได้สำหรับพร็อพเพอร์ตี้ที่กำหนดเอง
อนุญาต ตัวอย่างเช่น ต่อไปนี้เป็นพร็อพเพอร์ตี้ที่กำหนดเองที่ถูกต้อง
--foo: if(x > 5) this.width = 10;
แม้ว่าตัวแปรนี้จะไม่มีประโยชน์ในการเป็นตัวแปร แต่จะใช้งานไม่ได้ใน ปกติ ก็มีโอกาสที่จะอ่านและดำเนินการกับ JavaScript ที่ รันไทม์ ซึ่งหมายความว่าพร็อพเพอร์ตี้ที่กำหนดเอง มีศักยภาพในการปลดล็อก ปัจจุบันยังไม่มีเทคนิคที่น่าสนใจสำหรับ CSS Preprocessor ของปัจจุบัน สไตรค์ ถ้าคุณกำลังคิดว่า "หาว ฉันมี SASS แล้วใครจะสนใจ..." ก็ลองดูอีกรอบนะ สิ่งเหล่านี้ไม่ใช่ตัวแปรที่คุณคุ้นเคย
น้ำตก
คุณสมบัติที่กำหนดเองเป็นไปตามกฎการเรียงซ้อนมาตรฐาน ดังนั้นคุณสามารถกำหนด พร็อพเพอร์ตี้ในระดับความเฉพาะเจาะจงต่างๆ
:root { --color: blue; }
div { --color: green; }
#alert { --color: red; }
* { color: var(--color); }
<p>I inherited blue from the root element!</p>
<div>I got green set directly on me!</div>
<div id="alert">
While I got red set directly on me!
<p>I’m red too, because of inheritance!</p>
</div>
ซึ่งหมายความว่าคุณสามารถใช้คุณสมบัติที่กำหนดเองภายในคำสืบค้นสื่อเพื่อช่วย ด้วยการออกแบบที่ปรับเปลี่ยนตามอุปกรณ์ กรณีการใช้งานหนึ่งอาจเป็นการขยายขอบข่าย องค์ประกอบหลักที่เป็นการแบ่งส่วนหลักเมื่อขนาดหน้าจอเพิ่มขึ้น ได้แก่
:root {
--gutter: 4px;
}
section {
margin: var(--gutter);
}
@media (min-width: 600px) {
:root {
--gutter: 16px;
}
}
สิ่งสำคัญที่ควรทราบคือ ข้อมูลโค้ดด้านบนไม่สามารถใช้ CSS Preprocessor ของวันนี้ซึ่งไม่สามารถระบุตัวแปรภายในสื่อได้ การค้นหา การมีความสามารถนี้ช่วยปลดล็อกศักยภาพต่างๆ ได้มากมาย
นอกจากนี้ ยังอาจมีพร็อพเพอร์ตี้ที่กำหนดเองซึ่งสร้างคุณค่าจากพร็อพเพอร์ตี้อื่น พร็อพเพอร์ตี้ที่กำหนดเอง ซึ่งจะเป็นประโยชน์อย่างมากสำหรับการกำหนดธีม ดังนี้
:root {
--primary-color: red;
--logo-text: var(--primary-color);
}
ฟังก์ชัน var()
หากต้องการดึงข้อมูลและใช้ค่าของพร็อพเพอร์ตี้ที่กำหนดเอง คุณจะต้องใช้เมธอด
var()
ไวยากรณ์ของฟังก์ชัน var()
มีลักษณะดังนี้
var(<custom-property-name> [, <declaration-value> ]? )
โดยที่ <custom-property-name>
คือชื่อของพร็อพเพอร์ตี้ที่กำหนดเองซึ่งผู้เขียนระบุไว้
เช่น --foo
และ <declaration-value>
เป็นค่าสำรองที่จะใช้เมื่อพร็อพเพอร์ตี้
พร็อพเพอร์ตี้แบบกำหนดเองที่อ้างอิงไม่ถูกต้อง ค่าสำรองสามารถคั่นด้วยเครื่องหมายจุลภาคได้
ซึ่งจะรวมเป็นค่าเดียว เช่น var(--font-stack,
"Roboto", "Helvetica");
กำหนดโฆษณาสำรอง "Roboto", "Helvetica"
เก็บใน
ค่าสั้นๆ เช่น ค่าที่ใช้สำหรับขอบและระยะห่างจากขอบไม่ใช่ค่า
คั่นด้วยเครื่องหมายจุลภาค ดังนั้นตัวเลือกสำรองที่เหมาะสมสำหรับระยะห่างจากขอบจะมีลักษณะดังนี้
p {
padding: var(--pad, 10px 15px 20px);
}
เมื่อใช้ค่าสำรองเหล่านี้ ผู้เขียนคอมโพเนนต์สามารถเขียนรูปแบบการป้องกันสำหรับ ธาตุ ดังนี้
/* In the component’s style: */
.component .header {
color: var(--header-color, blue);
}
.component .text {
color: var(--text-color, black);
}
/* In the larger application’s style: */
.component {
--text-color: #080;
/* header-color isn’t set,
and so remains blue,
the fallback value */
}
เทคนิคนี้มีประโยชน์มากสำหรับการกำหนดธีมให้คอมโพเนนต์ของเว็บที่ใช้แสงเงา เนื่องจากคุณสมบัติที่กำหนดเองสามารถข้ามผ่านขอบเขตของเงาได้ ผู้เขียนคอมโพเนนต์เว็บ สามารถสร้างการออกแบบเริ่มต้นโดยใช้ค่าสำรอง และแสดงธีมเป็น "hook" ในรูปแบบพร็อพเพอร์ตี้ที่กำหนดเอง
<!-- In the web component's definition: -->
<x-foo>
#shadow
<style>
p {
background-color: var(--text-background, blue);
}
</style>
<p>
This text has a yellow background because the document styled me! Otherwise it
would be blue.
</p>
</x-foo>
/* In the larger application's style: */
x-foo {
--text-background: yellow;
}
เมื่อใช้ var()
มีบางสิ่งที่ควรระวังอยู่ ตัวแปรไม่สามารถเป็น
ชื่อพร็อพเพอร์ตี้ ตัวอย่างเช่น
.foo {
--side: margin-top;
var(--side): 20px;
}
อย่างไรก็ตาม การตั้งค่านี้ไม่เทียบเท่ากับการตั้งค่า margin-top: 20px;
แต่
การประกาศครั้งที่ 2 ไม่ถูกต้องและไม่แสดงข้อผิดพลาด
ในทำนองเดียวกัน คุณก็ไม่สามารถสร้างค่า (โดยไม่มีเหตุอันควร) ซึ่งบางส่วนมาจาก ตัวแปร ได้แก่
.foo {
--gap: 20;
margin-top: var(--gap)px;
}
ย้ำอีกครั้ง การตั้งค่านี้ไม่เทียบเท่ากับการตั้งค่าmargin-top: 20px;
เพื่อสร้าง
คุณต้องมีค่าอื่นด้วย ซึ่งก็คือฟังก์ชัน calc()
การสร้างค่าด้วย calc()
หากคุณไม่เคยใช้งานมาก่อน ฟังก์ชัน calc()
จะทำงานน้อยมาก
เครื่องมือที่ให้คุณคำนวณหาค่า CSS ได้ เครื่องมือนี้รองรับเบราว์เซอร์รุ่นใหม่ทั้งหมดและใช้ร่วมกันได้
โดยใช้พร็อพเพอร์ตี้ที่กำหนดเองเพื่อสร้างค่าใหม่ๆ เช่น
.foo {
--gap: 20;
margin-top: calc(var(--gap) * 1px); /* niiiiice */
}
การใช้งานพร็อพเพอร์ตี้ที่กำหนดเองใน JavaScript
หากต้องการรับค่าของพร็อพเพอร์ตี้ที่กำหนดเองขณะรันไทม์ ให้ใช้ getPropertyValue()
ของออบเจ็กต์ CSSStyledeclaration ที่คำนวณ
/* CSS */
:root {
--primary-color: red;
}
p {
color: var(--primary-color);
}
<!-- HTML -->
<p>I’m a red paragraph!</p>
/* JS */
var styles = getComputedStyle(document.documentElement);
var value = String(styles.getPropertyValue('--primary-color')).trim();
// value = 'red'
ในทำนองเดียวกัน หากต้องการกำหนดค่าพร็อพเพอร์ตี้ที่กำหนดเองขณะรันไทม์ ให้ใช้พารามิเตอร์
เมธอด setProperty()
ของออบเจ็กต์ CSSStyleDeclaration
/* CSS */
:root {
--primary-color: red;
}
p {
color: var(--primary-color);
}
<!-- HTML -->
<p>Now I’m a green paragraph!</p>
/* JS */
document.documentElement.style.setProperty('--primary-color', 'green');
คุณยังตั้งค่าของพร็อพเพอร์ตี้ที่กำหนดเองเพื่ออ้างอิงถึงอีกรายการที่กำหนดเองได้
ขณะรันไทม์โดยใช้ฟังก์ชัน var()
ในการเรียกไปยัง
setProperty()
/* CSS */
:root {
--primary-color: red;
--secondary-color: blue;
}
<!-- HTML -->
<p>Sweet! I’m a blue paragraph!</p>
/* JS */
document.documentElement.style.setProperty('--primary-color', 'var(--secondary-color)');
เนื่องจากพร็อพเพอร์ตี้ที่กำหนดเองสามารถอ้างอิงถึงพร็อพเพอร์ตี้ที่กำหนดเองอื่นๆ ใน คุณอาจนึกภาพออกว่าสิ่งนี้จะนำไปสู่ ผลกระทบรันไทม์
การสนับสนุนเบราว์เซอร์
ขณะนี้ Chrome 49, Firefox 42, Safari 9.1 และ iOS Safari 9.3 รองรับ พร็อพเพอร์ตี้
สาธิต
ลองใช้ ตัวอย่าง เพื่อดูเทคนิคที่น่าสนใจทั้งหมดในตอนนี้ที่คุณนำมาใช้ประโยชน์ได้ พร็อพเพอร์ตี้ที่กำหนดเอง
อ่านเพิ่มเติม
หากสนใจดูข้อมูลเพิ่มเติมเกี่ยวกับอสังหาริมทรัพย์ที่กำหนดเอง Philip Walton ทีม Google Analytics ได้เขียนเกริ่นนำเกี่ยวกับเหตุผลที่เขาตื่นเต้นกับพร็อพเพอร์ตี้ที่กำหนดเอง และสามารถดูความคืบหน้าในเบราว์เซอร์อื่น chromestatus.com.