BEM สำหรับผู้เริ่มต้น: ทำไมคุณถึงต้องการ BEM

เผยแพร่แล้ว: 2022-03-10
สรุปโดยย่อ ↬ การแยกสไตล์ CSS เป็นจุดเริ่มต้นที่พบบ่อยที่สุดของการใช้ BEM แต่นี่คือสิ่งที่น้อยที่สุดที่ BEM สามารถให้คุณได้ BEM นำแนวทางระบบมาใช้ในโปรเจ็กต์ของคุณและป้องกันไม่ให้ยุ่งเหยิง

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

เราจะรวบรวมประเด็นหลักทั้งหมดของ BEM ในรูปแบบย่อ บทความนี้ช่วยให้คุณเข้าใจแนวคิดพื้นฐานของ BEM ในเวลาเพียง 20 นาที และเพื่อปฏิเสธอคติที่แนวทางของระบบเป็นอันตรายต่อโครงการของคุณ

Big BEM ประกอบด้วย ระเบียบวิธี เทคโนโลยี ห้องสมุด และ เครื่องมือ ในบทความนี้ เราจะพูดถึงวิธีการนี้มากขึ้น เนื่องจากเป็นประสบการณ์ที่เข้มข้นของนักพัฒนาจำนวนมาก และนำเสนอแนวทางที่เป็นระบบสำหรับโครงการใดๆ

เพื่อแสดงกรณีการใช้งานจริงของ BEM เราจะพูดถึงเทคโนโลยี BEM และข้ามไลบรารีและเครื่องมือโดยสมบูรณ์

จากทฤษฎีสู่การปฏิบัติ:

  • เหตุผลหลักว่าทำไมเราไม่ใช้ตัวเลือกใด ๆ ยกเว้นคลาส
  • พื้นฐานของ BEM
    • บล็อกและองค์ประกอบ
    • โมดิฟายเออร์และมิกซ์
    • บล็อกในโครงสร้างไฟล์
  • ข้อดีที่ไม่ชัดเจนของวิธีการ
  • กรณีปฏิบัติ: BEM ไม่ได้มีไว้สำหรับ CSS เท่านั้น
  • BEM เป็นระบบที่ปรับแต่งได้

สรุปว่า BEM เป็นฮีโร่หรือวายร้ายกันแน่? มันขึ้นอยู่กับคุณ! แต่ก่อนอื่น อ่านบทความ

BEM เป็นโลโก้แบทแมน
แบมแบม
เพิ่มเติมหลังกระโดด! อ่านต่อด้านล่าง↓

เหตุผลหลักว่าทำไมเราไม่ใช้ตัวเลือกใด ๆ ยกเว้นคลาส

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

  • ทำไมเราไม่ใช้ ID?
  • ทำไมเราไม่ใช้ตัวเลือกแท็ก
  • ทำไมเราไม่ใช้ตัวเลือกสากลล่ะ?
  • ทำไมเราไม่ใช้การรีเซ็ต CSS
  • ทำไมเราไม่ใช้ตัวเลือกที่ซ้อนกัน?
  • ทำไมเราไม่รวมแท็กและคลาสในตัวเลือกล่ะ
  • ทำไมเราไม่ใช้ตัวเลือกแบบรวม-
  • ทำไมเราไม่ใช้ตัวเลือกแอตทริบิวต์?

เราไม่ใช้ ID (ตัวเลือก ID)

รหัสระบุชื่อที่ไม่ซ้ำสำหรับองค์ประกอบ HTML หากชื่อไม่ซ้ำกัน คุณจะใช้ชื่อนั้นซ้ำในอินเทอร์เฟซไม่ได้ ซึ่งจะป้องกันไม่ให้คุณใช้รหัสซ้ำ

ความเข้าใจผิดที่พบบ่อย

  1. ต้องใช้รหัสเพื่อใช้ JavaScript
    เบราว์เซอร์สมัยใหม่สามารถทำงานกับ ID หรือคลาสใดก็ได้ ตัวเลือกประเภทใดก็ตามจะได้รับการประมวลผลในอัตราเดียวกันในเบราว์เซอร์
  2. ID ใช้กับแท็ก <label>
    หากคุณวาง <label> ไว้ในตัวควบคุม ก็ไม่จำเป็นต้องใช้ ID แทนที่จะใช้ <input id="ID"><label for="ID">Text</label> ให้ใช้ <label><input type="...">Text</label>

