การสร้างคอมโพเนนต์ปุ่ม

ภาพรวมพื้นฐานของวิธีสร้างคอมโพเนนต์ <button> ที่ปรับตามสี ตอบสนอง และเข้าถึงง่าย

ในโพสต์นี้ผมอยากจะแชร์ความคิดเห็นเกี่ยวกับวิธีปรับแต่งสี ปรับเปลี่ยนตามพื้นที่โฆษณาและเข้าถึงได้ <button> ทดลองใช้ และดู แหล่งที่มา

โต้ตอบกับปุ่มต่างๆ ผ่านแป้นพิมพ์และเมาส์ในธีมสว่างและมืด

หากต้องการดูวิดีโอ โปรดใช้โพสต์นี้ในเวอร์ชัน YouTube

ภาพรวม

การรองรับเบราว์เซอร์

  • Chrome: 1.
  • ขอบ: 12.
  • Firefox: 1.
  • Safari: 1.

แหล่งที่มา

<button> สร้างขึ้นเพื่อการโต้ตอบของผู้ใช้ ทริกเกอร์เหตุการณ์ click จากแป้นพิมพ์ เมาส์ การแตะ เสียง และอื่นๆ ด้วยกฎที่ชาญฉลาด ช่วงเวลา นอกจากนี้ยังมาพร้อมกับ พร้อมรูปแบบเริ่มต้นบางรายการในแต่ละเบราว์เซอร์ คุณจึงใช้ได้โดยตรงโดยไม่ต้อง การปรับแต่งใดๆ ก็ได้ ใช้ color-scheme เพื่อเลือกใช้ ลงในปุ่มสว่างและปุ่มมืดที่เบราว์เซอร์มีให้ด้วย

นอกจากนี้ยังมีแท็ก ปุ่ม แต่ละโค้ดที่แสดงในการฝังโค้ดบรรทัดก่อนหน้า <button> ที่ไม่มีประเภทจะ ปรับให้อยู่ภายใน <form> โดยเปลี่ยนเป็นประเภทการส่ง

<!-- buttons -->
<button></button>
<button type="submit"></button>
<button type="button"></button>
<button type="reset"></button>

<!-- button state -->
<button disabled></button>

<!-- input buttons -->
<input type="button" />
<input type="file">

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

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

ปุ่มยังมีคลาสสมมติด้วย สำหรับ CSS เพื่อใช้ในการจัดรูปแบบ คลาสเหล่านี้มีฮุกของ CSS ในการปรับแต่ง ลักษณะของปุ่ม: :hover เมื่อเมาส์อยู่เหนือปุ่ม :active เมื่อเลื่อนเมาส์ หรือแป้นพิมพ์กำลังกด :focus หรือ :focus-visible สำหรับช่วยในการจัดรูปแบบเทคโนโลยีความช่วยเหลือพิเศษ

button:hover {}
button:active {}
button:focus {}
button:focus-visible {}
ตัวอย่างปุ่มทุกประเภทในชุดสุดท้ายในธีมมืด
ตัวอย่างปุ่มทุกประเภทในชุดสุดท้ายในธีมมืด

Markup

นอกจากประเภทปุ่มที่กำหนดโดยข้อกำหนด HTML แล้ว ผมยังได้เพิ่มองค์ประกอบ ที่มีไอคอนและปุ่มที่มีชั้นเรียนที่กำหนดเอง btn-custom

<button>Default</button>
<input type="button" value="<input>"/>
<button>
  <svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true">
    <path d="..." />
  </svg>
  Icon
</button>
<button type="submit">Submit</button>
<button type="button">Type Button</button>
<button type="reset">Reset</button>
<button disabled>Disabled</button>
<button class="btn-custom">Custom</button>
<input type="file">

จากนั้นสำหรับการทดสอบ ปุ่มแต่ละปุ่มจะอยู่ในแบบฟอร์ม วิธีนี้ทำให้ฉันมั่นใจ มีการอัปเดตอย่างเหมาะสมสำหรับปุ่มเริ่มต้น ซึ่งมีลักษณะเหมือน ปุ่ม "ส่ง" ฉันยังเปลี่ยนกลยุทธ์ไอคอนด้วย จาก SVG ในหน้าเป็น SVG ที่มาสก์ เพื่อให้แน่ใจว่าทั้ง 2 เครื่องทำงานได้ดีเท่าๆ กัน

