วิธีกำหนดค่าชุดรูปแบบสีของแอปพลิเคชันด้วยคุณสมบัติกำหนดเอง CSS
เผยแพร่แล้ว: 2022-03-10ตัวแปรเป็นเครื่องมือพื้นฐานที่ช่วยจัดระเบียบสีในโครงการ เป็นเวลานาน วิศวกรส่วนหน้าใช้ตัวแปรตัวประมวลผลล่วงหน้าเพื่อกำหนดค่าสีในโครงการ แต่ตอนนี้ นักพัฒนาหลายคนชอบกลไกดั้งเดิมที่ทันสมัยในการจัดระเบียบตัวแปรสี: คุณสมบัติที่กำหนดเอง CSS ข้อได้เปรียบที่สำคัญที่สุดของพวกเขาเหนือตัวแปรพรีโปรเซสเซอร์คือทำงานแบบเรียลไทม์ ไม่ใช่ในขั้นตอนการรวบรวมของโปรเจ็กต์ และรองรับโมเดลคาสเคดซึ่งช่วยให้คุณใช้การสืบทอดและการนิยามค่าใหม่ได้ทันที
เมื่อคุณพยายามจัดระเบียบโครงร่างสีของแอปพลิเคชัน คุณสามารถวางคุณสมบัติที่กำหนดเองทั้งหมดที่เกี่ยวข้องกับสีในส่วนราก ตั้งชื่อ และใช้งานในตำแหน่งที่จำเป็นทั้งหมด
นั่นเป็นตัวเลือกหนึ่ง แต่ช่วยคุณแก้ปัญหาเกี่ยวกับธีมของแอปพลิเคชัน ไวท์เลเบล การรีเฟรชแบรนด์ หรือการจัดโหมดสว่างหรือมืดได้หรือไม่ จะทำอย่างไรถ้าคุณต้องการปรับโทนสีเพื่อเพิ่มคอนทราสต์ ด้วยแนวทางปัจจุบัน คุณจะต้องอัปเดตแต่ละค่าในตัวแปรของคุณ
ในบทความนี้ ฉันต้องการแนะนำแนวทางที่ยืดหยุ่นและทนทานยิ่งขึ้นในการแบ่งตัวแปรสีโดยใช้คุณสมบัติที่กำหนดเอง ซึ่งสามารถแก้ปัญหาเหล่านี้ได้หลายอย่าง
ตั้งค่าจานสี
สีของเว็บไซต์เริ่มต้นด้วยการตั้งค่าชุดสี รูปแบบดังกล่าวขึ้นอยู่กับวงล้อสี โดยปกติ สีหลักเพียงไม่กี่สีจะเป็นพื้นฐานของจานสี ส่วนที่เหลือเป็นสีที่ได้รับ ได้แก่ โทนสีและโทนสีกลาง ส่วนใหญ่แล้ว จานสีจะคงที่และไม่เปลี่ยนแปลงในขณะที่เว็บแอปพลิเคชันทำงานอยู่
ตามทฤษฎีสี มีเพียงไม่กี่ตัวเลือกสำหรับโครงร่างสี:
- รูปแบบเอกรงค์ (สีหลักหนึ่งสี)
- รูปแบบเสริม (สองสีหลัก)
- รูปแบบสาม (สามสีหลัก)
- รูปแบบ Tetradic (สี่สีหลัก)
- รูปแบบที่อยู่ติดกัน (สีหลักสองหรือสามสี)
สำหรับตัวอย่างของฉัน ฉันจะสร้างชุดสีสามสีโดยใช้บริการ Paletton:
ตอนนี้ฉันมีสามสีหลัก บนพื้นฐานของสิ่งเหล่านี้ ฉันจะคำนวณโทนและโทนกลาง (รูปแบบ HSL ร่วมกับฟังก์ชัน calc
เป็นเครื่องมือที่มีประโยชน์มากสำหรับสิ่งนี้) ด้วยการเปลี่ยนค่าความสว่าง ฉันสามารถสร้างสีเพิ่มเติมได้หลายสีสำหรับจานสี
ตอนนี้หากมีการปรับเปลี่ยนจานสี จำเป็นต้องเปลี่ยนเฉพาะค่าของสีหลักเท่านั้น ส่วนที่เหลือจะถูกคำนวณใหม่โดยอัตโนมัติ
หากคุณต้องการรูปแบบ HEX หรือ RGB ก็ไม่สำคัญ จานสีสามารถเกิดขึ้นได้ในขั้นตอนการรวบรวมโปรเจ็กต์ด้วยฟังก์ชันที่เกี่ยวข้องของตัวประมวลผลล่วงหน้า (เช่น กับ SCSS และฟังก์ชันการ color-adjust
) ดังที่ได้กล่าวมาแล้ว เลเยอร์นี้ส่วนใหญ่เป็นแบบสแตติก หายากมากที่จานสีอาจมีการเปลี่ยนแปลงในแอปพลิเคชันที่ทำงานอยู่ นั่นเป็นเหตุผลที่เราสามารถคำนวณได้ด้วยตัวประมวลผลล่วงหน้า
หมายเหตุ : ฉันแนะนำให้สร้างทั้ง HEX literal และ RGB สำหรับแต่ละสี ซึ่งจะทำให้สามารถเล่นกับช่องอัลฟ่าได้ในอนาคต
ระดับจานสีเป็นระดับเดียวที่มีการเข้ารหัสสีโดยตรงในชื่อตัวแปร กล่าวคือ เราสามารถระบุสีได้โดยไม่ซ้ำกันโดยการอ่านชื่อ
กำหนดธีมหรือสีที่ใช้งานได้
เมื่อจานสีเสร็จสิ้น ขั้นตอนต่อไปคือระดับของ สีที่ใช้งาน ได้ ในระดับนี้ ค่าของสีไม่สำคัญเท่ากับจุดประสงค์ หน้าที่ของสี และสิ่งที่ทำให้สีตรงกันทุกประการ ตัวอย่างเช่น สีหลักหรือสีของแบรนด์แอป สีเส้นขอบ สีของข้อความบนพื้นหลังสีเข้ม สีของข้อความบนพื้นหลังสีอ่อน สีพื้นหลังของปุ่ม สีลิงก์ สีลิงก์โฮเวอร์ สีข้อความคำใบ้ และอื่นๆ .
สิ่งเหล่านี้เป็นเรื่องธรรมดามากสำหรับเว็บไซต์หรือแอปพลิเคชันเกือบทุกชนิด เราสามารถพูดได้ว่าสีดังกล่าวมีหน้าที่กำหนดธีมสีของแอปพลิเคชัน นอกจากนี้ ค่าของตัวแปรดังกล่าวจะถูกนำมาจากจานสีอย่างเคร่งครัด ดังนั้นเราจึงสามารถเปลี่ยนธีมของแอปพลิเคชันได้อย่างง่ายดายเพียงแค่ใช้งานด้วยจานสีต่างๆ
ด้านล่างนี้ ฉันได้สร้างการควบคุม UI ทั่วไปสามส่วน: ปุ่ม ลิงก์ และช่องป้อนข้อมูล พวกมันถูกระบายสีโดยใช้ตัวแปรการทำงานที่มีค่าจากจานสีที่ฉันสร้างไว้ข้างต้นก่อนหน้านี้ ตัวแปรการทำงานหลักที่รับผิดชอบธีมของแอปพลิเคชัน (แบรนด์ตามเงื่อนไข) คือตัวแปรสีหลัก
คุณสามารถใช้ปุ่มสามปุ่มที่ด้านบนเพื่อสลับธีม (เปลี่ยนสีของแบรนด์สำหรับการควบคุม) การเปลี่ยนแปลงเกิดขึ้นโดยใช้ CSSOM API (setProperty) ที่เหมาะสม
วิธีนี้สะดวกไม่เพียงแต่สำหรับธีมแต่ยังสำหรับการกำหนดค่าหน้าเว็บแต่ละหน้าด้วย ตัวอย่างเช่น บนเว็บไซต์ zubry.by ฉันใช้สไตล์ชีตทั่วไปและตัวแปรการทำงาน --page-color
เพื่อทำให้โลโก้ ส่วนหัว ตัวควบคุม และการเลือกข้อความเป็นสีสำหรับทุกหน้า และในรูปแบบของตัวเองของแต่ละหน้า ฉันเพิ่งกำหนดตัวแปรนี้ใหม่เพื่อกำหนดสีหลักของหน้าแต่ละหน้า
ใช้สีส่วนประกอบ
โครงการเว็บขนาดใหญ่มักจะมีการสลายตัว เราแบ่งทุกอย่างออกเป็นส่วนประกอบเล็กๆ และนำกลับมาใช้ใหม่ได้ในหลายๆ ที่ แต่ละองค์ประกอบมักจะมีสไตล์ของตัวเอง ซึ่งหมายความว่า ไม่สำคัญว่าเราเคยใช้อะไรในการสลายโมดูล BEM หรือ CSS หรือวิธีการอื่น สิ่งสำคัญคือโค้ดแต่ละส่วนสามารถเรียกว่าขอบเขตท้องถิ่นและนำกลับมาใช้ใหม่ได้
โดยทั่วไป ฉันเห็นประเด็นในการใช้ตัวแปรสีที่ ระดับส่วนประกอบ ในสองกรณี
อย่างแรกคือเมื่อส่วนประกอบต่างๆ ตามคำแนะนำลักษณะการใช้งานซ้ำกับการตั้งค่าต่างๆ เช่น ปุ่มสำหรับความต้องการที่แตกต่างกัน เช่น ปุ่มหลัก (แบรนด์) ปุ่มรอง ปุ่มตติยภูมิ และอื่นๆ
ประการที่สองคือเมื่อส่วนประกอบที่มีสถานะหลายสีด้วยสีต่างๆ เช่น ปุ่มโฮเวอร์ สถานะใช้งานและโฟกัส สถานะปกติและไม่ถูกต้องสำหรับการป้อนข้อมูลหรือฟิลด์เลือก เป็นต้น
กรณีที่เกิดขึ้นได้ยากกว่าเมื่อตัวแปรองค์ประกอบอาจมีประโยชน์คือฟังก์ชันของ "ป้ายกำกับสีขาว" “ไวท์เลเบล” เป็นคุณสมบัติบริการที่อนุญาตให้ผู้ใช้ปรับแต่งหรือสร้างแบรนด์บางส่วนของอินเทอร์เฟซผู้ใช้เพื่อปรับปรุงประสบการณ์ในการโต้ตอบกับลูกค้าของตน ตัวอย่างเช่น เอกสารอิเล็กทรอนิกส์ที่ผู้ใช้แชร์กับลูกค้าผ่านเทมเพลตบริการหรืออีเมล ในกรณีนี้ ตัวแปรที่ระดับส่วนประกอบจะช่วยกำหนดค่าส่วนประกอบบางอย่างแยกจากส่วนที่เหลือของธีมสีของแอปพลิเคชัน
ในตัวอย่างด้านล่าง ตอนนี้ฉันได้เพิ่มการควบคุมสำหรับการกำหนดสีของปุ่มหลัก (แบรนด์) การใช้ตัวแปรสีของระดับส่วนประกอบ เราสามารถกำหนดค่าการควบคุม UI แยกจากกัน
จะกำหนดระดับของตัวแปรได้อย่างไร?
ฉันเจอคำถามว่าจะเข้าใจได้อย่างไรว่าสามารถใส่อะไรในรูทได้ (ธีมหรือระดับการใช้งาน) และควรทิ้งอะไรไว้ที่ระดับของส่วนประกอบ นี่เป็นคำถามที่ยอดเยี่ยมที่ตอบยากโดยที่คุณไม่เห็นสถานการณ์ที่คุณทำงานด้วย
น่าเสียดายที่แนวทางเดียวกับในการเขียนโปรแกรมใช้ไม่ได้กับสีและรูปแบบ หากเราเห็นโค้ดที่เหมือนกันสามชิ้น เราก็จำเป็นต้องจัดองค์ประกอบใหม่
สามารถทำซ้ำสีจากส่วนประกอบหนึ่งไปอีกส่วนประกอบหนึ่งได้ แต่ไม่ได้หมายความว่ามันเป็นกฎ ไม่สามารถมีความสัมพันธ์ระหว่างส่วนประกอบดังกล่าวได้ ตัวอย่างเช่น เส้นขอบของช่องใส่ข้อมูลและพื้นหลังของปุ่มหลัก ใช่ ในตัวอย่างของฉันด้านบนนั้นเป็นกรณีนี้ แต่มาดูตัวอย่างต่อไปนี้กัน:
มีการทำซ้ำสีเทาเข้ม ซึ่งเป็นเส้นขอบของช่องป้อนข้อมูล สีเติมของไอคอนปิด และพื้นหลังของปุ่มรอง แต่องค์ประกอบเหล่านี้ไม่ได้เชื่อมโยงถึงกัน หากสีเส้นขอบของช่องใส่ข้อมูลเปลี่ยนไป เราจะไม่เปลี่ยนพื้นหลังของปุ่มรอง สำหรับกรณีดังกล่าว เราต้องเก็บเฉพาะตัวแปรจากจานสีไว้ที่นี่
แล้วสีเขียวล่ะ? เราสามารถกำหนดได้อย่างชัดเจนว่าเป็นสีหลักหรือสีของแบรนด์ เป็นไปได้มากว่าหากสีของปุ่มหลักเปลี่ยนไป สีของลิงก์และส่วนหัวของระดับแรกก็จะเปลี่ยนไปเช่นกัน
แล้วสีแดงล่ะ? สถานะของช่องป้อนข้อมูลไม่ถูกต้อง ข้อความแสดงข้อผิดพลาด และปุ่มทำลายล้างจะมีสีเดียวกันที่ระดับแอปพลิเคชันทั้งหมด นี่คือรูปแบบ ตอนนี้ฉันสามารถกำหนดตัวแปรการทำงานทั่วไปหลายตัวในส่วนรูท:
เกี่ยวกับระดับของสีส่วนประกอบ เราสามารถระบุส่วนประกอบที่สามารถปรับแต่งได้โดยใช้คุณสมบัติที่กำหนดเอง
ปุ่มถูกทำซ้ำด้วยการตั้งค่าที่แตกต่างกัน สีพื้นหลังและข้อความสำหรับกรณีการใช้งานที่แตกต่างกันจะเปลี่ยนไป — ตัวพิมพ์หลัก รอง ระดับอุดมศึกษา แบบทำลายล้าง หรือเชิงลบ
ช่องป้อนข้อมูลมีสองสถานะ — ไม่ถูกต้องและปกติ โดยที่สีพื้นหลังและเส้นขอบต่างกัน ลองใส่การตั้งค่าเหล่านี้ลงในตัวแปรสีที่ระดับของส่วนประกอบที่เกี่ยวข้องกัน
สำหรับส่วนประกอบที่เหลือ ไม่จำเป็นต้องกำหนดตัวแปรสีในเครื่อง เนื่องจากจะซ้ำซ้อน
คุณต้องเจาะลึกถึงรูปแบบภาษาของโปรเจ็กต์ของคุณ ซึ่งอาจได้รับการพัฒนาโดยทีมออกแบบและ UX วิศวกรต้องเข้าใจแนวคิดทั้งหมดของภาษาภาพอย่างถ่องแท้ จากนั้นเราจะสามารถระบุได้ว่าสิ่งใดเป็นเรื่องธรรมดาและควรอยู่ในระดับที่ใช้งานได้ และสิ่งที่ควรยังคงอยู่ในขอบเขตการมองเห็นในท้องถิ่น
แต่ทุกอย่างไม่ได้ซับซ้อนนัก มีสิ่งที่ชัดเจน พื้นหลังทั่วไปของหน้า พื้นหลัง และสีของข้อความหลัก ในกรณีส่วนใหญ่ นี่คือสิ่งที่กำหนดธีมของแอปพลิเคชันของคุณ สะดวกในการรวบรวมสิ่งต่าง ๆ ที่รับผิดชอบการกำหนดค่าของโหมดเฉพาะ (เช่นโหมดมืดหรือสว่าง)
ทำไมไม่ใส่ทุกอย่างในส่วนรูท?
ฉันมีประสบการณ์ดังกล่าว ในโครงการ Lition ทีมงานและฉันต้องเผชิญกับความจริงที่ว่าเราจำเป็นต้องสนับสนุน IE11 สำหรับเว็บแอปพลิเคชัน แต่ไม่ใช่สำหรับเว็บไซต์และการลงจอด มีการใช้ UI Kit ทั่วไประหว่างโปรเจ็กต์ และเราตัดสินใจที่จะใส่ตัวแปรทั้งหมดลงในรูท ซึ่งจะทำให้เราสามารถกำหนดตัวแปรใหม่ได้ทุกระดับ
และด้วยแนวทางนี้สำหรับเว็บแอปพลิเคชันและกรณี IE11 เราเพียงแค่ส่งโค้ดผ่านปลั๊กอินตัวประมวลผลภายหลังและแปลงตัวแปรเหล่านี้เป็นตัวอักษรสำหรับส่วนประกอบ UI ทั้งหมดในโปรเจ็กต์ เคล็ดลับนี้เป็นไปได้ก็ต่อเมื่อตัวแปรทั้งหมดถูกกำหนดไว้ในส่วนรูทเนื่องจากตัวประมวลผลภายหลังไม่เข้าใจลักษณะเฉพาะของโมเดลคาสเคด
ตอนนี้ฉันเข้าใจแล้วว่านี่ไม่ใช่วิธีที่ถูกต้อง ประการแรก หากคุณใส่สีส่วนประกอบลงในส่วนรูท แสดงว่าคุณแยกหลักการข้อกังวลออก เป็นผลให้คุณสามารถจบลงด้วย CSS ที่ซ้ำซ้อนในสไตล์ชีต ตัวอย่างเช่น คุณมีโฟลเดอร์ของส่วนประกอบที่แต่ละองค์ประกอบมีสไตล์ของตัวเอง คุณยังมีสไตล์ชีตทั่วไปที่คุณอธิบายตัวแปรสีในส่วนรูท คุณตัดสินใจที่จะลบองค์ประกอบปุ่ม ในกรณีนี้ คุณต้องไม่ลืมที่จะลบตัวแปรที่เกี่ยวข้องกับปุ่มออกจากไฟล์ลักษณะทั่วไปด้วย
ประการที่สอง นี่ไม่ใช่ทางออกที่ดีที่สุดในแง่ของประสิทธิภาพ ใช่ การเปลี่ยนสีทำให้เกิดเฉพาะกระบวนการทาสีใหม่ ไม่ใช่การรีโฟลว์/เลย์เอาต์ ซึ่งในตัวมันเองนั้นไม่แพงเกินไป แต่เมื่อคุณทำการเปลี่ยนแปลงบางอย่างที่ระดับสูงสุด คุณจะใช้ทรัพยากรในการตรวจสอบต้นไม้ทั้งหมดมากกว่าเมื่อสิ่งเหล่านี้ การเปลี่ยนแปลงอยู่ในพื้นที่ขนาดเล็ก ฉันแนะนำให้อ่านเกณฑ์มาตรฐานประสิทธิภาพของตัวแปร CSS จาก Lisi Linhart สำหรับรายละเอียดเพิ่มเติม
ในโครงการ Tispr ปัจจุบันของฉัน ทีมงานและฉันใช้ split และไม่ถ่ายโอนข้อมูลทุกอย่างในรูท ในระดับสูงมีเพียงจานสีและสีที่ใช้งานได้ นอกจากนี้เรายังไม่กลัว IE11 เพราะปัญหานี้แก้ไขได้ด้วย polyfill ที่เกี่ยวข้อง เพียงติดตั้งโมดูล npm ie11-custom-properties และนำเข้าไลบรารีไปยังบันเดิล JS ของแอปพลิเคชันของคุณ:
// Use ES6 syntax import "ie11-custom-properties"; // or CommonJS require('ie11-custom-properties');
หรือเพิ่มโมดูลด้วยแท็กสคริปต์:
<script async src="./node_modules/ie11-custom-properties/ie11CustomProperties.js">
นอกจากนี้ คุณสามารถเพิ่มไลบรารีโดยไม่ต้อง npm ผ่าน CDN การทำงานของ polyfill นี้ขึ้นอยู่กับข้อเท็จจริงที่ว่า IE11 มีการสนับสนุนเพียงเล็กน้อยสำหรับคุณสมบัติที่กำหนดเอง ซึ่งคุณสมบัติสามารถกำหนดและอ่านตามการเรียงซ้อนได้ ไม่สามารถทำได้กับคุณสมบัติที่เริ่มต้นด้วยเส้นประคู่ แต่อาจมีเส้นประเดียว (กลไกคล้ายกับคำนำหน้าของผู้ขาย) คุณสามารถอ่านเพิ่มเติมเกี่ยวกับสิ่งนี้ได้ในเอกสารของที่เก็บ รวมทั้งทำความคุ้นเคยกับข้อจำกัดบางประการ เบราว์เซอร์อื่นจะละเว้น polyfill นี้
ด้านล่างนี้คือชุดข้อมูลของเว็บแอปพลิเคชัน Tispr รวมถึงการควบคุมฟังก์ชัน "ไวท์เลเบล" สำหรับเอกสารอิเล็กทรอนิกส์ (เช่น สัญญาผู้ใช้ ใบแจ้งหนี้ หรือข้อเสนอ)
ทำไมไม่เก็บตัวแปรสีไว้ที่ด้าน JavaScript?
อีกคำถามหนึ่งที่สมเหตุสมผล: ทำไมไม่เก็บจานสีและตัวแปรฟังก์ชันในโค้ด JavaScript? นอกจากนี้ยังสามารถเปลี่ยนแปลงแบบไดนามิกและกำหนดสีใหม่ในภายหลังผ่านสไตล์อินไลน์ นี่อาจเป็นตัวเลือก แต่เป็นไปได้มากว่าแนวทางนี้จะไม่ค่อยเหมาะสมนัก เนื่องจากคุณจำเป็นต้องมีสิทธิ์เข้าถึงองค์ประกอบบางอย่างและเปลี่ยนคุณสมบัติสี ด้วยตัวแปร CSS คุณจะเปลี่ยนคุณสมบัติเดียวเท่านั้น กล่าวคือ ค่าตัวแปร
ใน JavaScript ไม่มีฟังก์ชันดั้งเดิมหรือ API สำหรับการทำงานกับสี ในโมดูลสี CSS 5 จะมีโอกาสมากมายที่จะสร้างสีที่ได้รับหรือคำนวณสีเหล่านั้น จากมุมมองของอนาคต คุณสมบัติที่กำหนดเองของ CSS มีความสมบูรณ์และยืดหยุ่นมากกว่าตัวแปร JS นอกจากนี้ ด้วยตัวแปร JS จะไม่มีความเป็นไปได้ที่จะใช้การสืบทอดใน cascade และนั่นคือข้อเสียเปรียบหลัก
บทสรุป
การแบ่งสีออกเป็นสามระดับ (จานสี การใช้งาน และส่วนประกอบ) สามารถช่วยให้คุณปรับตัวให้เข้ากับการเปลี่ยนแปลงและข้อกำหนดใหม่ ๆ ในขณะที่ทำงานในโครงการ ฉันเชื่อว่าคุณสมบัติที่กำหนดเองของ CSS เป็นเครื่องมือที่เหมาะสมสำหรับการจัดแบ่งสี — ไม่สำคัญว่าคุณจะใช้สำหรับการจัดสไตล์อย่างไร: CSS บริสุทธิ์ ตัวประมวลผลล่วงหน้า หรือแนวทาง CSS-in-JS
ฉันมาถึงแนวทางนี้ผ่านประสบการณ์ของตัวเอง แต่ฉันไม่ได้อยู่คนเดียว Sara Soueidan อธิบายในบทความของเธอถึงแนวทางที่คล้ายคลึงกัน ซึ่งเธอแบ่งตัวแปรออกเป็นระดับสากลและระดับองค์ประกอบ
ฉันอยากจะแนะนำให้อ่านบทความของ Lea Verou ซึ่งเธออธิบายกรณีที่เป็นไปได้ของการใช้ตัวแปร CSS (ไม่ใช่แค่ในแง่ของสี)