เราไม่ใช้ตัวเลือกแท็ก

มาร์กอัปหน้า HTML ไม่เสถียร: การออกแบบใหม่สามารถเปลี่ยนการซ้อนส่วน ระดับส่วนหัว (เช่น จาก <h1> เป็น <h3> ) หรือเปลี่ยนย่อหน้า <p> เป็นแท็ก <div> การเปลี่ยนแปลงใดๆ เหล่านี้จะทำลายสไตล์ที่เขียนขึ้นสำหรับแท็ก แม้ว่าการออกแบบจะไม่เปลี่ยนแปลง แต่ชุดแท็กก็มีจำกัด หากต้องการใช้เลย์เอาต์ที่มีอยู่ในโปรเจ็กต์อื่น คุณต้องแก้ไขข้อขัดแย้งระหว่างสไตล์ที่เขียนขึ้นสำหรับแท็กเดียวกัน

ชุดแท็กความหมายแบบขยายไม่สามารถตอบสนองความต้องการด้านเลย์เอาต์ทั้งหมดได้เช่นกัน

ตัวอย่างคือเมื่อส่วนหัวของหน้ามีโลโก้ การคลิกที่โลโก้จะเปิดหน้าหลักของเว็บไซต์ ( index ) คุณสามารถทำเครื่องหมายด้วยแท็กโดยใช้แท็ก <img> สำหรับรูปภาพและแท็ก <a> สำหรับลิงก์

 <header> <a href="/"> <img src="img.logo.png" alt="Logo"> </a> </header>

หากต้องการแยกความแตกต่างระหว่างลิงก์โลโก้และลิงก์ธรรมดาในข้อความ คุณต้องมีรูปแบบเพิ่มเติม ตอนนี้ลบการขีดเส้นใต้และสีน้ำเงินออกจากลิงค์โลโก้:

 header a { ... }

ลิงค์โลโก้ไม่จำเป็นต้องแสดงบนหน้าหลัก ดังนั้นให้เปลี่ยนมาร์กอัปหน้าดัชนี:

 <header> <!-- the <a> tag is replaced with <span> --> <span> <img src="img.logo.png" alt="Logo"> </span> </header>

คุณไม่จำเป็นต้องลบการขีดเส้นใต้และสีน้ำเงินสำหรับแท็ก <span> เรามาสร้างกฎทั่วไปสำหรับลิงค์โลโก้จากหน้าต่างๆ กัน:

 header a, header span { ... }

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

เพื่อหลีกเลี่ยงความสับสน เพียงใช้ตัวเลือกคลาส logo เพื่อเขียนลักษณะโลโก้:

 .logo { ... }

เราไม่ใช้การรีเซ็ต CSS

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

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

เราไม่ใช้ตัวเลือกสากล ( * )

ตัวเลือกสากลบ่งชี้ว่าโปรเจ็กต์มีลักษณะที่มีผลกับโหนดทั้งหมดในเลย์เอาต์ สิ่งนี้จำกัดการนำเค้าโครงมาใช้ซ้ำในโปรเจ็กต์อื่น:

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

นอกจากนี้ Universal Selector ยังทำให้รหัสโครงการคาดเดาไม่ได้ ตัวอย่างเช่น อาจส่งผลต่อรูปแบบของคอมโพเนนต์ไลบรารีสากล

สไตล์ทั่วไปไม่ได้ช่วยให้คุณประหยัดเวลา นักพัฒนามักจะเริ่มต้นด้วยการรีเซ็ตระยะขอบทั้งหมดสำหรับส่วนประกอบ ( * { margin: 0; padding: 0; } ) แต่พวกเขายังคงตั้งค่าเหมือนเดิมในเลย์เอาต์ (เช่น margin: 12px; padding: 30px; )

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

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

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

 .button_hovered .button__text { text-decoration: underline; } .button_theme_islands .button__text { line-height: 1.5; }