<form>
  <button>Default</button>
  <input type="button" value="<input>"/>
  <button>Icon <span data-icon="cloud"></span></button>
  <button type="submit">Submit</button>
  <button type="button">Type Button</button>
  <button type="reset">Reset</button>
  <button disabled>Disabled</button>
  <button class="btn-custom btn-large" type="button">Large Custom</button>
  <input type="file">
</form>

เมทริกซ์ของชุดค่าผสมนั้นมีมากมายมหาศาลในจุดนี้ ปุ่มระหว่าง ประเภท, Pseudo-class และการอยู่ในหรือออกจากฟอร์ม จะมี โดยใช้ปุ่มต่างๆ โชคดีที่ CSS จะช่วยเราในการสื่อสาร อย่างชัดเจน

การช่วยเหลือพิเศษ

องค์ประกอบต่างๆ ของปุ่มนั้นสามารถเข้าถึงได้โดยธรรมชาติ แต่ก็มีบางส่วนที่พบได้ทั่วไป การเพิ่มประสิทธิภาพ

วางเมาส์เหนือและโฟกัสไปด้วยกัน

ฉันต้องการจัดกลุ่ม :hover และ :focus เข้าด้วยกันด้วยฟังก์ชัน :is() ตัวเลือกเทียม วิธีนี้จะช่วยให้อินเทอร์เฟซพิจารณาแป้นพิมพ์เสมอ และเทคโนโลยีความช่วยเหลือพิเศษ

button:is(:hover, :focus) {
  
}
ลองใช้การสาธิต

วงแหวนโฟกัสแบบอินเทอร์แอกทีฟ

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

:where(button, input):where(:not(:active)):focus-visible {
  outline-offset: 5px;
}

ตรวจสอบคอนทราสต์ของสี

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

ซ่อนไอคอนจากผู้ที่ไม่เห็น

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

<button>
  <svg … aria-hidden="true">...</svg>
  Icon Button
</button>
เครื่องมือสำหรับนักพัฒนาเว็บใน Chrome แสดงโครงสร้างการช่วยเหลือพิเศษสำหรับปุ่ม ต้นไม้ไม่สนใจรูปภาพปุ่มเนื่องจากตั้งค่า aria-hidden เป็น &quot;จริง&quot;
เครื่องมือสำหรับนักพัฒนาเว็บใน Chrome แสดงโครงสร้างการช่วยเหลือพิเศษสำหรับปุ่ม ต้นไม้ไม่สนใจรูปภาพปุ่มเนื่องจากตั้งค่า aria-hidden เป็น "จริง"

รูปแบบ

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

กลยุทธ์พร็อพเพอร์ตี้ที่กำหนดเองแบบปรับเปลี่ยนได้

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

button {
  --_bg-light: white;
  --_bg-dark: black;
  --_bg: var(--_bg-light);

  background-color: var(--_bg);
}

@media (prefers-color-scheme: dark) {
  button {
    --_bg: var(--_bg-dark);
  }
}

ฉันชอบตรงที่ธีมสว่างและมืดเป็นแบบประกาศชัดเจนและชัดเจน ทางอ้อมและแอบสแตรกต์จะถูกปิดลงในพร็อพเพอร์ตี้ที่กำหนดเองของ --_bg ซึ่งขณะนี้จะเป็นเพียง "ปฏิกิริยา" เพียงอย่างเดียว คุณสมบัติ --_bg-light และ --_bg-dark แบบคงที่ ธีมสว่างเป็นธีมเริ่มต้นอย่างชัดเจน ใช้ "มืด" อย่างมีเงื่อนไขเท่านั้น

เตรียมพร้อมสำหรับความสอดคล้องกันของการออกแบบ

ตัวเลือกที่ใช้ร่วมกัน

