PerfectVector
โดย Irene Kimอ่าน 4 นาที

สไปรต์ Symbol ของ SVG: เก็บ ID, ViewBox และสี

สร้างสไปรต์ symbol ของ SVG ด้วยสองไอคอน รักษา ID และ viewBox กำหนดพฤติกรรมสี และตรวจการอ้างอิงภายนอกกับชื่อสำหรับการเข้าถึงตามบริบท

ในหน้านี้

สไปรต์ symbol ของ SVG เก็บนิยามไอคอนที่มีชื่อในไฟล์ SVG เดียว ไอคอนแต่ละตัวที่มองเห็นใช้องค์ประกอบ <use> อ้างถึงนิยามที่ต้องการ การบรรจุแบบนี้ทำงานได้ต่อเมื่อ ID ส่วนย่อย ระบบพิกัด และกฎการลงสียังอยู่ครบเมื่อย้ายจากไฟล์แต่ละไฟล์

เริ่มด้วยสองไอคอนก่อนรวมทั้งโฟลเดอร์ ในตัวอย่างนี้ ใบไม้ใช้พื้นที่พิกัดสี่เหลี่ยมจัตุรัส และลูกศรขวาใช้พื้นที่กว้าง ใบไม้จะปรากฏสองสีโดยไม่ทำสำเนาพาธ ลูกศรจะรักษาสัดส่วนแทนการถูกบังคับลงพื้นที่ภาพของใบไม้

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

สร้างนิยาม symbol ที่มีชื่อสองตัว

บันทึกตัวอย่างต้นฉบับนี้เป็น sprite.svg:

<svg xmlns="http://www.w3.org/2000/svg">
  <symbol id="pv-leaf" viewBox="0 0 24 24">
    <path fill="currentColor"
      d="M5 19C2 10 9 4 20 4C20 15 14 22 5 19Z"/>
  </symbol>
  <symbol id="pv-arrow" viewBox="0 0 32 16">
    <path fill="currentColor"
      d="M2 5H21V1L30 8L21 15V11H2Z"/>
  </symbol>
</svg>

ใบไม้ชื่อ pv-leaf และลูกศรชื่อ pv-arrow นี่คือตัวระบุที่หน้าเว็บจะเรียก MDN อธิบาย symbol ว่าเป็นนิยามกราฟิกใช้ซ้ำได้ที่สร้างตัวอย่างแสดงผลผ่าน use ไฟล์ที่มีเพียง symbol อาจดูว่างเมื่อเปิดโดยลำพัง เพราะนิยามไม่ได้เรนเดอร์โดยตรง

เก็บ viewBox คู่กับงานภาพที่มันอธิบาย ในที่นี้ ใบไม้ใช้ 0 0 24 24 และลูกศรใช้ 0 0 32 16 ตัวเลขเหล่านี้กำหนดขอบเขตพิกัด ไม่ใช่ขนาดแสดงผลที่บังคับ การเปลี่ยนขอบเขตลูกศรเป็น 24 คูณ 24 โดยไม่ปรับรูปทรงไม่ใช่การทำให้เป็นมาตรฐาน ดู เอกสารอ้างอิง viewBox ของ MDN สำหรับการจับคู่พิกัดกับช่องแสดงผล

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

แผนภาพแนวคิดแสดงใบไม้และลูกศรกว้างที่เก็บเป็นนิยาม symbol สองตัว โดยใช้ใบไม้ซ้ำในสีเขียวอมฟ้าและคอรัล และลูกศรในสีน้ำเงินเข้ม
ภาพประกอบ: นิยามสองตัวสร้างตัวอย่างที่มองเห็นสามตัว การใช้ใบไม้ซ้ำเปลี่ยนสีของแต่ละตัวอย่าง ขณะที่แต่ละ symbol เก็บรูปทรงของตัวเอง

อ้างถึงสไปรต์จากหน้าเว็บ

