メンテナンスしやすいCSS_html/css_WEB-ITnoseの書き方

WBOY
リリース: 2016-06-24 11:17:13
オリジナル
921 人が閲覧しました

多くの人が関係する大規模で時間のかかるプロジェクトに取り組む場合、すべての開発者が次のルールに従うことが非常に重要です:

  • CSS を保守しやすい状態に保つ
  • コードを明確で理解しやすい状態に保つ
  • コードのスケーラビリティを維持する

この目標を達成するには、多くの方法を使用する必要があります。

このドキュメントの最初の部分では、CSS 構造の構文、形式、分析について説明し、2 番目の部分では、CSS の作成と計画に対する方法論、思考フレームワーク、態度に焦点を当てます。

CSS ドキュメント分析

どのようなドキュメントを作成する場合でも、統一されたコメント、統一された文法、統一された命名規則など、統一されたスタイルを維持するために最善を尽くす必要があります。

一般的なルール

線幅は 80 バイト未満に保つようにしてください。結局のところ、コメント内のグラデーション関連の構文と URL は例外としてカウントされる可能性があります。この部分については何もできません。

私はタブ インデントの代わりに 4 つのスペースを使用し、ステートメントを複数の行に分割する傾向があります。

単一ファイル vs. 複数ファイル

すべてを 1 つのファイルに書きたい人もいますが、私は Sass に移行してからスタイルを複数の小さなファイルに分割し始めました。これはすべて良い習慣です。どちらを選択しても、以下のルールが適用され、それに従っていただければ問題ありません。これら 2 つの書き込み方法の唯一の違いは、ディレクトリとブロック タイトルです。

目次

CSS の最初に、次のような目次を書きます。

/*------------------------------------*\    $CONTENTS\*------------------------------------*//** * CONTENTS............You’re reading it! * RESET...............Set our reset defaults * FONT-FACE...........Import brand font files */
ログイン後にコピー

この目次は、このファイルにどのようなコンテンツが含まれているかを他の開発者に伝えることができます。このディレクトリ内の各項目には、対応するブロックと同じブロック タイトルが付けられます。

単一ファイルの CSS を保守している場合、対応するブロックも同じファイル内に存在します。一連の小さなファイルを作成している場合は、ディレクトリ内の各項目に対応する @include ステートメントが必要です。

ブロックタイトル

目次はブロックのタイトルに対応している必要があります。次の例を参照してください:

/*------------------------------------*\    $RESET\*------------------------------------*/
ログイン後にコピー

ブロック タイトルの接頭辞 $ を使用すると、検索範囲をブロック タイトルに制限しながら、[Cmd|Ctrl]+F コマンドを使用してタイトル名を検索できます

大きなファイルを管理している場合は、次のようにチャンクの間に 5 つの空行を残してください:

/*------------------------------------*\    $RESET\*------------------------------------*/[Ourresetstyles]/*------------------------------------*\    $FONT-FACE\*------------------------------------*/
ログイン後にコピー

これらの大きなギャップは、大きなファイルをすばやくめくるときにチャンクを区別するのに役立ちます。

@include で接続された CSS のコピーを複数保持している場合は、このように空白行を残さずに各ファイルのヘッダーにタイトルを追加するだけです。

コードの順序

特定の順序でルールを記述するようにすると、CSS の略語であるカスケードの最初の C の意味を最大限に活用できるようになります。

綿密に計画された CSS は次のように配置する必要があります:

  1. リセットすべての根源
  2. 要素タイプクラスのない H1、ul など
  3. オブジェクトと抽象コンテンツ 最も一般的で、基本デザインパターン
  4. 子要素オブジェクトによって拡張されたすべての拡張子と子要素
  5. 例外用のパッチ
このように、CSSを順番に記述すると、各ブロックは自動的にそれを継承できます 前のブロックのプロパティ。このようにして、コードの相互にオフセットする部分を減らすことができ、いくつかの特別な問題を軽減し、より理想的な CSS 構造を形成することができます。