ตัวเลือกต่อไปนี้ใช้ในการกำหนดเป้าหมายปุ่มประเภทต่างๆ และ ก็จะซับซ้อนเล็กน้อยในตอนแรก :where() คือ ดังนั้นการปรับแต่งปุ่มจึงไม่ต้องเจาะจง ปุ่มมักมี ปรับให้เหมาะกับสถานการณ์ทางเลือก และตัวเลือก :where() จะช่วยให้แน่ใจว่างาน นั้นง่ายมาก ใน :where() จะมีการเลือกปุ่มแต่ละประเภท รวมถึง ::file-selector-button ซึ่งไม่สามารถ มือสอง ภายใน :is() หรือ :where()

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"],
  input[type="file"]
),
:where(input[type="file"])::file-selector-button {
  
}

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

สีเฉพาะจุดของปุ่ม

ปุ่มและไอคอนส่งเป็นวิธีที่ยอดเยี่ยมในการแสดงสีที่โดดเด่น:

--_accent-light: hsl(210 100% 40%);
--_accent-dark: hsl(210 50% 70%);
--_accent: var(--_accent-light);

สีข้อความบนปุ่ม

สีข้อความบนปุ่มไม่ได้เป็นสีขาวหรือสีดำ สีที่เข้มขึ้นหรือสีอ่อนลง ของ --_accent กำลังใช้ hsl() และ ตามโทนสี 210:

--_text-light: hsl(210 10% 30%);
--_text-dark: hsl(210 5% 95%);
--_text: var(--_text-light);

สีพื้นของปุ่ม

พื้นหลังของปุ่มใช้รูปแบบ hsl() เดียวกัน ยกเว้นธีมสว่าง ปุ่ม — ปุ่มทั้งหมดถูกตั้งค่าเป็นสีขาวเพื่อให้พื้นผิวของปุ่มเหล่านั้นปรากฏใกล้กับ ผู้ใช้หรือหน้าพื้นที่อื่นๆ

--_bg-light: hsl(0 0% 100%);
--_bg-dark: hsl(210 9% 31%);
--_bg: var(--_bg-light);

พื้นหลังของปุ่ม

สีพื้นหลังนี้มีไว้สำหรับการทำให้พื้นผิวปรากฏหลังพื้นผิวอื่นๆ มีประโยชน์สำหรับพื้นหลังของอินพุตไฟล์:

--_input-well-light: hsl(210 16% 87%);
--_input-well-dark: hsl(204 10% 10%);
--_input-well: var(--_input-well-light);

ระยะห่างจากขอบของปุ่ม

ระยะห่างรอบๆ ข้อความบนปุ่มนั้นใช้ ch ซึ่งเป็นความยาวที่สัมพันธ์กับขนาดแบบอักษร ซึ่งจะมีความสำคัญอย่างมากหากมี ปุ่มต่างๆ จะสามารถยกระดับ font-size และขนาดปุ่มได้ ตามสัดส่วน:

--_padding-inline: 1.75ch;
--_padding-block: .75ch;

เส้นขอบปุ่ม

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

--_border-radius: .5ch;

--_border-light: hsl(210 14% 89%);
--_border-dark: var(--_bg-dark);
--_border: var(--_border-light);

เอฟเฟกต์ไฮไลต์เมื่อวางเมาส์เหนือปุ่ม

พร็อพเพอร์ตี้เหล่านี้จะสร้างพร็อพเพอร์ตี้ขนาดสำหรับการเปลี่ยนผ่านการโต้ตอบ และ สีไฮไลต์จะเป็นไปตามระบบสีแบบปรับอัตโนมัติ เราจะพูดถึงวิธี โต้ตอบภายหลังในโพสต์นี้ แต่ท้ายที่สุดแล้วรายการเหล่านี้จะใช้สำหรับ box-shadow ผลกระทบ:

--_highlight-size: 0;

--_highlight-light: hsl(210 10% 71% / 25%);
--_highlight-dark: hsl(210 10% 5% / 25%);
--_highlight: var(--_highlight-light);

เงาข้อความบนปุ่ม

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

--_ink-shadow-light: 0 1px 0 var(--_border-light);
--_ink-shadow-dark: 0 1px 0 hsl(210 11% 15%);
--_ink-shadow: var(--_ink-shadow-light);

ไอคอนปุ่ม

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

--_icon-size: 2ch;
--_icon-color: var(--_accent);

เงาปุ่ม

เงาจะต้องปรับ สี และความทึบแสง เงาของธีมสว่างจะดีที่สุดเมื่อมีความละเอียดแบบเล็กน้อยและย้อมสี ตามสีพื้นผิวที่วางซ้อน เงาของธีมมืดจะต้องเข้มกว่าและ มีความอิ่มตัวมากกว่า จึงสามารถวางซ้อนสีพื้นผิวที่เข้มขึ้นได้