วาง sprite.svg หน้า HTML และ icons.css ในไดเรกทอรีที่ให้บริการเดียวกัน เริ่มด้วยการดูตัวอย่างผ่าน HTTP ที่มีต้นกำเนิดเดียวกัน เพื่อไม่ให้ข้อจำกัดไฟล์ในเครื่องหรือโฮสต์อื่นบดบังข้อผิดพลาดการอ้างอิงพื้นฐาน

เพิ่มกฎเหล่านี้ใน icons.css แล้วโหลดสไตล์ชีตนั้นจากหน้าเว็บ:

.icon {
  display: inline-block;
  width: 1.5rem;
  height: 1.5rem;
  vertical-align: middle;
}
.icon-wide {
  width: 3rem;
}
.garden-button {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: #167d8d;
}

จากนั้นเพิ่มตัวอย่างเหล่านี้ใน body ของ HTML:

<button class="garden-button" type="button">
  <svg class="icon" aria-hidden="true" focusable="false">
    <use href="./sprite.svg#pv-leaf"></use>
  </svg>
  Garden
</button>
 
<svg class="icon icon-wide" role="img" aria-label="Right direction"
  style="color: #233b63">
  <use href="./sprite.svg#pv-arrow"></use>
</svg>

ส่วนก่อน # ระบุไฟล์ ส่วนหลังเลือก symbol แอตทริบิวต์สมัยใหม่คือ href เอกสารอ้างอิง use ของ MDN อธิบายการอ้างอิงภายนอกและเตือนว่าเบราว์เซอร์อาจปฏิเสธการโหลดข้ามต้นกำเนิด อย่าคิดว่าการย้ายสไปรต์ที่ใช้ได้ไป CDN จะใช้แทนได้ทันที ทดสอบตำแหน่งส่งมอบจริง

ที่ขนาดฟอนต์รากเริ่มต้นของเบราว์เซอร์ กฎเหล่านี้ให้กล่องใบไม้ 24 คูณ 24 พิกเซล CSS และลูกศร 48 คูณ 24 ขนาดใช้ rem ดังนั้นขนาดฟอนต์รากที่ต่างจะเปลี่ยนขนาดเหล่านี้ เปรียบเทียบไอคอนในคอมโพเนนต์จริงและภาพตัวอย่างขยาย กล่องที่ถูกต้องยังอาจมีงานภาพที่มีระยะว่างมากเกินไปอยู่ภายใน

ปุ่มด้านบนสาธิตการแสดงไอคอนและการตั้งชื่อ เพิ่มตัวจัดการการทำงานของแอปเองเมื่อใช้ในผลิตภัณฑ์

เลือกกฎการลงสีก่อนรวมไฟล์

พาธตัวอย่างทั้งสองใช้ fill="currentColor" อย่างชัดเจน ทำให้ตัวอย่างที่เรียกใช้รับ CSS color รอบข้างได้: ปุ่มให้สีเขียวอมฟ้า ส่วนลูกศรให้สีน้ำเงินเข้ม เอกสารอ้างอิง color อธิบายว่า currentColor ให้ค่าสำหรับสีเติมและเส้นขอบได้

สำหรับใบไม้ที่ปรากฏครั้งที่สอง ใช้การอ้างอิง pv-leaf เดิมแล้วเปลี่ยน color ของตัวอย่างเป็นคอรัล อย่าทำสำเนาพาธเพียงเพื่อสร้างสีธีมอีกสี

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

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

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

ป้องกัน ID ซ้ำภายในงานภาพ

ชื่อ symbol ไม่ซ้ำเป็นสิ่งจำเป็น แต่ SVG ที่ส่งออกอาจมี ID ภายในเพิ่มอีก: การไล่สี mask clip path หรือนิยามอ้างอิงอื่น MDN กำหนดว่า id แต่ละตัวใน SVG ต้องไม่ซ้ำภายในต้นไม้โหนดของมัน ไฟล์สองไฟล์ที่เคยแยกกันอาจผิดกฎนี้เมื่อรวมกัน