これについて詳しくは、Jonathan Snook の SMACSS を強くお勧めします。

CSS ルール セットの分析

CSS スタイルを記述するとき、私は次のルールに従うことに慣れています:

    以下で説明する BEM 命名法を除き、クラス名はハイフン (-) で接続されます
  • スペースを 4 つインデントします。
  • 宣言は複数の行に分割されます。
  • 宣言はアルファベット順ではなく、関連性の高い順に並べられます。
  • DOM を反映するようにインデントされます。
  • 末尾にセミコロンを付けます。声明の。
  • 例:
  • [选择器]{    [属性]:[值];    [<- 声明 ->]}
    ログイン後にコピー
  • .widget-Heading は .widget の子要素であることがわかります。これは、前者が後者より 1 レベルインデントされているためです。このようにして、開発者はインデントを通じてコードを読むときに、そのような重要な情報を迅速に取得できます。
.widget-Heading の宣言が関連性に従って配置されていることもわかります。 .widget-Heading はインライン要素なので、最初にフォント関連のスタイル宣言を追加し、次に他のスタイル宣言を追加します。

複数行に分割しない例を次に示します:

.widget{    padding:10px;    border:1px solid #BADA55;    background-color:#C0FFEE;    -webkit-border-radius:4px;       -moz-border-radius:4px;            border-radius:4px;}    .widget-heading{        font-size:1.5rem;        line-height:1;        font-weight:bold;        color:#BADA55;        margin-right:-10px;        margin-left: -10px;        padding:0.25em;    }
ログイン後にコピー

この例 (inuit.css のテーブル グリッド システムから) では、CSS を 1 行に配置することでコードがよりコンパクトになります。

命名規則

通常、クラス名を接続するにはハイフン (-) を使用します (.foo_bar や .fooBar の代わりに .foo-bar など) が、特定の場合には BEM (Block 、 Element、修飾子)命名法。

BEM 命名法により、セレクターをより標準化、明確、よりセマンティックにすることができます。

命名法は次の形式に従います:

.t10    { width:10% }.t20    { width:20% }.t25    { width:25% }       /* 1/4 */.t30    { width:30% }.t33    { width:33.333% }   /* 1/3 */.t40    { width:40% }.t50    { width:50% }       /* 1/2 */.t60    { width:60% }.t66    { width:66.666% }   /* 2/3 */.t70    { width:70% }.t75    { width:75% }       /* 3/4*/.t80    { width:80% }.t90    { width:90% }
ログイン後にコピー

ここで:

  • .block代表某个基本的抽象元素;
  • .block__element代表 .block这一整体的一个子元素;
  • .block--modifier代表 .block的某个不同状态。

打个比方:

.person{}.person--woman{}    .person__hand{}    .person__hand--left{}    .person__hand--right{}
ログイン後にコピー

这个例子中我们描述的基本元素是一个人,然后这个人可能是一个女人。我们还知道人拥有手,这些是人体的一部分,而手也有不同的状态,如同左手与右手。

这样我们就可以根据亲元素来划定选择器的命名空间并传达该选择器的职能,这个选择器是一个子元素( __)还是亲元素的不同状态( --)?

由此, .page-wrapper是一个独立的选择器。这是一个符合规范的命名,因为它不是其它元素的子元素或其它状态;然而 .widget-heading则与其它对象有关联,它应当是 .widget的子元素,所以我们应当将其重命名为 .widget__heading。

BEM 命名法虽然不太好看,而且相当冗长,但是它使得我们可以通过名称快速获知元素的功能和元素之间的关系。与此同时,BEM 语法中的重复部分非常有利于 gzip 的压缩算法。

无论你是否使用 BEM 命名法,你都应当确保 class 命名得当,力保一字不多、一字不少;将元素命名抽象化以提高复用性(例如 .ui-list, .media)。由此延伸出去的元素命名则要尽量精准(例如 .user-avatar-link)。不用担心 class 名的数量或长度,因为写得好的代码 gzip 也能有效压缩。

HTML 中的 class

为了确保易读性,在 HTML 标记中用两个空格隔开 class 名,例如:

<div class="foo--bar  bar__baz">
ログイン後にコピー

增加的空格应当可以使得在使用多个 class 时更易阅读与定位。

JavaScript 钩子

千万不要把 CSS 样式用作 JavaScript 钩子。把 JS 行为与样式混在一起将无法对其分别处理。

如果你要把 JS 和某些标记绑定起来的话,写一个 JS 专用的 class。简单地说就是划定一个前缀 .js-的命名空间,例如 .js-toggle, .js-drag-and-drop。这意味着我们可以通过 class 同时绑定 JS 和 CSS 而不会因为冲突而引发麻烦。

<th class="is-sortable  js-is-sortable"></th>
ログイン後にコピー

上面的这个标记有两个 class,你可以用其中一个来给这个可排序的表格栏添加样式,用另一个添加排序功能。

I18n

虽然我(该 CSS Guideline 文档原作者 Harry Roberts)是个英国人,而且我一向拼写 colour 而非 color,但是为了追求统一,我认为在 CSS 中用美式拼法更佳。CSS 以及其它多数语言都是以美式拼法编写,所以如果在 .colour-picker{}中写 color:red就缺乏统一性。我以前主张同时用两种拼法,例如:

.color-picker,.colour-picker{}
ログイン後にコピー

但是我最近参与了一份规模庞大的 Sass 项目,这个项目中有许多的颜色变量(例如 $brand-color, $highlight-color等等),每个变量要维护两种拼法实在辛苦,要查找并替换时也需要两倍的工作量。

所以为了统一,把所有的 class 与变量都以你参与的项目的惯用拼法命名即可。

注释

我使用行宽不超过 80 字节的块状注释:

/** * 这是一个文档块(DocBlock)风格的注释。 * * 这里开始是描述更详细、篇幅更长的注释正文。当然,我们要把行宽控制在 80 字以内。 * * 我们可以在注释中嵌入 HTML 标记,而且这也是个不错的办法: *    <div class=foo>        <p>Lorem</p>    </div> * * 如果是注释内嵌的标记的话,在它前面不加星号,否则会被复制进去。 */
ログイン後にコピー

在注释中应当尽量详细描述代码,因为对你来说清晰易懂的内容对其他人可能并非如此。每写一部分代码就要专门写注释以详解。

注释的拓展用法

注释有许多很先进的用法,例如:

  • 准修饰选择器
  • 代码标签
  • 继承标记

准修饰选择器

你应当避免过分修饰选择器,例如如果你能写 .nav{}就尽量不要写 ul.nav{}。过分修饰选择器将影响性能,影响 class 复用性,增加选择器私有度。这些都是你应当竭力避免的。

不过有时你可能希望告诉其他开发者 class 的使用范围。以 .product-page为例,这个 class 看起来像是一个根容器,可能是 html或者 body元素,但是仅凭 .product-page则无法判断。

我们可以在选择器前加上准修饰(即将前面的类型选择器注释掉)来描述我们规划的 class 作用范围:

/*html*/.product-page{}
ログイン後にコピー

这样我们就能准确获知该 class 的作用范围而不会影响复用性。

其它例子如:

/*ol*/.breadcrumb{}/*p*/.intro{}/*ul*/.image-thumbs{}
ログイン後にコピー

这样我们就能在不影响代码私有度的前提下获知 class 作用范围。

代码标签

如果你写了一个新规则的话,可以在它上面加上标签,例如:

/** * ^navigation ^lists */.nav{}/** * ^grids ^lists ^tables */.matrix{}
ログイン後にコピー

这些标签可以使得其他开发者快速找到相关代码。如果一个开发者需要查找和列表相关的部分,他只要搜索 ^lists就能快速定位到 .nav, .matrix以及其它相关部分。

继承标记

将面向对象的思路用于 CSS 编写的话,你经常能找到两部分 CSS 密切相关(其一为基础,其一为拓展)却分列两处。我们可以用继承标记来在原元素和继承元素之间建立紧密联系。这些在注释中的写法如下:

在元素的基本样式中:

/** * Extend `.foo` in theme.css */ .foo{}
ログイン後にコピー

在元素的拓展样式中:

/** * Extends `.foo` in base.css */ .bar{}
ログイン後にコピー

这样一来我们就能在两块相隔很远的代码间建立紧密联系。

编写 CSS

之前的章节主要探讨如何规划 CSS,这些都是易于量化的规则。本章将探讨更理论化的东西,也将探讨我们的态度与方法。

编写新组件

编写新组件时,要在着手处理 CSS 之前写好 HTML 部分。这可以令你准确判断哪些 CSS 属性可以继承,避免重复浪费。

先写标记的话,你就可以关注数据、内容与语义,在这之后再添加需要的 class 和 CSS 样式。

面向对象 CSS

我以面向对象 CSS 的方式写代码。我把组件分成结构(对象)与外观(拓展)。正如以下分析:

.room{}.room--kitchen{}.room--bedroom{}.room--bathroom{}
ログイン後にコピー

我们在屋子里有许多房间,它们都有共同的部分:它们都包含地板、天花板、墙壁和门。这些共享的部分我们可以放到一个抽象的 .room{}class 中。不过我们还有其它与众不同的房间:一个厨房可能有地砖,卧室可能有地毯,洗手间可能没有窗户但是卧室会有,每个房间的墙壁颜色也许也会不一样。面向对象 CSS 的思路使得我们把相同部分抽象出来组成结构部分,然后用更具体的 class 来拓展这些特征并添加特殊的处理方法。

所以比起编写大量的特殊模块,应当努力找出这些模块中重复的设计模式并将其抽象出来,写成一个可以复用的 class,将其用作基础然后编写其它拓展模块的特殊情形。

当你要编写一个新组件时,将其拆分成结构和外观。编写结构部分时用最通用 class 以保证复用性,编写外观时用更具体的 class 来添加设计方法。

布局

所有组件都不要声明宽度,而由其亲元素或格栅系统来决定。

坚决不要声明高度。高度应当仅仅用于尺寸已经固定的东西,例如图片和 CSS Sprite。在 p, ul, div等元素上不应当声明高度。如果需要的话可以写 line-height,这个更加灵活。

格栅系统应当当作书架来理解。是它们容纳内容,而不是把它们本身当成内容装起来,正如你先搭起书架再把东西放进去。比起声明它们的尺寸,把格栅系统和元素的其它属性分来开处理更有助于布局,也使得我们的前端工作更高效。

你在格栅系统上不应当添加任何样式,他们仅仅是为布局而用。在格栅系统内部再添加样式。在格栅系统中任何情况下都不要添加盒模型相关属性。

UI 尺寸

我用很多方法设定 UI 尺寸,包括百分比, px, em, rem以及干脆什么都不用。

理想情况下,格栅系统应当用百分比设定。如上所述,因为我用格栅系统来固定栏宽和页宽,所以我可以不用理会元素的尺寸。

我用 rem 定义字号,并且辅以 px 以兼容旧浏览器。这可以兼具 em 和 px 的优势。下面是一个非常漂亮的 Sass Mixin,假设你在别处声明了基本字号(base-font-size)的话,用它就可以生成 rem 以及兼容旧浏览器的 px。

@mixin font-size($font-size){    font-size:$font-size +px;    font-size:$font-size / $base-font-size +rem;}
ログイン後にコピー

我只在已经固定尺寸的元素上使用 px,包括图片以及尺寸已经用 px 固定的 CSS Sprite。

字号

我会定义一些与格栅系统原理类似的 class 来声明字号。这些 class 可以用于双重标题分级,关于这点请阅读 Pragmatic, practical font-sizing in CSS。

简写

CSS 简写应当谨慎使用。

编写像 background:red;这样的属性的确很省事,但是你这么写的意思其实是同时声明 background-image:none; background-position:top left; background-repeat: repeat; background-color:red;。虽然大多数时候这样不会出什么问题,但是哪怕只出一次问题就值得考虑要不要放弃简写了。这里应当改为 background-color:red;。

类似的,像 margin:0;这样的声明的确简洁清爽,但是还是应当 尽量写清楚。如果你只是想修改底边边距,就要具体一些,写成 margin-bottom:0;。

反过来,你需要声明的属性也要写清楚,不要因为简写而波及其它属性。例如如果你只想改掉底部的 margin,那就不要用会把其它边距也清零的 margin:0。

简写虽然是好东西,但是注意切勿滥用。

ID

セレクターの扱いを始める前に、次の文に留意してください:

CSS では ID を決して使用しないでください。

HTML では JS やアンカーの位置決めに ID を使用できますが、CSS ではクラスのみを使用する必要があり、ID はまったく必要ありません。

クラスの利点は、再利用可能であり、プライバシーの程度が低いことです。プライバシーは問題を引き起こしやすいため、プライバシーを減らすことが重要です。 ID のプライバシーはクラスのプライバシーの 255 倍であるため、CSS では決して使用しないでください。

セレクター

セレクターは常に短く効率的にしてください。

ページ要素の位置によって配置されたセレクターは理想的ではありません。たとえば、.sidebar h3 span{} などのセレクターの位置は相対位置に大きく依存するため、スパンが h3 やサイドバーの外側に移動されるとスタイルを維持するのが困難になります。

複雑な構造を持つセレクターはパフォーマンスに影響します。セレクターの構造が複雑になればなるほど (たとえば、.sidebar h3 spa は 3 層、.content ul pa は 4 層)、ブラウザの消費量も多くなります。

スタイルをその位置から独立させて、セレクターをシンプルかつ明確に保つようにしてください。

全体として、セレクターはできるだけ短くする必要があります (たとえば、構造の 1 つのレイヤーのみ)。ただし、クラス名は単純すぎてはなりません。たとえば、.usr-avt よりも .user-avatar の方がはるかに優れています。 。

覚えておいてください: クラスが意味論的であるかどうかは問題ではなく、クラスが合理的であるかどうかに焦点を当てる必要があります。クラス名が意味論的であることを強調するのではなく、合理的で時代遅れではない名前を使用することに重点を置きます。

過剰に変更されたセレクター

前述したように、過剰に変更されたセレクターは理想的ではありません。

過剰に変更されたセレクターは、div.promo のようなセレクターです。ほとんどの場合、.promo だけを使用しても同じ効果が得られます。もちろん、場合によっては、要素タイプを使用してクラスを変更する必要がある場合があります (たとえば、.error を作成し、.error{ color:red; } div.error{ padding など、さまざまな要素タイプで異なる表示をしたい場合) : 14px;}) ですが、ほとんどの場合は避けるべきです。