--_shadow-color-light: 220 3% 15%;
--_shadow-color-dark: 220 40% 2%;
--_shadow-color: var(--_shadow-color-light);

--_shadow-strength-light: 1%;
--_shadow-strength-dark: 25%;
--_shadow-strength: var(--_shadow-strength-light);

ด้วยการปรับสีและจุดแข็ง ทำให้ฉันสามารถรวมความลึกของเงาได้ 2 ระดับ:

--_shadow-1: 0 1px 2px -1px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 9%));

--_shadow-2: 
  0 3px 5px -2px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 3%)),
  0 7px 14px -5px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 5%));

นอกจากนี้ เพื่อให้ปุ่มมีลักษณะ 3 มิติเล็กน้อย เงากล่อง 1px สร้างภาพลวงตา:

--_shadow-depth-light: 0 1px var(--_border-light);
--_shadow-depth-dark: 0 1px var(--_bg-dark);
--_shadow-depth: var(--_shadow-depth-light);

การเปลี่ยนปุ่ม

ตามรูปแบบของสีที่ปรับเปลี่ยนได้ ฉันสร้างคุณสมบัติคงที่ 2 อย่างเพื่อ ตัวเลือกระบบการออกแบบ

--_transition-motion-reduce: ;
--_transition-motion-ok:
  box-shadow 145ms ease,
  outline-offset 145ms ease
;
--_transition: var(--_transition-motion-reduce);

พร็อพเพอร์ตี้ทั้งหมดรวมกันในตัวเลือก

พร็อพเพอร์ตี้ที่กำหนดเองทั้งหมดในตัวเลือก

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"],
  input[type="file"]
),
:where(input[type="file"])::file-selector-button {
  --_accent-light: hsl(210 100% 40%);
  --_accent-dark: hsl(210 50% 70%);
  --_accent: var(--_accent-light);

--_text-light: hsl(210 10% 30%); --_text-dark: hsl(210 5% 95%); --_text: var(--_text-light);

--_bg-light: hsl(0 0% 100%); --_bg-dark: hsl(210 9% 31%); --_bg: var(--_bg-light);

--_input-well-light: hsl(210 16% 87%); --_input-well-dark: hsl(204 10% 10%); --_input-well: var(--_input-well-light);

--_padding-inline: 1.75ch; --_padding-block: .75ch;

--_border-radius: .5ch; --_border-light: hsl(210 14% 89%); --_border-dark: var(--_bg-dark); --_border: var(--_border-light);

--_highlight-size: 0; --_highlight-light: hsl(210 10% 71% / 25%); --_highlight-dark: hsl(210 10% 5% / 25%); --_highlight: var(--_highlight-light);

--_ink-shadow-light: 0 1px 0 hsl(210 14% 89%); --_ink-shadow-dark: 0 1px 0 hsl(210 11% 15%); --_ink-shadow: var(--_ink-shadow-light);

--_icon-size: 2ch; --_icon-color-light: var(--_accent-light); --_icon-color-dark: var(--_accent-dark); --_icon-color: var(--accent, var(--_icon-color-light));

--_shadow-color-light: 220 3% 15%; --_shadow-color-dark: 220 40% 2%; --_shadow-color: var(--_shadow-color-light); --_shadow-strength-light: 1%; --_shadow-strength-dark: 25%; --_shadow-strength: var(--_shadow-strength-light); --_shadow-1: 0 1px 2px -1px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 9%)); --_shadow-2: 0 3px 5px -2px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 3%)), 0 7px 14px -5px hsl(var(--_shadow-color)/calc(var(--_shadow-strength) + 5%)) ;

--_shadow-depth-light: hsl(210 14% 89%); --_shadow-depth-dark: var(--_bg-dark); --_shadow-depth: var(--_shadow-depth-light);

--_transition-motion-reduce: ; --_transition-motion-ok: box-shadow 145ms ease, outline-offset 145ms ease ; --_transition: var(--_transition-motion-reduce); }

ปุ่มเริ่มต้นจะแสดงในธีมสว่างและธีมมืดคู่กัน

การปรับธีมมืด

ค่าของรูปแบบอุปกรณ์ประกอบคงที่ -light และ -dark จะชัดเจนเมื่อ พร็อพถ่ายรูปในธีมมืดได้รับการตั้งค่าแล้ว

@media (prefers-color-scheme: dark) {
  :where(
    button,
    input[type="button"],
    input[type="submit"],
    input[type="reset"],
    input[type="file"]
  ),
  :where(input[type="file"])::file-selector-button {
    --_bg: var(--_bg-dark);
    --_text: var(--_text-dark);
    --_border: var(--_border-dark);
    --_accent: var(--_accent-dark);
    --_highlight: var(--_highlight-dark);
    --_input-well: var(--_input-well-dark);
    --_ink-shadow: var(--_ink-shadow-dark);
    --_shadow-depth: var(--_shadow-depth-dark);
    --_shadow-color: var(--_shadow-color-dark);
    --_shadow-strength: var(--_shadow-strength-dark);
  }
}

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

ลดการปรับเปลี่ยนการเคลื่อนไหว

หากการเคลื่อนไหวเหมาะกับผู้ใช้ที่เข้าชมรายนี้ ให้กำหนด --_transition ให้กับ var(--_transition-motion-ok):

@media (prefers-reduced-motion: no-preference) {
  :where(
    button,
    input[type="button"],
    input[type="submit"],
    input[type="reset"],
    input[type="file"]
  ),
  :where(input[type="file"])::file-selector-button {
    --_transition: var(--_transition-motion-ok);
  }
}

2-3 สไตล์ที่แชร์

ปุ่มและอินพุตต้องตั้งค่าแบบอักษรเป็น inherit เพื่อให้ตรงกับ แบบอักษรที่เหลือของหน้า มิฉะนั้นจะมีการจัดรูปแบบโดยเบราว์เซอร์ ยัง ใช้กับ letter-spacing การตั้งค่า line-height เป็น 1.5 จะตั้งค่าตู้จดหมาย ปรับขนาดเพื่อให้ข้อความมีพื้นที่ว่างด้านบนและด้านล่างบางส่วน:

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"],
  input[type="file"]
),
:where(input[type="file"])::file-selector-button {
  /* …CSS variables */

  font: inherit;
  letter-spacing: inherit;
  line-height: 1.5;
  border-radius: var(--_border-radius);
}

ภาพหน้าจอแสดงปุ่มหลังจากใช้รูปแบบก่อนหน้า

ปุ่มการจัดรูปแบบ

การปรับตัวเลือก

ตัวเลือก input[type="file"] ไม่ใช่ส่วนปุ่มของอินพุต องค์ประกอบเทียม ::file-selector-button คือ ฉันจึงนำ input[type="file"] ออก จากรายการดังนี้

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"],
  input[type="file"]
),
:where(input[type="file"])::file-selector-button {
  
}

การปรับเคอร์เซอร์และการสัมผัส

ก่อนอื่น ให้จัดรูปแบบเคอร์เซอร์เป็นสไตล์ pointer ซึ่งช่วยให้ปุ่มแสดง แก่ผู้ใช้เมาส์ว่าเป็นการโต้ตอบ จากนั้นฉันเพิ่ม touch-action: manipulation ไปยัง ทำให้การคลิกไม่จำเป็นต้องรอและสังเกต การดับเบิลคลิกที่อาจเกิดขึ้น ทำงานได้เร็วขึ้น:

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  cursor: pointer;
  touch-action: manipulation;
}

สีและเส้นขอบ

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

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  

  font-size: var(--_size, 1rem);
  font-weight: 700;
  background: var(--_bg);
  color: var(--_text);
  border: 2px solid var(--_border);
}

ภาพหน้าจอแสดงปุ่มหลังจากใช้รูปแบบก่อนหน้า

เงา

ปุ่มเหล่านี้มีเทคนิคที่ยอดเยี่ยม text-shadow คือ ปรับอัตโนมัติให้เข้ากับแสงและมืด ทำให้ปุ่มดูเพลินตา ข้อความวางอยู่บนพื้นหลังอย่างสวยงาม สำหรับ box-shadow กำหนดเงาสามรายการ รายการแรก --_shadow-2 เป็นเงากล่องปกติ เงาที่ 2 เป็นสิ่งลวงตาที่ทำให้ปุ่มดูเหมือน นูนขึ้นมาหน่อย เงาสุดท้ายเป็นไฮไลต์การชี้เมาส์เมื่อเริ่มต้น ที่ขนาด 0 แต่จะได้รับขนาดในภายหลังและมีการเปลี่ยนแปลงเพื่อให้ปรากฏ ให้เติบโตจากปุ่ม

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  

  box-shadow: 
    var(--_shadow-2),
    var(--_shadow-depth),
    0 0 0 var(--_highlight-size) var(--_highlight)
  ;
  text-shadow: var(--_ink-shadow);
}

ภาพหน้าจอแสดงปุ่มหลังจากใช้รูปแบบก่อนหน้า

เลย์เอาต์

ฉันให้ปุ่มมีเลย์เอาต์ flexbox การออกแบบ inline-flex ที่จะพอดีกับเนื้อหา จากนั้นจัดกึ่งกลาง ข้อความ และจัดแนวเด็กในแนวตั้งและแนวนอนตามแนว center ซึ่งจะช่วยไอคอนและอื่นๆ ของปุ่มเพื่อปรับแนวอย่างเหมาะสม

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  

  display: inline-flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}

ภาพหน้าจอแสดงปุ่มหลังจากใช้รูปแบบก่อนหน้า

การเว้นวรรค

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

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  

  gap: 1ch;
  padding-block: var(--_padding-block);
  padding-inline: var(--_padding-inline);
}

ภาพหน้าจอแสดงปุ่มหลังจากใช้รูปแบบก่อนหน้า

UX การแตะและเมาส์

ส่วนถัดไปนี้ส่วนใหญ่จะเป็นเรื่องสำหรับผู้ที่แตะแล้วในอุปกรณ์เคลื่อนที่ องค์ประกอบ พร็อพเพอร์ตี้ user-select สำหรับผู้ใช้ทุกคน จะป้องกันไม่ให้ข้อความไฮไลต์ข้อความบนปุ่ม โดยส่วนใหญ่ สังเกตเห็นได้ในอุปกรณ์ระบบสัมผัสเมื่อแตะปุ่มค้างไว้และขณะทำงาน ระบบจะไฮไลต์ข้อความของปุ่ม

ฉันพบว่านี่ไม่ใช่ประสบการณ์ของผู้ใช้สำหรับปุ่มในตัว ฉันเลยปิดใช้โดยตั้งค่า user-select เป็น "ไม่มี" แตะสีไฮไลต์ (-webkit-tap-highlight-color) และเมนูตามบริบทของระบบปฏิบัติการ (-webkit-touch-callout) เป็นคุณสมบัติปุ่มอื่นๆ ที่เน้นเว็บซึ่งไม่สอดคล้องกับ กับสิ่งที่คาดหวังได้ ผมก็เลยนำความคิดเห็นนั้นออกด้วย

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  

  user-select: none;
  -webkit-tap-highlight-color: transparent;
  -webkit-touch-callout: none;
}

ทรานซิชัน

มีการกำหนดตัวแปร --_transition แบบปรับอัตโนมัติให้กับฟังก์ชัน พร็อพเพอร์ตี้ transition

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
),
:where(input[type="file"])::file-selector-button {
  

  transition: var(--_transition);
}

เมื่อวางเมาส์เหนือขณะที่ผู้ใช้ไม่ได้กดอยู่ ให้ปรับการไฮไลต์เงา ปรับขนาดเพื่อให้มีลักษณะเด่นที่ดูเหมือนจะขยายจากภายใน ปุ่ม:

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
):where(:not(:active):hover) {
  --_highlight-size: .5rem;
}

เมื่อโฟกัสแล้ว ให้เพิ่มออฟเซ็ตโครงร่างโฟกัสจากปุ่ม ซึ่งเป็นการเพิ่ม ลักษณะการโฟกัสที่ดีซึ่งปรากฏจากภายในปุ่ม:

:where(button, input):where(:not(:active)):focus-visible {
  outline-offset: 5px;
}

ไอคอน

สำหรับไอคอนการจัดการ ตัวเลือกจะมีตัวเลือก :where() เพิ่มเข้ามาสำหรับ SVG โดยตรง องค์ประกอบย่อยหรือองค์ประกอบที่มีแอตทริบิวต์ที่กำหนดเอง data-icon กำหนดขนาดไอคอนแล้ว ด้วยพร็อพเพอร์ตี้ที่กำหนดเองโดยใช้พร็อพเพอร์ตี้แบบอินไลน์และพร็อพเพอร์ตี้บล็อก สีเส้น มีการตั้งค่า รวมถึง drop-shadow ให้ตรงกับ text-shadow flex-shrink ได้รับการตั้งค่าเป็น 0 ดังนั้นไอคอนจะไม่มีทาง ชนะ สุดท้าย ฉันเลือกไอคอนที่มีเส้นตรง และกำหนดรูปแบบดังกล่าวไว้ที่นี่ด้วย การผนวกบรรทัด fill: none และ round บรรทัดและการรวมบรรทัด:

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
) > :where(svg, [data-icon]) {
  block-size: var(--_icon-size);
  inline-size: var(--_icon-size);
  stroke: var(--_icon-color);
  filter: drop-shadow(var(--_ink-shadow));

  flex-shrink: 0;
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
}

ภาพหน้าจอแสดงปุ่มหลังจากใช้รูปแบบก่อนหน้า

การปรับแต่งปุ่มส่ง

ฉันต้องการให้ปุ่ม "ส่ง" มีการโปรโมตเล็กน้อย และบรรลุผล โดยทำให้สีข้อความของปุ่มเป็นสีเฉพาะจุด ดังนี้

:where(
  [type="submit"], 
  form button:not([type],[disabled])
) {
  --_text: var(--_accent);
}

ภาพหน้าจอแสดงปุ่มหลังจากใช้รูปแบบก่อนหน้า

ปรับแต่งปุ่มรีเซ็ต

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

:where([type="reset"]) {
  --_border-light: hsl(0 100% 83%);
  --_highlight-light: hsl(0 100% 89% / 20%);
  --_text-light: hsl(0 80% 50%);
  --_text-dark: hsl(0 100% 89%);
}

และยังคิดว่าคงจะดีหากสีโครงร่างของจุดโฟกัส จะตรงกับการเน้นเสียงของ สีแดง สีข้อความจะปรับสีแดงเข้มให้เป็นสีแดงอ่อน ฉันทำให้เป็นสีโครงร่าง จับคู่สิ่งนี้กับคีย์เวิร์ด currentColor:

:where([type="reset"]):focus-visible {
  outline-color: currentColor;
}

ภาพหน้าจอแสดงปุ่มหลังจากใช้รูปแบบก่อนหน้า

ปรับแต่งปุ่มที่ปิดใช้

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

:where(
  button,
  input[type="button"],
  input[type="submit"],
  input[type="reset"]
)[disabled] {
  --_bg: none;
  --_text-light: hsl(210 7% 40%);
  --_text-dark: hsl(210 11% 71%);

  cursor: not-allowed;
  box-shadow: var(--_shadow-1);
}

ภาพหน้าจอแสดงปุ่มหลังจากใช้รูปแบบก่อนหน้า

กำลังปรับแต่งปุ่มอินพุตไฟล์

ปุ่มอินพุตไฟล์เป็นคอนเทนเนอร์สำหรับระยะเวลาและปุ่ม CSS ดำเนินการต่อไปนี้ได้ จัดรูปแบบคอนเทนเนอร์อินพุตเล็กน้อย รวมถึงปุ่มที่ซ้อนกัน แต่ ระยะเวลา คอนเทนเนอร์ได้ค่าเป็น max-inline-size เพื่อไม่ให้ขยายเกิน จำเป็นต้องย่อ แต่ inline-size: 100% จะย่อและพอดีได้ คอนเทนเนอร์ที่มีขนาดเล็กกว่านั้น ตั้งค่าสีพื้นหลังเป็นสีแบบปรับอัตโนมัติแล้ว ที่มืดกว่าพื้นผิวอื่นๆ ดังนั้นจึงมองไปด้านหลังปุ่มตัวเลือกไฟล์

:where(input[type="file"]) {
  inline-size: 100%;
  max-inline-size: max-content;
  background-color: var(--_input-well);
}

ปุ่มตัวเลือกไฟล์และปุ่มประเภทอินพุตจะมีให้ appearance: none เพื่อนำสไตล์ที่เบราว์เซอร์ระบุมาออก ถูกเขียนทับด้วยปุ่มรูปแบบอื่นๆ

:where(input[type="button"]),
:where(input[type="file"])::file-selector-button {
  appearance: none;
}

สุดท้าย ระบบจะเพิ่มระยะขอบที่inline-endของปุ่มเพื่อดันข้อความระยะเวลา ห่างจากปุ่มเพื่อให้มีพื้นที่

:where(input[type="file"])::file-selector-button {
  margin-inline-end: var(--_padding-inline);
}

ภาพหน้าจอแสดงปุ่มหลังจากใช้รูปแบบก่อนหน้า

ข้อยกเว้นธีมสีเข้มพิเศษ

ฉันให้ปุ่มการทำงานหลักมีพื้นหลังสีเข้มขึ้นเพื่อคอนทราสต์ที่สูงขึ้น ทำให้พวกเขามีการโปรโมตมากขึ้นเล็กน้อย

@media (prefers-color-scheme: dark) {
  :where(
    [type="submit"],
    [type="reset"],
    [disabled],
    form button:not([type="button"])
  ) {
    --_bg: var(--_input-well);
  }
}

ภาพหน้าจอแสดงปุ่มหลังจากใช้รูปแบบก่อนหน้า

การสร้างตัวแปร

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

ปุ่มสด

เพื่อได้ปุ่มแบบนี้ ฉันก็แทนที่ของตกแต่งฐานด้วยสีฟ้าโดยตรง สีต่างๆ แม้ว่าการดำเนินการนี้จะรวดเร็วและง่ายดาย แต่ก็นำอุปกรณ์ประกอบฉากและรูปลักษณ์แบบปรับเปลี่ยนได้ออก เหมือนกันทั้งธีมสว่างและธีมมืด

.btn-custom {
  --_bg: linear-gradient(hsl(228 94% 67%), hsl(228 81% 59%));
  --_border: hsl(228 89% 63%);
  --_text: hsl(228 89% 100%);
  --_ink-shadow: 0 1px 0 hsl(228 57% 50%);
  --_highlight: hsl(228 94% 67% / 20%);
}

ปุ่มที่กำหนดเองจะแสดงแบบสว่างและมืด เป็นสีน้ำเงินที่สดใสมากเหมือนกับปุ่มการทำงานหลักทั่วไป

ปุ่มขนาดใหญ่

ปุ่มรูปแบบนี้ทำได้โดยการแก้ไขพร็อพเพอร์ตี้ที่กำหนดเอง --_size ระยะห่างจากขอบและองค์ประกอบพื้นที่อื่นๆ จะสัมพันธ์กับขนาดนี้ โดยจะปรับขนาดไปตาม ตามสัดส่วนกับขนาดใหม่

.btn-large {
  --_size: 1.5rem;
}

ปุ่มขนาดใหญ่จะแสดงอยู่ข้างปุ่มที่กำหนดเอง ซึ่งจะมีขนาดใหญ่กว่าประมาณ 150 เท่า

ปุ่มไอคอน

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

[data-icon="cloud"] {
  --icon-cloud: url("https://api.iconify.design/mdi:apple-icloud.svg") center / contain no-repeat;

  -webkit-mask: var(--icon-cloud);
  mask: var(--icon-cloud);
  background: linear-gradient(to bottom, var(--_accent-dark), var(--_accent-light));
}

ปุ่มที่มีไอคอนจะแสดงในธีมสว่างและธีมมืด

บทสรุป

ตอนนี้คุณก็รู้แล้วว่าฉันทำท่านั้นได้อย่างไร คุณจะทำยังไงบ้างคะ‽ 🙂

มาเพิ่มความหลากหลายให้กับแนวทางของเราและเรียนรู้วิธีทั้งหมดในการสร้างเนื้อหาบนเว็บกัน

สร้างลิงก์สาธิต ทวีตฉัน แล้วฉันจะเพิ่มให้เอง ที่ส่วนรีมิกซ์ของชุมชนด้านล่างนี้ได้เลย

รีมิกซ์ในชุมชน

ยังไม่มีอะไรให้ดูที่นี่

แหล่งข้อมูล