เราไม่ใช้ตัวเลือกรวม

ตัวเลือกแบบรวมมีความเฉพาะเจาะจงมากกว่าตัวเลือกเดียว ซึ่งทำให้ยากต่อการกำหนดบล็อกใหม่

พิจารณารหัสต่อไปนี้:

 <button class="button button_theme_islands">...</button>

สมมติว่าคุณตั้งกฎ CSS ในตัวเลือก .button.button_theme_islands เพื่อเขียนน้อยลง จากนั้นคุณเพิ่มตัวแก้ไข "ใช้งานอยู่" ให้กับบล็อก:

 <button class="button button_theme_islands button_active">...</button>

ตัวเลือก .button_active ไม่ได้กำหนดคุณสมบัติของบล็อกใหม่ซึ่งเขียนเป็น .button.button_theme_islands เนื่องจาก .button.button_theme_islands มีความเฉพาะเจาะจงมากกว่า . .button_active หากต้องการกำหนดใหม่ ให้รวมตัวเลือกตัวแก้ไขบล็อกเข้ากับตัวเลือก .button และประกาศไว้ใต้ .button.button_theme_islands เนื่องจากตัวเลือกทั้งสองมีความเฉพาะเจาะจงเท่ากัน:

 .button.button_theme_islands {} .button.button_active {}

หากคุณใช้ตัวเลือกคลาสอย่างง่าย คุณจะไม่มีปัญหาในการกำหนดสไตล์ใหม่:

 .button_theme_islands {} .button_active {} .button {}

เราไม่รวมแท็กและคลาสไว้ในตัวเลือก

การรวมแท็กและคลาสในตัวเลือกเดียวกัน (เช่น button.button ) ทำให้กฎ CSS มีความเฉพาะเจาะจงมากขึ้น ดังนั้นจึงยากต่อการกำหนดใหม่

พิจารณารหัสต่อไปนี้:

 <button class="button">...</button>

สมมติว่าคุณตั้งกฎ CSS ในตัวเลือก button.button จากนั้นคุณเพิ่มตัวแก้ไขที่ active ในบล็อก:

 <button class="button button_active">...</button>

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

ในขณะที่โปรเจ็กต์พัฒนาขึ้น คุณอาจลงเอยด้วยบล็อกด้วยตัวเลือก input.button , span.button หรือ a.button ในกรณีนี้ ตัวปรับแต่งทั้งหมดของบล็อค button และองค์ประกอบที่ซ้อนกันทั้งหมดจะต้องมีการประกาศสี่แบบที่แตกต่างกันสำหรับแต่ละอินสแตนซ์

ข้อยกเว้นที่เป็นไปได้

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

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

 <div class="content"> ... <!-- the user's text --> </div> CSS rules: .content a { ... } .content p { font-family: Arial, sans-serif; text-align: center; }

เราไม่ใช้ตัวเลือกแอตทริบิวต์

ตัวเลือกแอตทริบิวต์มีข้อมูลน้อยกว่าตัวเลือกชั้นเรียน เพื่อเป็นหลักฐาน ให้พิจารณาตัวอย่างด้วยแบบฟอร์มการค้นหาในส่วนหัว:

 <header> <form action="/"> <input name="s"> <input type="submit"> </form> </header>

ลองใช้แอตทริบิวต์ selector เพื่อเขียนรูปแบบแบบฟอร์ม:

 header input[type=submit], header input[type=checkbox] { width: auto; margin-right: 20px; } header input[type=checkbox] { margin: 0; }

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

 .form .search { ... }

ตอนนี้โค้ดมีความคลุมเครือน้อยลง และเห็นได้ชัดว่าสไตล์เป็นของแบบฟอร์มการค้นหา

แต่ตัวเลือกที่ซ้อนกันยังคงทำให้กฎ CSS มีความเฉพาะเจาะจงมากขึ้น และป้องกันไม่ให้คุณถ่ายโอนเค้าโครงระหว่างโปรเจ็กต์ ในการกำจัดการทำรัง ให้ใช้หลักการ BEM

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

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

พื้นฐานของ BEM

  • บล็อกและองค์ประกอบ
  • โมดิฟายเออร์และมิกซ์
  • บล็อกในโครงสร้างไฟล์

บล็อกและองค์ประกอบ

วิธีการ BEM คือชุดของกฎสากลที่สามารถนำมาใช้โดยไม่คำนึงถึงเทคโนโลยีที่ใช้ เช่น CSS, Sass, HTML, JavaScript หรือ React

BEM ช่วยแก้ไขงานต่อไปนี้:

  • ใช้เค้าโครงซ้ำ
  • ย้ายส่วนย่อยของโครงร่างไปรอบๆ ภายในโปรเจ็กต์อย่างปลอดภัย
  • ย้ายเลย์เอาต์ที่เสร็จแล้วระหว่างโปรเจ็กต์
  • สร้างโค้ดที่เสถียร คาดเดาได้ และชัดเจน
  • ลดเวลาการดีบักโครงการ

ในโครงการ BEM อินเทอร์เฟซประกอบด้วยบล็อกที่สามารถรวมองค์ประกอบได้ บล็อกเป็นส่วนประกอบที่เป็นอิสระของหน้า องค์ประกอบไม่สามารถอยู่นอกบล็อกได้ ดังนั้น พึงระลึกว่าแต่ละองค์ประกอบสามารถอยู่ในบล็อกเดียวเท่านั้น

ตัวอักษรสองตัวแรกใน BEM ย่อมาจาก B locks และ E lements ชื่อบล็อกไม่ซ้ำกันเสมอ มันตั้งค่าเนมสเปซสำหรับองค์ประกอบและให้การเชื่อมต่อที่มองเห็นได้ระหว่างส่วนต่าง ๆ ของบล็อก ชื่อบล็อกจะยาวแต่ชัดเจน เพื่อแสดงการเชื่อมต่อระหว่างส่วนประกอบ และเพื่อหลีกเลี่ยงการสูญเสียส่วนใดส่วนหนึ่งของส่วนประกอบเหล่านี้เมื่อถ่ายโอนเค้าโครง

หากต้องการดูพลังเต็มที่ของการตั้งชื่อ BEM ให้พิจารณาตัวอย่างนี้ด้วยแบบฟอร์ม ตามวิธีการของ BEM แบบฟอร์มจะดำเนินการโดยใช้บล็อกของ form ใน HTML ชื่อบล็อกจะรวมอยู่ในแอตทริบิวต์ class :

 <form class="form" action="/">

ทุกส่วนของแบบฟอร์ม (บล็อกของ form ) ที่ไม่สมเหตุสมผลในตัวเองถือเป็นองค์ประกอบ ดังนั้นช่องค้นหา ( search ) และปุ่ม ( send ) จึงเป็นองค์ประกอบ form บล็อค submit คลาสยังระบุด้วยว่าองค์ประกอบนั้นเป็นของบล็อก:

 <form class="form" action="/"> <input class="form__search" name="s"> <input class="form__submit" type="submit"> </form>

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

ชื่อตัวเลือกทำให้ชัดเจนว่าในการย้ายแบบฟอร์มไปยังโครงการอื่น คุณต้องคัดลอกส่วนประกอบทั้งหมด:

 .form__search {} .form__submit {}

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

แนวคิดในการตั้งชื่อส่วนประกอบ BEM คือคุณสามารถกำหนดการเชื่อมต่อระหว่างบล็อกและองค์ประกอบได้อย่างชัดเจน

โมดิฟายเออร์และมิกซ์

อย่างเป็นทางการ “M” ย่อมาจาก M odifier แต่ยังแสดงถึงแนวคิดที่สำคัญอีกประการหนึ่งใน BEM: “mix” ทั้งตัวดัดแปลงและส่วนผสมทำการเปลี่ยนแปลงบล็อกและองค์ประกอบของบล็อก ลองมาดูเรื่องนี้กันดีกว่า

ตัวดัดแปลง

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

มาดูกันว่าตัวปรับแต่งทำงานอย่างไร

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

 header .form {} footer .form {}

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