過剰に変更されたセレクターの別の例、ul.nav li a{}。前に述べたように、.nav がリストであることがわかっているので、ul をすぐに削除できます。また、a が li になければならないことがわかるので、このセレクターを .nav a{} に書き換えることができます。

セレクターのパフォーマンス

ブラウザのパフォーマンスは日々向上しており、CSS のレンダリングはますます高速になっていますが、それでも効率に注意を払う必要があります。この問題は、不連続でネストされていないセレクターを使用し、グローバル セレクター (*{}) をコア セレクターとして使用せず、ますます複雑になる CSS3 の新しいセレクターの使用を回避することで回避できます。

翻訳、コア セレクター: ブラウザーはセレクターを右から左の順序で解析します。そのスタイルが有効になる要素であり、コア セレクターです。

CSS セレクターを使用する目的

セレクターを使用して要素を見つけるのではなく、スタイルを追加したい要素にクラスを直接追加する方が良い方法です。例として .header ul{} のようなセレクターを見てみましょう。

この ul がこの Web サイトのフルサイト ナビゲーションであり、ヘッダー内にあり、これまでのところヘッダー内の唯一の ul 要素であると仮定します。 .header ul{} は機能しますが、良いアイデアではなく、すぐに時代遅れになり、非常に曖昧です。ヘッダーに別の ul を追加すると、たとえこれが想定していた効果ではない場合でも、このナビゲーション パーツ用に作成したスタイルが適用されます。これは、以前の影響を相殺するために、多くのコードをリファクタリングするか、後の UL 用に多くの新しいスタイルを作成する必要があることを意味します。

