乾淨的代碼:為什麼 HTML/CSS 基礎仍然很重要
已發表: 2022-03-11在我 15 年的 Web 開發經驗中,我曾與各種公司合作過,從企業級到初創公司,一路上我與許多軟件工程師同行。 我在項目中遇到的最常見和最重要的問題之一是未能編寫乾淨且易於理解的代碼。
即使是來自一流公司的最優秀的開發人員也並不總是遵循最佳實踐並編寫可以清理和優化的代碼。
混亂和骯髒代碼的後果
引用一篇討論乾淨代碼原則的舊但仍然相關的博客文章:
源代碼類似於金融債務。 假設你想買房子住。大多數人沒有足夠的資金來買房,所以你選擇抵押貸款。 但抵押貸款本身並不是一件好事。 這是一種責任。 你每個月都必須為你的債務支付利息……
在 Web 開發中也是如此。 該代碼有持續的成本。 你必須理解它,你必須維護它,你必須隨著時間的推移使其適應新的目標。 您擁有的代碼越多,這些持續成本就會越大。 擁有盡可能少的源代碼,同時仍然能夠實現我們的業務目標,這符合我們的最大利益。
但我們不要停留在抽像上。 本文將介紹基本的干淨代碼原則、用於組織代碼的不同技術,以及如何使其更易於維護、可擴展和更易於調試。
高質量的代碼從基本的代碼樣式開始,擴展到使用 HTML/CSS 編寫具有許多可重用塊的大型應用程序時的最佳實踐,我們還將討論命名約定以創建更大的隱式可讀性以及第三方框架及其最佳實踐。
當你讀完這篇文章時,你應該對質量代碼的基礎知識以及如何使你的 HTML 和 CSS 代碼更容易維護和擴展有了很好的理解。
代碼樣式要點
讓我們從良好的 HTML 和 CSS 代碼的基礎開始:W3C 有效性、命名約定、文件結構等。
從第一天起就注意結構。
如果您要開發一個大型應用程序,那麼您需要注意文件結構。 它可以,或者更確切地說,應該是這樣的:
使用驗證器檢查您的代碼。
嘗試始終使用 HTML 和 CSS 驗證器。
錯誤代碼:
<figure> <div> <img src="demo.jpg" alt=""> <figcaption> <h2>Hello world</h2> </figcaption> </div> </figure> <picture> <source src="demo.webp" type="image/webp"> <img src="demo.jpg" alt=""> </picture> <details> <header> <summary>Expand details</summary> </header> <p>All content goes here</p> </details> p { font: 400 inherit/1.125 serif; }好代碼:
<figure> <img src="demo.jpg" alt=""> <!-- figcaption should be child of element figure element, not div --> <figcaption> <h2>Hello world</h2> </figcaption> </figure> <picture> <!-- source should have srcset attribute --> <source type="image/webp"> <img src="demo.jpg" alt=""> </picture> <details> <!-- summary is not allowed as child of header --> <summary>Expand details</summary> <p>All content goes here</p> </details> p { font-weight: 400; font-size: inherit; line-height: 1.125; font-family: serif; } 使用<img>標記上的替代文本來保證乾淨代碼原則的有效性。
該屬性對 SEO、搜索引擎、網絡爬蟲、屏幕閱讀器等起著至關重要的作用。
錯誤代碼:
<img src="demo.jpg">好代碼:
<img src="demo.jpg" alt="This is placeholder of the image">使用 kebab-case(脊椎病例)。
對於名稱,請嘗試使用kebab-case ( spinal-case ) 而不要使用camelCase或under_score 。 僅在使用 BEM 時使用under_score ,但如果您使用 Bootstrap,最好保持一致並使用-作為分隔符。
錯誤代碼:
<section class="section_featured_Listing"> <h1 class="largeTitle">H1 title</h1> </section>好代碼:
<section class="section-featured-listing"> <h1 class="large-title">H1 title</h1> </section> kebab kebab-case比camelCase和under_score更具可讀性。
使用任何人都可以理解的有意義的名稱,並保持簡短。
類的名稱應該類似於.noun-adjective 。
嘗試使用類的通用名稱,而不是編寫特定於內容的名稱。 它使代碼更具可讀性
錯誤代碼:
<div class="team-wrapper"> <button class="large-button-green"></button> <p class="greenText-john-smith-description"></p> <div class="white-bg"></div> </div>好代碼:
<div class="section-team"> <button class="btn-lg btn-success"></button> <p class="text-success"></p> <div class="bg-white"></div> </div>不要在 HTML5 中為樣式表和腳本編寫類型屬性。
HTML5不需要它們,但 HTML4/XHTML 中的 W3C 標準要求它們。
錯誤代碼:
<link type="text/css" rel="stylesheet" href="../styles.css"> <script type="text/javascript" src="..//main.js"></script>好代碼:
<link rel="stylesheet" href="styles.css"> <script src="app.js"></script>必要時使用特定的類。
保持 CSS 選擇器更具體,並選擇您需要的元素; 如果沒有必要,盡量不要提及他們的父母。 它將允許代碼更快地呈現並消除將來的任何管理障礙
錯誤代碼:
section aside h1 span { margin-left: 25%; }好代碼:
.left-offset { margin-left: 25%; }雖然將類應用到目標元素可能會在 HTML 中創建更多代碼,但它將允許代碼更快地呈現並消除任何管理障礙。
如果您想為同一個塊提供另一種樣式,請向父元素添加一個類。
如果您需要使用相同的塊但具有不同的樣式,請盡量保持 HTML 不變。 只需將一個類添加到父元素並將所有新樣式應用到 CSS 中該類的子元素。
錯誤代碼:
<article> <h1>Same section with another styles</h1> <p>Lorem ipsum dolor sit amet, lorem sit eget proin id ipsum. </p> … </article> <article class=”another-article”> <h1 class=”other-styling-title”>Same section with another styles</h1> <p>Lorem ipsum dolor sit amet, lorem sit eget proin id ipsum. </p> … </article> article { padding: 10px 15px; h1 { font-size: 32px; color: #ff0000; } } .another-article { padding-bottom: 30px; border-bottom: 4px solid #ccc; } h1.other-styling-title { font-size: 20px; }好代碼:
<article> <h1>Same section with another styles</h1> <p>Lorem ipsum dolor sit amet, lorem sit eget proin id ipsum. </p> … </article> <article class=”other-styling”> <h1>Same section with another styles</h1> <p>Lorem ipsum dolor sit amet, lorem sit eget proin id ipsum. </p> … </article> article { padding: 10px 15px; h1 { font-size: 32px; color: #ff0000; } &.other-styling { padding-bottom: 30px; border-bottom: 4px solid #ccc; /* you will have less classes */ h1 { font-size: 20px; } } }從零值中刪除單位。
添加單位是不必要的,並且不會提供額外的價值。 0px、0em、0% 或任何其他零值之間沒有區別。 單位並不重要,因為值仍然為零。
錯誤代碼:
div { margin: 20px 0px; letter-spacing: 0%; padding: 0px 5px; }好代碼:
div { margin: 20px 0; letter-spacing: 0; padding: 0 5px; } 如果可以添加hr標籤,請不要在 CSS 中編寫border-bottom 。
使用hr標籤而不是編寫新的選擇器並在 CSS 中添加邊框樣式。 它使代碼更加基於標記,這就是我們的目標。
錯誤代碼:
<p class="border-bottom">I want this section to have a border.</p> <p>Lorem ipsum</p> .border-bottom { border-bottom: 1px solid #000; }好代碼:
<p>I want this section to have a border.</p> <hr> <p>Lorem ipsum</p> // If necessary change hr variable in bootstrap使用 A > B 選擇器。
使用A > B選擇器非常有幫助,它僅將規則應用於直接子項(ren),在這種情況下,您不必重置不需要該樣式的所有其他子項的樣式。 例如,它在編碼嵌套菜單時非常有用。 您無需重新定義子菜單樣式。
錯誤代碼:
<ul> <li>List 1</li> <li>List 2</li> <li>List 3 <ul> <li>Submenu 1</li> <li>Submenu 2</li> </ul> </li> </ul> ul li { list-style-type: none; } li ul li { /* redefine to default value */ list-style-type: disc; }好代碼:
<ul> <li>List 1</li> <li>List 2</li> <li>List 3 <ul> <li>Submenu 1</li> <li>Submenu 2</li> </ul> </li> </ul> ul > li { list-style-type: none; }如何編寫乾淨的 HTML
繼續討論 HTML,首要任務是確保一個健壯且易於維護的前端。
嘗試擁有一個盡可能基於標記的前端。
使您的前端代碼基於標記,而不是編寫過多的 CSS。
這將有助於搜索引擎並使您的代碼更具可讀性,從而可能提高搜索排名和用戶體驗。
錯誤代碼:
<div class="main-content"> <p class="content-title">Main text title</p> <img src="http://via.placeholder.com/150x150" alt="example"> <p class="image-description">Here is image description</p> </div>好代碼:
<main> <h1>Main text title</h1> <figure> <img src="http://via.placeholder.com/150x150" alt="example"> <figcaption> Here is image description </figcaption> </figure> </main>避免在 HTML 中使用不必要的包裝器。
盡量不要在 HTML 中使用不必要的包裝元素。 擁有大量的<div>和<span>元素已成為過去。 保持細化和線性使您能夠實現最少的代碼(見下一點)。
錯誤代碼:
<section class=”container”> <div class=”row”> <div class=”col-xs-12”> <div class=”inner-wrapper”> <span>Unnecessary br tags</span> </div> </div> </div> </section>好代碼:
<section class=”container”> <p>Unnecessary br tags</p> </section>使用原子類進行樣式設置。
不要使用任何自定義顏色或字體大小(如果顏色或字體大小不在框架中,只需添加您的原子類)。 原子類是簡單的、單一用途的樣式單元。 很像內聯樣式,原子樣式只應用一個樣式聲明。
錯誤代碼:
<h1>Without using atomic class</h1> <p>Paragraph without atomic class</p> <section> <h1> Another h1 text</h1> <p>Paragraph inside div without class</p> </section> h1 { color: red; } section > h1 { color: blue; }好代碼:
<h1 class="text-red">Without using atomic class</h1> <p>Paragraph without atomic class</p> <section> <h1 class="text-blue"> Another h1 text</h1> <p>Paragraph inside div without class</p> </section> .text-red { color: red; } .text-blue { color: blue; }盡量保持細化和原子類,並在需要時使用它們。 因此,您的前端將變得更加基於標記。
利用語義元素。
使用語義可以提供更好的結構並使代碼和內容更易於閱讀。
錯誤代碼:
<span class="heading"><strong>Welcome</strong></span> <span>This is unnecessary br tag.</span>好代碼:
<h1>Welcome</h1> <p>This is unnecessary br tag.</p>使用 HTML5 標籤。
新標籤為您提供更多表達自由並標準化常見元素,從而改進文檔的自動化處理。 這是所有元素的可靠列表。 我發現很多開發人員總是使用很多<div>和<span> ,但首先請在此處檢查哪些標籤在邏輯上適合您的上下文:
錯誤代碼:
<div class="article-blue"> <div class="article-title-red">HTML 4 title</div> <div class="content"> Semantics <span class="boldtext">are</span> important. </div> </div>好代碼:
<article> <h1>HTML5 title</h1> <p> Semantics <strong>are</strong> important. </p> </article>底線:學習和使用 HTML5 中的新元素。 這是非常值得的!
CSS:清潔代碼和預處理器
當談到 CSS 時,很難不從一些非原創但時髦的建議開始:
使用 CSS 預處理器。
Sass 是世界上最成熟、最穩定、最強大的專業級 CSS 擴展語言。
Sass 有兩種可用的語法。 第一個,稱為 SCSS (Sassy CSS),在本參考資料中使用,是 CSS 語法的擴展。 第二種和更舊的語法,稱為縮進語法(或有時簡稱為“Sass”),提供了一種更簡潔的 CSS 編寫方式。
分組選擇器:在 SASS 中使用 @extend。
通過對選擇器進行分組,或在 SASS 中使用@extend ,您應該有助於保持代碼乾燥(不要重複自己)。
錯誤代碼:
p { font-size: 22px; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } h1 { font-size: 41px; color: #000; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }好代碼:

.font-smoothing { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } p { font-size: 22px; @extend .font-smoothing; } h1 { font-size: 22px; @extend .font-smoothing; }在 CSS 中使用 rem 單位而不是像素。
將 REM 用於大小和間距,例如它根據根<html>元素的font-size製作的字體大小。 它們還允許您通過更改根字體大小(例如在某個媒體查詢/屏幕大小)來快速縮放整個項目。
您將為響應式視圖編寫更少的代碼:
錯誤代碼:
p { font-size: 22px; padding: 10px; } @media (max-width: 767px) { p { font-size: 16px; padding: 5px; } }好代碼:
html { font-size: 14px; } @media (max-width: 767px) { html { font-size: 12px; } } p { font-size: 1.6rem; padding: 1rem; }盡量避免在 CSS 中使用固定的高度或寬度。
盡量避免在 CSS 中使用固定的高度或寬度。 高度可以通過內部內容+填充來生成,寬度可以由網格系統定義(必要時使用嵌套網格)。
錯誤代碼:
<footer class="text-center"> <h2>Let's Get In Touch!</h2> <hr> <p>Ready to start your next project with us?</p> </footer> #footer { height: 130px; }好代碼:
<footer class="text-center"> <h2>Let's Get In Touch!</h2> <hr> <p>Ready to start your next project with us?</p> </footer> #footer { padding-top: 23px; padding-bottom: 47px; }確保在 SCSS 中只使用一次父項。
當您使用 CSS 預處理器併計劃為任何部分編寫樣式時,請確保在 CSS 中只使用一次父項,並將所有子元素和媒體查詢包含在其括號內。 這將允許您在將來進行更改時輕鬆地在一個地方查找和修改主要父元素。
錯誤代碼:
.section-parent-class { position: relative; h2 { color: #ff0; } header { margin: 2rem 1rem; } } @media (max-width: 767px) { .section-parent-class { footer { padding: .5rem; } } }好代碼:
.section-parent-class { position: relative; h2 { color: #ff0; } header { margin: 2rem 1rem; } footer { @media (max-width: 767px) { padding: .5rem; } } }在編寫 CSS 規則之前考慮哪些元素會受到影響。
在編寫任何 CSS 規則之前,請始終考慮哪些元素會受到影響。 如果您的更改不常見,那麼以僅影響某個元素而不影響其他元素的方式編寫您的規則。
錯誤代碼:
/* Commonly used class */ .title { color: #008000; }好代碼:
/* Specify it not to affect other titles */ .section-blog .title { color: #008000; }嘗試在編寫新的 CSS 規則和變量之前查找現有的 CSS 規則和變量。
始終在自定義 CSS 和框架中尋找適合所需樣式的現有規則。 只有當沒有足夠的東西時,才繼續寫一個新的。
這在使用大型應用程序時尤其重要。
錯誤代碼:
.jumbotron { margin-bottom: 20px; }好代碼:
// change $jumbotron-padding from _variables.scss .jumbotron { margin-bottom: $jumbotron-padding; }使用特定規則。
如果背景有一個屬性,我們指定那個屬性,但是如果它有不同的背景屬性,我們可以給它一個聲明。
錯誤代碼:
.selector { background: #fff; }好代碼:
.selector { /* This way background image will not be overwritten if there is any */ background-color: #fff; }使用速記屬性和值。
盡量使用更多的速記屬性和值。 使用速記屬性,您可以編寫簡潔且通常更具可讀性的樣式表,從而節省寶貴的時間和精力。
錯誤代碼:
img { margin-top: 5px; margin-right: 10px; margin-bottom: 25px; margin-left: 10px; } button { padding: 0 0 0 20px; }好代碼:
img { /* Shorthand style */ margin: 5px 10px 25px; } button { /* Don't play with shorthand too much */ padding-left: 20px; } 使用em而不是px作為行高。
使用em和px單位為我們的設計提供了靈活性,並且能夠向上和向下縮放元素,而不是被固定尺寸所束縛。 我們可以利用這種靈活性使我們的設計在開發過程中更容易調整,響應速度更快,並允許瀏覽器用戶控製網站的整體規模以獲得最大的可讀性。
錯誤代碼:
p { font-size: 12px; line-height: 24px; }好代碼:
p { font-size: 12px; line-height: 2em; /* or just line-height: 2; */ }盡可能使用 Bootstrap 類。
雖然這條規則通常適用於 UI 框架,但我以 Bootstrap 為例,因為它是世界上最流行的前端組件庫。
Bootstrap 允許你使用很多現成的類,讓你的工作更輕鬆。 嘗試盡可能多地使用 Bootstrap 類,以製作更多基於 HTML 的標記。
錯誤代碼:
<section class="without-bootstrap"> <div class="first-column">Lorem ipsum dolor sit amet, ut ius delenit facilisis</div> <div class="second-column">Lorem ipsum dolor sit amet, ut ius delenit facilisis</div> </section> .first-column, .second-column { width: 25%; float: left; padding-left: 15px; padding-right: 15px; } ...好代碼:
<section class="row"> <div class="col-md-6">Lorem ipsum dolor sit amet, ut ius delenit facilisis</div> <div class="col-md-6">Lorem ipsum dolor sit amet, ut ius delenit facilisis</div> </section>正確自定義您的框架。
Bootstrap 依賴於 variables.scss 文件,它允許您輕鬆配置和自定義前端,而無需編寫任何代碼。 否則,如果您要自己手動編寫所有自定義項,最好不要使用框架。
一些開發人員避免更改 variables.scss,認為他們仍然可以輕鬆地將 Bootstrap 升級到新版本,但這可能是一項乏味的任務。 即使是很小的更新也需要開發人員閱讀更改日誌,檢查所有標記和 CSS,然後手動遷移到新版本。
錯誤代碼:
navbar { padding: 20px 10px; } .carousel-indicators { li { width: 6px; height: 6px; margin-right: 3px; margin-left: 3px; } }好代碼:
$navbar-padding-y: ($spacer / 2) !default; $navbar-padding-x: $spacer !default; $carousel-indicator-width: 30px !default; $carousel-indicator-height: 3px !default; $carousel-indicator-spacer: 3px !default; 不要覆蓋.container寬度。
盡量不要覆蓋.container的寬度。 嘗試改用網格系統,或者只是更改_variables.scss中的容器寬度。 如果您需要減小它的寬度,只需使用 max-width 而不是寬度。 在這種情況下,來自 Bootstrap 的.container將在響應式視圖中保持不變。
錯誤代碼:
.container { @media (min-width: $screen-lg-min) { width: 1300px; } }好代碼:
// change $container-lg from _variables.scss .container { @media (min-width: $screen-lg-min) { width: $container-lg; } }使用 Bootstrap 4 類並少寫 CSS。
開始使用 Bootstrap 4,即使它處於測試階段。 它包括許多新的類,可以幫助您更快地創建佈局,尤其是 Flexbox 和 spacers。
錯誤代碼:
<div class="flex-ex"> <div>Flex item 1</div> <div>Flex item 2</div> <div>Flex item 3</div> </div> <div class="flex-ex flex-reverse"> <div>Flex item 1</div> <div>Flex item 2</div> <div>Flex item 3</div> </div> .flex-ex { display: flex; > div { padding: 2px; } &.flex-reverse { flex-direction: row-reverse; } li { list-style: none; padding: .5rem; } }好代碼:
<ul class="list-unstyled list-inline d-flex flex-row"> <li class="p-2">Flex item 1</li> <li class="p-2">Flex item 2</li> <li class="p-2">Flex item 3</li> </ul> <ul class="list-unstyled list-inline d-flex flex-row-reverse"> <li class="p-2">Flex item 1</li> <li class="p-2">Flex item 2</li> <li class="p-2">Flex item 3</li> </ul>現在我們可以將類分配給一個元素以刪除所有邊框或某些邊框。
錯誤代碼:
<div class="border-example2 py-5"> <span class="border0"></span> <span class="border-top0"></span> <span class="border-right0"></span> <span class="border-bottom0"></span> <span class="border-left0"></span> </div> border-example2 { > span { width: 100px; height: 100px; display: inline-block; margin: .50rem; background-color: #e1e1e1; border: 1px solid; &.border0 { border: none; } &.border-top0 { border-top: none; } &.border-right0 { border-right: none; } &.border-bottom0 { border-bottom: none; } &.border-left0 { border-left: none; } } }好代碼:
<div class="border-example py-5"> <span class="d-inline-block m-2 border-0"></span> <span class="d-inline-block m-2 border-top-0"></span> <span class="d-inline-block m-2 border-right-0"></span> <span class="d-inline-block m-2 border-bottom-0"></span> <span class="d-inline-block m-2 border-left-0"></span> </div> .border-example { > span { width: 100px; height: 100px; background-color: #e1e1e1; border: 1px solid; } } 如果.col-md-X和.col-lg-X對 X 具有相同的值,則使用.col-sm-X 。
如果.col-sm-X具有相同的值,則不要寫.col-md-X和.col-lg-X 。例如,不需要寫.col-lg-10因為當我們寫.col-md-10 ,我們會自動在其中包含.col-lg-10 。
錯誤代碼:
<ul class="press-list list-inline row"> <li class="col-lg-4 col-md-4 col-sm-4 col-xs-6"><a href="#"><img class="img-fluid" src="assets/images/press/press-1.png" alt=""></a></li> <li class="col-lg-4 col-md-4 col-sm-4 col-xs-6"><a href="#"><img class="img-fluid" src="assets/images/press/press-2.png" alt=""></a></li> </ul>好代碼:
<ul class="press-list list-inline row"> <li class="col-md-4 col-xs-6"><a href="#"><img class="img-fluid" src="assets/images/press/press-1.png" alt=""></a></li> <li class="col-md-4 col-xs-6"><a href="#"><img class="img-fluid" src="assets/images/press/press-2.png" alt=""></a></li> </ul> 不要使用.col-xs-12 。
不要使用.col-xs-12 ,因為如果沒有分配.col-xs-X ,則默認為.col-xs-12 。
錯誤代碼:
<section> <div class="container"> <div class="row"> <div class="col-lg-12 text-center"> <h2>Services</h2> <h3 class="text-muted">Lorem ipsum dolor sit amet consectetur.</h3> </div> </div> <div class="row text-center"> <div class="col-md-6 col-xs-12"> <h4>E-Commerce</h4> <p class="text-muted">Lorem ipsum dolor sit amet, consectetur adipisicing.</p> </div> </div> </div> </section>好代碼:
<section class="text-center"> <div class="container"> <h2>Services</h2> <h3 class="text-muted">Lorem ipsum dolor sit amet consectetur.</h3> <div class="row"> <div class="col-md-6"> <h4>E-Commerce</h4> <p class="text-muted">Lorem ipsum dolor sit amet, consectetur adipisicing.</p> </div> </div> </div> </section> 不要使用reset.css ; 改用normalize.css 。
如果您使用的是 Bootstrap,那麼normalize.css已經包含在其中,無需包含兩次。
遵循指南,即使它們不是最佳實踐。
為了保持一致性,最好始終遵循您開始使用的規則和指南(無論它們是關於命名、代碼樣式還是文件結構)
包起來
我希望你已經能夠帶走一些有用的東西,並且你會更多地考慮使用最佳實踐編寫最少的 HTML 和 CSS 代碼。
對於大公司來說,當代碼混亂時,維護大型應用程序是相當困難的。 當然,大公司有錢為優質買單。 如果您遵循乾淨的編碼原則,您將提高找到一份好工作的機會。 還值得提出自由職業者方面的問題:處理多個項目和客戶的專業人士必須提供乾淨的代碼,這些代碼可以立即傳遞給其他開發人員。
我希望在未來的文章中擴展到更高級的主題,因為我打算討論自動化編碼過程,使用 Gulp/Grunt 任務、Linter、編輯器插件、生成代碼的工具、代替你編寫代碼的 AI 工具,以及其他相關話題。
我希望這是一次有趣且內容豐富的閱讀。 祝你編碼工作好運。
進一步閱讀 Toptal 工程博客:
- 如何在 CSS 中處理 SVG 動畫