ใน BEM คุณสามารถใช้ตัวปรับแต่งเพื่อเพิ่มรูปแบบใหม่ให้กับบล็อก:

 <!-- Added the form_type_original modifier--> <form class="form form_type_original" action="/"> <input class="form__search" name="s"> <input class="form__submit" type="submit"> </form>

บรรทัด <form class="form form_type_original"></form> ระบุว่าบล็อกนั้นถูกกำหนดตัวแก้ไข type ด้วยค่า original ในรูปแบบคลาสสิก ชื่อตัวแก้ไขจะถูกแยกจากชื่อบล็อกหรือองค์ประกอบด้วยขีดล่าง

แบบฟอร์มสามารถมีสี ขนาด ชนิด หรือธีมการออกแบบที่ไม่ซ้ำกัน พารามิเตอร์ทั้งหมดเหล่านี้สามารถตั้งค่าได้ด้วยตัวปรับแต่ง:

 <form class="form form_type_original form_size_m form_theme_forest"> <form class="form form_type_original form_size_m form_theme_forest">

รูปทรงเดียวกันอาจดูแตกต่างออกไปแต่ยังคงขนาดเท่าเดิม:

 <form class="form form_type_original form_size_m form_theme_forest"></form> <form class="form form_type_original form_size_m form_theme_sun"></form>

แต่ตัวเลือกสำหรับตัวปรับแต่งแต่ละตัวจะยังคงมีน้ำหนักเท่าเดิม:

 .form_type_original {} .form_size_m {} .form_theme_forest {}

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

 .form { /* universal block styles */ } .form_type_original { /* added styles */ }

นี่คือเหตุผลที่ตัวปรับแต่งควรอยู่บนโหนด DOM เดียวกันกับบล็อกและองค์ประกอบที่เกี่ยวข้องเสมอ

 <form class="form form_type_original"></form>

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

มิกซ์

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

การผสมผสานหมายความว่าคุณโฮสต์เอนทิตี BEM หลายรายการ (บล็อก องค์ประกอบ ตัวดัดแปลง) บนโหนด DOM เดียว คล้ายกับตัวดัดแปลง มิกซ์ใช้สำหรับเปลี่ยนบล็อก ลองดูตัวอย่างว่าคุณควรใช้มิกซ์เมื่อใด

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

 .form, .search, .register { ... }

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

 <form class="form" action="/"> <input class="form__search" name="s"> <input class="form__submit" type="submit"> </form>

ตัวเลือกคลาส .form อธิบายสไตล์ทั้งหมดที่สามารถนำไปใช้กับแบบฟอร์มใดก็ได้ (การสั่งซื้อ การค้นหา หรือการลงทะเบียน):

 .form {}

ตอนนี้คุณสามารถสร้างแบบฟอร์มการค้นหาจากแบบฟอร์มสากล เมื่อต้องการทำสิ่งนี้ ให้สร้างคลาส search เพิ่มเติมในโปรเจ็กต์ คลาสนี้จะรับผิดชอบเฉพาะการค้นหาเท่านั้น ในการรวมสไตล์และการทำงานของ .form และ .search เข้าด้วยกัน ให้วางคลาสเหล่านี้บนโหนด DOM เดียว:

 <form class="form search" action="/"> <input class="form__search" name="s"> <input class="form__submit" type="submit"> </form>

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

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

 <nav class="menu"> <a class="link" href=""></a> <a class="link" href=""></a> <a class="link" href=""></a> </nav>

ฟังก์ชันลิงก์ถูกนำไปใช้ในบล็อก link แล้ว แต่ลิงก์เมนูต้องแตกต่างจากลิงก์ในข้อความอย่างเห็นได้ชัด มีหลายวิธีในการเปลี่ยนลิงก์เมนู:

  1. สร้างตัวแก้ไขรายการเมนูที่เปลี่ยนรายการเป็นลิงค์:
     <nav class="menu"> <a class="menu__item menu__item_link" href=""></a> <a class="menu__item menu__item_link" href=""></a> <a class="menu__item menu__item_link" href=""></a> </nav>

    ในกรณีนี้ ในการใช้งานตัวแก้ไข คุณควรคัดลอกพฤติกรรมและสไตล์ของบล็อก "ลิงก์" นี้จะนำไปสู่การทำซ้ำรหัส
  2. ใช้การผสมผสานระหว่าง "ลิงก์" บล็อกสากลและองค์ประกอบ "รายการ" ของบล็อก "เมนู":
     <nav class="menu"> <a class="link menu__item" href=""></a> <a class="link menu__item" href=""></a> <a class="link menu__item" href=""></a> </nav>

    ด้วยการผสมผสานระหว่างเอนทิตี BEM ทั้งสอง ขณะนี้คุณสามารถใช้ฟังก์ชันลิงก์พื้นฐานจากบล็อก "ลิงก์" และกฎ CSS เพิ่มเติมจากบล็อก "เมนู" และหลีกเลี่ยงการทำซ้ำโค้ดได้

เรขาคณิตภายนอกและการวางตำแหน่ง: เลิกใช้ HTML Wrappers ที่เป็นนามธรรม

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

งานนี้มีวิธีแก้ไขปัญหาหลายประการ:

  1. เขียนสไตล์ด้วยการเยื้องสำหรับบล็อกเมนู:
     .menu { margin-left: 20px; }

    ในกรณีนี้ บล็อก "เมนู" จะไม่เป็นแบบสากลอีกต่อไป หากคุณต้องวางเมนูไว้ในส่วนท้ายของหน้า คุณจะต้องแก้ไขสไตล์เพราะการเยื้องอาจแตกต่างกัน
  2. สร้างตัวแก้ไขบล็อกเมนู:
     <div> <ul class="menu menu_type_header"> <li class="menu__item"><a href=""></a></li> <li class="menu__item"><a href=""></a></li> <li class="menu__item"><a href=""></a></li> </ul> </div>
     .menu_type_header { margin-left: 20px; } .menu_type_footer { margin-left: 30px; }

    ในกรณีนี้ โครงการจะรวมเมนูสองประเภท แม้ว่าจะไม่ใช่กรณีนี้ก็ตาม เมนูยังเหมือนเดิม
  3. กำหนดตำแหน่งภายนอกของบล็อก: ซ้อนบล็อก "เมนู" ในแรปเปอร์นามธรรม (เช่น บล็อก "ตัด") โดยตั้งค่าการเยื้องทั้งหมด:
     <div class="wrap"> <ul class="menu"> <li class="menu__item"><a href=""></a></li> <li class="menu__item"><a href=""></a></li> <li class="menu__item"><a href=""></a></li> </ul> </div>

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

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

ไปต่อด้วยตัวอย่างของเรา:

 <div> <ul class="menu header__menu"> <li class="menu__item"><a href=""></a></li> <li class="menu__item"><a href=""></a></li> <li class="menu__item"><a href=""></a></li> </ul> </div>

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

องค์ประกอบบล็อกหลัก (ในกรณีของเราคือ header__menu ) ทำงานของ wrapper block ที่รับผิดชอบการวางตำแหน่งภายนอกของบล็อก

บล็อกในโครงสร้างไฟล์

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

การใช้งานแต่ละบล็อกจะถูกเก็บไว้ในโฟลเดอร์โครงการแยกต่างหาก แต่ละเทคโนโลยี (CSS, JavaScript, การทดสอบ, เทมเพลต, เอกสารประกอบ, รูปภาพ) อยู่ในไฟล์แยกต่างหาก

ตัวอย่างเช่น หากตั้งค่าลักษณะที่ปรากฏของบล็อก input ด้วย CSS โค้ดจะถูกบันทึกในไฟล์ input.css

 project common.blocks/ input/ input.css # The "input" block implementation with CSS input.js # The "input" block implementation with JavaScript

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

 project common.blocks/ input/ input.css # The "input" block implementation with CSS input.js # The "input" block implementation with JavaScript input_theme_sun.css # The "input_theme_sun" modifier implementation input__clear.css # The "input__clear" element implementation with CSS input__clear.js # The "input__clear" element implementation with JavaScript

ในการปรับปรุงการนำทางของโปรเจ็กต์ ให้รวมตัวดัดแปลงบล็อกเข้ากับหลายค่าในไดเร็กทอรี

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

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

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

ข้อดีที่ไม่ชัดเจนของวิธีการ

ความสะดวกสบายของการพัฒนาแบบคู่ขนาน

ใน BEM เลย์เอาต์ใดๆ จะถูกแบ่งออกเป็นบล็อค เนื่องจากบล็อกต่างๆ เป็นอิสระจากกัน นักพัฒนาหลายคนจึงสามารถพัฒนาไปพร้อม ๆ กันได้

นักพัฒนาสร้างบล็อกเป็นองค์ประกอบสากลที่สามารถนำกลับมาใช้ใหม่ในโครงการอื่นได้

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

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

การทดสอบเค้าโครง

การทดสอบการทำงานของทั้งเพจเป็นปัญหา โดยเฉพาะในโปรเจ็กต์ไดนามิกที่เชื่อมต่อกับฐานข้อมูล

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

สร้างโครงการที่ปรับแต่งได้

เพื่อการพัฒนาที่สะดวก บล็อกและเทคโนโลยีทั้งหมดในโครงการ BEM จะอยู่ในโฟลเดอร์และไฟล์ที่แยกจากกัน ในการรวมไฟล์ต้นฉบับเป็นไฟล์เดียว (เช่น เพื่อใส่ไฟล์ CSS ทั้งหมดไว้ใน project.css ไฟล์ JS ทั้งหมดใน project.js เป็นต้น) เราใช้กระบวนการสร้าง

บิลด์ดำเนินการงานต่อไปนี้:

  • รวมไฟล์ต้นฉบับที่กระจายไปทั่วระบบไฟล์ของโปรเจ็กต์
  • รวมเฉพาะบล็อก องค์ประกอบ และตัวปรับแต่งที่จำเป็น (เอนทิตี BEM) ในโครงการ
  • ปฏิบัติตามคำสั่งสำหรับการรวมเอนทิตี
  • ประมวลผลซอร์สไฟล์โค้ดระหว่างบิลด์ (เช่น คอมไพล์โค้ด LESS เป็นโค้ด CSS)

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

เนื่องจากบล็อก BEM ได้รับการพัฒนาอย่างอิสระและวางไว้ในไฟล์แยกกันในระบบไฟล์ พวกเขาจึงไม่ได้ 'รู้' อะไรเกี่ยวกับกันและกัน หากต้องการสร้างบล็อกตามบล็อกอื่นๆ ให้ระบุการพึ่งพา มีเทคโนโลยี BEM ที่รับผิดชอบในเรื่องนี้: ไฟล์ deps.js ไฟล์การขึ้นต่อกันทำให้เอ็นจินการสร้างรู้ว่าบล็อกเพิ่มเติมใดบ้างที่ต้องรวมไว้ในโปรเจ็กต์

กรณีปฏิบัติ: BEM ไม่ได้มีไว้สำหรับ CSS เท่านั้น

ในส่วนก่อนหน้านี้ ตัวอย่างโค้ดทั้งหมดมีไว้สำหรับ CSS แต่ BEM ให้คุณปรับเปลี่ยนพฤติกรรมของบล็อกและการแสดงข้อมูลใน HTML ในลักษณะการประกาศเช่นเดียวกับใน CSS

วิธีการใช้เทมเพลตใน BEM

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

เทมเพลตช่วยให้คุณ:

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

BEM ใช้เครื่องมือเทมเพลต bem-xjst ซึ่งมีเอ็นจิ้นสองตัว:

  • BEMHTML
    แปลงคำอธิบาย BEMJSON ของหน้าเป็น HTML เทมเพลตมีอธิบายไว้ในไฟล์ .bemhtml.js
  • เบมทรี
    แปลงข้อมูลเป็น BEMJSON เทมเพลตมีคำอธิบายในรูปแบบ BEMJSON ในไฟล์ .bemtree.js

หากไม่ได้เขียนเทมเพลตสำหรับบล็อก เครื่องมือเทมเพลตจะตั้งค่าแท็ก <div> สำหรับบล็อกตามค่าเริ่มต้น

เปรียบเทียบการประกาศของบล็อกและผลลัพธ์ HTML:

ประกาศ:

 { block: 'menu', content: [ { elem: 'item', content: { block: 'link'} }, { elem: 'item', elemMods: { current: true }, // Set the modifier for the menu item content: { block: 'link' } } ] }

HTML:

 <div class="menu"> <div class="menu__item"> <div class="link"></div> </div> <div class="menu__item menu__item_current"> <div class="link"></div> </div> </div>

ในการแก้ไขเค้าโครงบล็อก menu คุณต้องเขียนเทมเพลตสำหรับบล็อก:

  1. มาเปลี่ยนแท็กบล็อก menu :
     block('menu')( tag()('menu') // Set the "menu" tag for the menu block )

    แก้ไข HTML:
     <menu class="menu"> <!-- Replace the "div" tag with the "menu" tag for the "menu" block --> <div class="menu__item"> <div class="link"></div> </div> <div class="menu__item menu__item_current"> <div class="link"></div> </div> </menu>

    เช่นเดียวกับ CSS เทมเพลตจะนำไปใช้กับบล็อก "เมนู" ทั้งหมดบนหน้า
  2. เพิ่มองค์ประกอบพิเศษ ( menu__inner ) ที่ทำงานเป็น wrapper ภายในและรับผิดชอบเลย์เอาต์ขององค์ประกอบในบล็อก menu เดิมทีองค์ประกอบ menu__inner ไม่ได้รวมอยู่ในการประกาศ ดังนั้นเราต้องเพิ่มเข้าไปเมื่อสร้างเทมเพลต

    เทมเพลต BEM เขียนด้วย JavaScript ดังนั้นคุณจึงสามารถใช้ JavaScript เพื่อเพิ่มองค์ประกอบใหม่ลงในเทมเพลตได้:
     block('menu')( tag()('menu'), content()(function() { return { elem: 'inner', content: this.ctx.content }; }) )
     <menu class="menu"> <!-- Replace the "div" tag with the "menu" tag for the "menu" block --> <div class="menu__inner"> <div class="menu__item"> <div class="link"></div> </div> <div class="menu__item menu__item_current"> <div class="link"></div> </div> </div> </menu>
  3. แทนที่แท็กสำหรับองค์ประกอบ inner และ item ทั้งหมด:
     block('menu')( tag()('menu'), content()(function() { return { elem: 'inner', content: this.ctx.content } }), elem('inner')( tag()('ul') ), elem('item')( tag()('li') ) )
     <menu class="menu"> <ul class="menu__inner"> <li class="menu__item"> <div class="link"></div> </li> <li class="menu__item menu__item_current"> <div class="link"></div> </li> </ul> </menu>
  4. ตั้งค่าแท็ก <a> สำหรับลิงก์ทั้งหมดบนหน้า:
     block('menu')( tag()('menu'), content()(function() { return { elem: 'inner', content: this.ctx.content } }), elem('inner')( tag()('ul') ), elem('item')( tag()('li') ) ); block('link')( tag()('a') );
     <menu class="menu"> <ul class="menu__inner"> <li class="menu__item"> <a class="link"></a> </li> <li class="menu__item menu__item_current"> <a class="link"></a> </li> </ul> </menu>
  5. แก้ไขเทมเพลตที่มีอยู่ กฎในเทมเพลตถูกนำไปใช้ในลักษณะเดียวกับใน CSS: กฎที่ต่ำกว่าจะแทนที่กฎที่สูงกว่า เพิ่มกฎใหม่ให้กับเทมเพลต และเปลี่ยนแท็กลิงก์จาก <a> เป็น <span> :
     block('link')( tag()('a') ); block('link')( tag()('span') );
     <menu class="menu"> <ul class="menu__inner"> <li class="menu__item"> <span class="link"></span> </li> <li class="menu__item menu__item_current"> <span class="link"></span> </li> </ul> </menu>

BEM เป็นระบบที่ปรับแต่งได้

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

ตอนนี้คุณสามารถปรับแต่งระบบและสร้างซูเปอร์ฮีโร่ BEM ของคุณเองได้!

BEM เป็นโลโก้กัปตันอเมริกา
BEM กัปตันอเมริกา

ทำอย่างไรจึงจะได้ประโยชน์จาก BEM . มากขึ้น

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