セレクターは、この要素のスタイルを設定する理由に適合する必要があります。 「この要素が .header の下にある ul であるため、ターゲットにしているのでしょうか? それとも、サイト ナビゲーションであるためですか? これにより、セレクターをどのように使用するかが決まります。」

コア セレクターが型セレクターではなく、高レベル オブジェクトや抽象セレクターでもないことを確認してください。たとえば、CSS には .sidebar ul{} や .footer .media{} などのセレクターは絶対にありません。

明確な式: 親要素ではなく、スタイルを設定したい要素を直接見つけます。 HTML が変更されないとは考えないでください。 CSS を使用して、ご都合主義ではなく、必要な要素を直接ヒットします。

私の記事「Shoot to kill; CSS セレクターのインテント」を参照してください

! important

! important は補助クラスでのみ使用してください。たとえば、特定のルールを常に有効にしたい場合は、 .error{ color:red! important } を使用して優先度を上げることもできます。 ! important を積極的に使用することは避けてください。たとえば、複雑な CSS を作成するときにこれをショートカットとして使用しないでください。前の部分をクリーンアップしてリファクタリングし、セレクターを短くし、他の部分を圧倒する ID の使用を避けてください。

マジックナンバーと絶対位置決め

マジックナンバーは、「たまたま影響を及ぼした」数字を指します。これは、症状を治療するだけで根本原因を治療するものではなく、拡張性が欠けているため、非常に悪いものです。