เช่น สมมติไฟล์ใบไม้และตราสัญลักษณ์ที่ส่งออกต่างมีการไล่สีชื่อ paint0 เติมคำนำหน้า ID การไล่สีของใบไม้และการอ้างอิงที่ตรงกันพร้อมกัน:

ตำแหน่งในงานใบไม้ก่อนหลัง
นิยามการไล่สีid="paint0"id="pv-leaf-paint0"
พาธที่ใช้การไล่สีนั้นfill="url(#paint0)"fill="url(#pv-leaf-paint0)"

ส่วนย่อยยังต้องชี้ไปนิยามที่ตั้งใจ ตัวอย่าง fill ของ MDN แสดงความสัมพันธ์ระหว่าง ID การไล่สีกับ url(#...) ให้ตราสัญลักษณ์มีคำนำหน้าของตัวเอง แทนการให้ทั้งสองอ้างถึงการไล่สีของใบไม้

ตัวอย่างสองพาธของเราไม่มีนิยามซ้อน จึงเหมาะสำหรับตรวจครั้งแรก สำหรับไฟล์ส่งออกจริง รวบรวม ID และการอ้างอิงภายในทั้งหมดก่อนรวมไฟล์ หลังเครื่องมือปรับไฟล์หรือตัวสร้างทำงาน ให้รวบรวมรายการนั้นอีกครั้งจากสไปรต์ที่ส่งมอบ การเปลี่ยนชื่อเฉพาะ symbol ภายนอกไม่แก้ ID ภายในซ้ำ

ตั้งชื่อตัวอย่างที่มองเห็นแต่ละตัวตามบริบท

ใบไม้ข้างคำที่มองเห็น “Garden” ซ้ำข้อมูลที่ปุ่มให้ไว้แล้ว SVG ของมันใช้ aria-hidden="true" ให้ข้อความปุ่มเป็นชื่อ เก็บแอตทริบิวต์นี้ไว้ที่ SVG ตกแต่ง ไม่ใช่ปุ่มโต้ตอบ คำแนะนำ aria-hidden ของ MDN อธิบายเนื้อหาตกแต่งและเตือนไม่ให้ซ่อนองค์ประกอบที่รับโฟกัส

ลูกศรที่อยู่ลำพังมีบทบาทต่างกัน: สื่อทิศทางโดยไม่มีข้อความใกล้เคียง SVG ชั้นนอกใช้ role="img" และ aria-label="Right direction" ตามคำแนะนำ MDN สำหรับ ตั้งชื่อภาพ SVG ที่ฝัง

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

ตรวจสไปรต์ที่ส่งมอบ ไม่ใช่เฉพาะไฟล์ต้นทาง

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

ใช้รายการตรวจเล็กชุดเดียวกันหลังบรรจุ:

  1. ไฟล์: ยืนยันว่าหน้าเว็บโหลดสไปรต์ที่ต้องการจาก URL สุดท้าย
  2. ส่วนย่อย: เปรียบเทียบส่วนย่อยใน href ทุกตัวกับ ID symbol ที่ส่งมอบ รวมทั้งตัวพิมพ์ใหญ่เล็ก
  3. ขอบเขต: เปรียบเทียบคอมโพเนนต์เล็กกับภาพขยายเพื่อดูการตัดขอบ ระยะว่าง และอัตราส่วน
  4. สี: เรนเดอร์ไอคอนสีเดียวในสองสีธีม และตรวจงานที่มีสีคงที่แยกกัน
  5. การอ้างอิงภายใน: ตรวจว่าการอ้างอิงสี mask และการตัดขอบที่เติมคำนำหน้ายังหาเป้าหมายได้หลังปรับไฟล์
  6. ความหมาย: ตรวจชื่อของคอมโพเนนต์โต้ตอบแต่ละตัวและป้ายกำกับของภาพที่มีความหมายซึ่งอยู่ลำพัง

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

เมื่อต้นทางมีเพียงไอคอน PNG

หากไอคอนเรียบง่ายเหลือเพียง PNG ให้ แปลง PNG นั้นเป็น SVG ด้วย PerfectVector ก่อนบรรจุ ตรวจขอบรูป ช่องว่าง และบริเวณสีกับต้นฉบับ แล้วอนุมัติขอบเขตพิกัดและกฎการลงสี สุดท้ายให้ ID คงที่แก่งานที่ยอมรับแล้วและเพิ่มในสไปรต์ การแปลงให้งานเวกเตอร์ ไม่ได้เลือกชื่อ symbol ความหมายคอมโพเนนต์ หรือสถาปัตยกรรมการส่งมอบ

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

คำถามที่พบบ่อย

ทำไมสไปรต์ SVG ว่างเมื่อเปิดโดยตรง? สไปรต์ที่มีเพียงนิยาม symbol ไม่แสดง symbol โดยตรง ทดสอบผ่านตัวอย่าง SVG use ที่มีพาธไฟล์และ ID ส่วนย่อยถูกต้อง ก่อนถือว่าเอกสารว่างหมายถึงงานภาพเสีย

ทุก symbol ต้องมี viewBox เดียวกันหรือไม่? ไม่ รักษาระบบพิกัดที่ยอมรับแล้วของแต่ละตัวเมื่อบรรจุ ไอคอนที่ใช้กริดระบบออกแบบร่วมกันมีขอบเขตตรงกันได้ แต่ symbol กว้างไม่ได้กลายเป็นไอคอนจัตุรัสเพียงด้วยการเปลี่ยนตัวเลข viewBox

ทำไมเปลี่ยนสีหน้าเว็บแล้วไอคอนไม่เปลี่ยนสี? ตรวจกฎการลงสีต้นทาง สีเติมคงที่ต่างจากพาธที่เขียนด้วย currentColor เก็บงานหลายสีที่ตั้งใจไว้ และเลือกอย่างชัดเจนว่าสีเติมหรือเส้นขอบใดควรรับสีของตัวอย่าง

วางสไปรต์ในอีกโดเมนได้หรือไม่? อย่าคิดว่าการอ้างอิง use ภายนอกจะทำงานข้ามต้นกำเนิด เริ่มจากชุดทดสอบต้นกำเนิดเดียวกัน แล้วทดสอบโฮสต์จริงและเบราว์เซอร์เป้าหมายก่อนเปลี่ยนการส่งมอบ ตัวอย่างในเครื่องที่สำเร็จไม่ได้ยืนยันการรองรับข้ามต้นกำเนิด

แหล่งอ้างอิง

  1. MDN — symbol — นิยามใช้ซ้ำและการเรนเดอร์ทางอ้อม
  2. MDN — use — ส่วนย่อยภายนอก ข้อจำกัดรูปแบบ และข้อจำกัดต้นกำเนิด
  3. MDN — viewBox — ความสัมพันธ์ระหว่างขอบเขตพิกัดกับช่องแสดงผล
  4. MDN — color — currentColor เป็นค่าป้อนให้การลงสี SVG
  5. MDN — id — ตัวระบุไม่ซ้ำภายในต้นไม้เอกสาร
  6. MDN — fill — การอ้างอิงแหล่งสี เช่น URL การไล่สี
  7. MDN — aria-hidden — เนื้อหาตกแต่งและข้อควรระวังองค์ประกอบที่รับโฟกัส
  8. MDN — บทบาท img — SVG ชั้นนอกที่มีป้ายกำกับสำหรับภาพที่มีความหมาย

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

เพิ่มเติมจากบล็อก

เริ่มต้นด้วย SVG ที่เรียบร้อยขึ้น
และแก้ไขได้ง่ายกว่า