例如 .dropdown-nav li:hover ul{ top:37px; }把下拉菜单移动下来远非良策,因为这里的 37px 就是个魔数。37px 会生效的原因是因为这时 .dropbox-nav碰巧高 37px 而已。

这时你应该用 .dropdown-nav li:hover ul{ top:100%; },也即无论 .dropbox-down多高,这个下拉菜单都会往下移动 100%。

每当你要在代码中放入数字的时候,请三思而行。如果你能用一个关键字(例如 top:100%意即「从上面拉到最下面」)替换之,或者有更好的解决方法的话,就尽量避免直接出现数字。

你在 CSS 中留下的每一个数字,都是你许下而不愿遵守的承诺。

条件判断

专门为 IE 写的样式基本上都是可以避免的,唯一需要为 IE 专门处理的是为了处理 IE 不支持的内容(例如 PNG)。

简而言之,如果你重构 CSS 的话,所有的布局和盒模型都不用额外兼容 IE。也就是说你基本上不用 或者类似的兼容 IE 的写法。

Debugging

如果你要解决 CSS 问题的话, 先把旧代码拿掉再写新的。如果旧的 CSS 中有问题的话,写新代码是解决不了的。

把 CSS 代码和 HTML 部分删掉,直到没有 BUG 为止,然后你就知道问题出在哪里了。

有时候写上一个 overflow:hidden或者其它能把问题藏起来的代码的确效果立竿见影,但是 overflow 方面可能根本就没问题。所以 要治本,而不是单纯治标

CSS 预处理器

我用 Sass。使用时应当 灵活运用。用 Sass 可以令你的 CSS 更强大,但是不要嵌套得太复杂。在 Vanilla CSS 中,只在必要的地方用嵌套即可,例如:

.header{}.header .site-nav{}.header .site-nav li{}.header .site-nav li a{}
ログイン後にコピー

这样的写法在普通 CSS 里完全用不到。以下为 不好的Sass 写法:

.header{    .site-nav{        li{            a{}        }    }}
ログイン後にコピー

如果你用 Sass 的话,尽量这么写:

.header{}.site-nav{    li{}    a{}}
ログイン後にコピー

Update 最新版本 英文

-

原文 CSS Guildelines

翻译 chadluo

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート