整合營銷服務商

          電腦端+手機端+微信端=數(shù)據(jù)同步管理

          免費咨詢熱線:

          1.5 萬字 CSS 基礎(chǔ)拾遺(核心知識、常見需求)

          1.5 萬字 CSS 基礎(chǔ)拾遺(核心知識、常見需求)

          篇文章圍繞了 CSS 的核心知識點和項目中常見的需求來展開。雖然行文偏長,但較基礎(chǔ),適合初級中級前端閱讀,閱讀的時候請適當跳過已經(jīng)掌握的部分。

          這篇文章斷斷續(xù)續(xù)寫了比較久,也參考了許多優(yōu)秀的文章,但或許文章里還是存在不好或不對的地方,請多多指教,可以評論里直接提出來哈。

          小tip:后續(xù)內(nèi)容更精彩哦。

          核心概念和知識點

          語法

          CSS 的核心功能是將 CSS 屬性設(shè)定為特定的值。一個屬性與值的鍵值對被稱為聲明(declaration)。

          css復制代碼color: red;
          

          而如果將一個或者多個聲明用 {} 包裹起來后,那就組成了一個聲明塊(declaration block)。

          css復制代碼{
              color: red;
              text-align: center;
          }
          

          聲明塊如果需要作用到對應的 HTML 元素,那還需要加上選擇器。選擇器和聲明塊組成了CSS 規(guī)則集(CSS ruleset),常簡稱為 CSS 規(guī)則。

          css復制代碼span {
              color: red;
              text-align: center;
          }
          

          規(guī)則集中最后一條聲明可以省略分號,但是并不建議這么做,因為容易出錯。

          CSS 中的注釋

          css復制代碼/* 單行注釋 */
          
          /*
              多行
              注釋
          */
          

          在 CSS 文件中,除了注釋、CSS 規(guī)則集以及 @規(guī)則 外,定義的一些別的東西都將被瀏覽器忽略。

          @規(guī)則

          CSS 規(guī)則是樣式表的主體,通常樣式表會包括大量的規(guī)則列表。但有時候也需要在樣式表中包括其他的一些信息,比如字符集,導入其它的外部樣式表,字體等,這些需要專門的語句表示。

          而 @規(guī)則 就是這樣的語句。CSS 里包含了以下 @規(guī)則:

          • @namespace 告訴 CSS 引擎必須考慮XML命名空間。
          • @media, 如果滿足媒體查詢的條件則條件規(guī)則組里的規(guī)則生效。
          • @page, 描述打印文檔時布局的變化.
          • @font-face, 描述將下載的外部的字體。
          • @keyframes, 描述 CSS 動畫的關(guān)鍵幀。
          • @document, 如果文檔樣式表滿足給定條件則條件規(guī)則組里的規(guī)則生效。 (推延至 CSS Level 4 規(guī)范)

          除了以上這幾個之外,下面還將對幾個比較生澀的 @規(guī)則 進行介紹。

          @charset

          @charset 用于定義樣式表使用的字符集。它必須是樣式表中的第一個元素。如果有多個 @charset 被聲明,只有第一個會被使用,而且不能在HTML元素或HTML頁面的 <style> 元素內(nèi)使用。

          注意:值必須是雙引號包裹,且和

          css復制代碼@charset "UTF-8";
          

          平時寫樣式文件都沒寫 @charset 規(guī)則,那這個 CSS 文件到底是用的什么字符編碼的呢?

          某個樣式表文件到底用的是什么字符編碼,瀏覽器有一套識別順序(優(yōu)先級由高到低):

          • 文件開頭的 Byte order mark 字符值,不過一般編輯器并不能看到文件頭里的 BOM 值;
          • HTTP 響應頭里的 content-type 字段包含的 charset 所指定的值,比如:
          • css復制代碼
          • Content-Type: text/css; charset=utf-8
          • CSS 文件頭里定義的 @charset 規(guī)則里指定的字符編碼;
          • <link> 標簽里的 charset 屬性,該條已在 HTML5 中廢除;
          • 默認是 UTF-8。

          @import

          @import 用于告訴 CSS 引擎引入一個外部樣式表。

          link 和 @import 都能導入一個樣式文件,它們有什么區(qū)別嘛?

          • link 是 HTML 標簽,除了能導入 CSS 外,還能導入別的資源,比如圖片、腳本和字體等;而 @import 是 CSS 的語法,只能用來導入 CSS;
          • link 導入的樣式會在頁面加載時同時加載,@import 導入的樣式需等頁面加載完成后再加載;
          • link 沒有兼容性問題,@import 不兼容 ie5 以下;
          • link 可以通過 JS 操作 DOM 動態(tài)引入樣式表改變樣式,而@import不可以。

          @supports

          @supports 用于查詢特定的 CSS 是否生效,可以結(jié)合 not、and 和 or 操作符進行后續(xù)的操作。

          css復制代碼/* 如果支持自定義屬性,則把 body 顏色設(shè)置為變量 varName 指定的顏色 */
          @supports (--foo: green) {
              body {
                  color: var(--varName);
              }
          }
          

          層疊性

          層疊樣式表,這里的層疊怎么理解呢?其實它是 CSS 中的核心特性之一,用于合并來自多個源的屬性值的算法。比如說針對某個 HTML 標簽,有許多的 CSS 聲明都能作用到的時候,那最后誰應該起作用呢?層疊性說的大概就是這個。

          針對不同源的樣式,將按照如下的順序進行層疊,越往下優(yōu)先級越高:

          • 用戶代理樣式表中的聲明(例如,瀏覽器的默認樣式,在沒有設(shè)置其他樣式時使用)。
          • 用戶樣式表中的常規(guī)聲明(由用戶設(shè)置的自定義樣式。由于 Chrome 在很早的時候就放棄了用戶樣式表的功能,所以這里將不再考慮它的排序。)
          • 作者樣式表中的常規(guī)聲明(這些是我們 Web 開發(fā)人員設(shè)置的樣式)。
          • 作者樣式表中的 !important 聲明。
          • 用戶樣式表中的 !important 聲明S

          理解層疊性的時候需要結(jié)合 CSS 選擇器的優(yōu)先級以及繼承性來理解。比如針對同一個選擇器,定義在后面的聲明會覆蓋前面的;作者定義的樣式會比默認繼承的樣式優(yōu)先級更高。

          選擇器

          CSS 選擇器無疑是其核心之一,對于基礎(chǔ)選擇器以及一些常用偽類必須掌握。下面列出了常用的選擇器。 想要獲取更多選擇器的用法可以看 MDN CSS Selectors。

          基礎(chǔ)選擇器

          • 標簽選擇器:h1
          • 類選擇器:.checked
          • ID 選擇器:#picker
          • 通配選擇器:*

          屬性選擇器

          • [attr]:指定屬性的元素;
          • [attr=val]:屬性等于指定值的元素;
          • [attr*=val]:屬性包含指定值的元素;
          • [attr^=val] :屬性以指定值開頭的元素;
          • [attr$=val]:屬性以指定值結(jié)尾的元素;
          • [attr~=val]:屬性包含指定值(完整單詞)的元素(不推薦使用);
          • [attr|=val]:屬性以指定值(完整單詞)開頭的元素(不推薦使用);

          組合選擇器

          • 相鄰兄弟選擇器:A + B
          • 普通兄弟選擇器:A ~ B
          • 子選擇器:A > B
          • 后代選擇器:A B

          偽類

          條件偽類

          • :lang():基于元素語言來匹配頁面元素;
          • :dir():匹配特定文字書寫方向的元素;
          • :has():匹配包含指定元素的元素;
          • :is():匹配指定選擇器列表里的元素;
          • :not():用來匹配不符合一組選擇器的元素;

          行為偽類

          • :active:鼠標激活的元素;
          • :hover: 鼠標懸浮的元素;
          • ::selection:鼠標選中的元素;

          狀態(tài)偽類

          • :target:當前錨點的元素;
          • :link:未訪問的鏈接元素;
          • :visited:已訪問的鏈接元素;
          • :focus:輸入聚焦的表單元素;
          • :required:輸入必填的表單元素;
          • :valid:輸入合法的表單元素;
          • :invalid:輸入非法的表單元素;
          • :in-range:輸入范圍以內(nèi)的表單元素;
          • :out-of-range:輸入范圍以外的表單元素;
          • :checked:選項選中的表單元素;
          • :optional:選項可選的表單元素;
          • :enabled:事件啟用的表單元素;
          • :disabled:事件禁用的表單元素;
          • :read-only:只讀的表單元素;
          • :read-write:可讀可寫的表單元素;
          • :blank:輸入為空的表單元素;
          • :current():瀏覽中的元素;
          • :past():已瀏覽的元素;
          • :future():未瀏覽的元素;

          結(jié)構(gòu)偽類

          • :root:文檔的根元素;
          • :empty:無子元素的元素;
          • :first-letter:元素的首字母;
          • :first-line:元素的首行;
          • :nth-child(n):元素中指定順序索引的元素;
          • :nth-last-child(n):元素中指定逆序索引的元素;;
          • :first-child :元素中為首的元素;
          • :last-child :元素中為尾的元素;
          • :only-child:父元素僅有該元素的元素;
          • :nth-of-type(n) :標簽中指定順序索引的標簽;
          • :nth-last-of-type(n):標簽中指定逆序索引的標簽;
          • :first-of-type :標簽中為首的標簽;
          • :last-of-type:標簽中為尾標簽;
          • :only-of-type:父元素僅有該標簽的標簽;

          偽元素

          • ::before:在元素前插入內(nèi)容;
          • ::after:在元素后插入內(nèi)容;

          優(yōu)先級

          優(yōu)先級就是分配給指定的 CSS 聲明的一個權(quán)重,它由匹配的選擇器中的每一種選擇器類型的數(shù)值決定。為了記憶,可以把權(quán)重分成如下幾個等級,數(shù)值越大的權(quán)重越高:

          • 10000:!important;
          • 01000:內(nèi)聯(lián)樣式;
          • 00100:ID 選擇器;
          • 00010:類選擇器、偽類選擇器、屬性選擇器;
          • 00001:元素選擇器、偽元素選擇器;
          • 00000:通配選擇器、后代選擇器、兄弟選擇器;

          可以看到內(nèi)聯(lián)樣式(通過元素中 style 屬性定義的樣式)的優(yōu)先級大于任何選擇器;而給屬性值加上 !important 又可以把優(yōu)先級提至最高,就是因為它的優(yōu)先級最高,所以需要謹慎使用它,以下有些使用注意事項:

          • 一定要優(yōu)先考慮使用樣式規(guī)則的優(yōu)先級來解決問題而不是 !important;
          • 只有在需要覆蓋全站或外部 CSS 的特定頁面中使用 !important;
          • 永遠不要在你的插件中使用 !important;
          • 永遠不要在全站范圍的 CSS 代碼中使用 !important;

          繼承性

          在 CSS 中有一個很重要的特性就是子元素會繼承父元素對應屬性計算后的值。比如頁面根元素 html 的文本顏色默認是黑色的,頁面中的所有其他元素都將繼承這個顏色,當申明了如下樣式后,H1 文本將變成橙色。

          css復制代碼body {
              color: orange;
          }
          h1 {
              color: inherit;
          }
          

          設(shè)想一下,如果 CSS 中不存在繼承性,那么我們就需要為不同文本的標簽都設(shè)置一下 color,這樣一來的后果就是 CSS 的文件大小就會無限增大。

          CSS 屬性很多,但并不是所有的屬性默認都是能繼承父元素對應屬性的,那哪些屬性存在默認繼承的行為呢?一定是那些不會影響到頁面布局的屬性,可以分為如下幾類:

          • 字體相關(guān):font-family、font-style、font-size、font-weight 等;
          • 文本相關(guān):text-align、text-indent、text-decoration、text-shadow、letter-spacing、word-spacing、white-space、line-height、color 等;
          • 列表相關(guān):list-style、list-style-image、list-style-type、list-style-position 等;
          • 其他屬性:visibility、cursor 等;

          對于其他默認不繼承的屬性也可以通過以下幾個屬性值來控制繼承行為:

          • inherit:繼承父元素對應屬性的計算值;
          • initial:應用該屬性的默認值,比如 color 的默認值是 #000;
          • unset:如果屬性是默認可以繼承的,則取 inherit 的效果,否則同 initial;
          • revert:效果等同于 unset,兼容性差。

          文檔流

          在 CSS 的世界中,會把內(nèi)容按照從左到右、從上到下的順序進行排列顯示。正常情況下會把頁面分割成一行一行的顯示,而每行又可能由多列組成,所以從視覺上看起來就是從上到下從左到右,而這就是 CSS 中的流式布局,又叫文檔流。文檔流就像水一樣,能夠自適應所在的容器,一般它有如下幾個特性:

          • 塊級元素默認會占滿整行,所以多個塊級盒子之間是從上到下排列的;
          • 內(nèi)聯(lián)元素默認會在一行里一列一列的排布,當一行放不下的時候,會自動切換到下一行繼續(xù)按照列排布;

          如何脫離文檔流呢?

          脫流文檔流指節(jié)點脫流正常文檔流后,在正常文檔流中的其他節(jié)點將忽略該節(jié)點并填補其原先空間。文檔一旦脫流,計算其父節(jié)點高度時不會將其高度納入,脫流節(jié)點不占據(jù)空間。有兩種方式可以讓元素脫離文檔流:浮動和定位。

          • 使用浮動(float)會將元素脫離文檔流,移動到容器左/右側(cè)邊界或者是另一個浮動元素旁邊,該浮動元素之前占用的空間將被別的元素填補,另外浮動之后所占用的區(qū)域不會和別的元素之間發(fā)生重疊;
          • 使用絕對定位(position: absolute;)或者固定定位(position: fixed;)也會使得元素脫離文檔流,且空出來的位置將自動被后續(xù)節(jié)點填補。

          盒模型

          在 CSS 中任何元素都可以看成是一個盒子,而一個盒子是由 4 部分組成的:內(nèi)容(content)、內(nèi)邊距(padding)、邊框(border)和外邊距(margin)。

          盒模型有 2 種:標準盒模型和 IE 盒模型,本別是由 W3C 和 IExplore 制定的標準。

          如果給某個元素設(shè)置如下樣式:

          css復制代碼.box {
              width: 200px;
              height: 200px;
              padding: 10px;
              border: 1px solid #eee;
              margin: 10px;
          }
          

          標準盒模型認為:盒子的實際尺寸=內(nèi)容(設(shè)置的寬/高) + 內(nèi)邊距 + 邊框

          所以 .box 元素內(nèi)容的寬度就為 200px,而實際的寬度則是 width + padding-left + padding-right + border-left-width + border-right-width=200 + 10 + 10 + 1 + 1=222。

          IE 盒模型認為:盒子的實際尺寸=設(shè)置的寬/高=內(nèi)容 + 內(nèi)邊距 + 邊框

          .box 元素所占用的實際寬度為 200px,而內(nèi)容的真實寬度則是 width - padding-left - padding-right - border-left-width - border-right-width=200 - 10 - 10 - 1 - 1=178。

          現(xiàn)在高版本的瀏覽器基本上默認都是使用標準盒模型,而像 IE6 這種老古董才是默認使用 IE 盒模型的。

          在 CSS3 中新增了一個屬性 box-sizing,允許開發(fā)者來指定盒子使用什么標準,它有 2 個值:

          • content-box:標準盒模型;
          • border-box:IE 盒模型;

          視覺格式化模型

          視覺格式化模型(Visual formatting model)是用來處理和在視覺媒體上顯示文檔時使用的計算規(guī)則。CSS 中一切皆盒子,而視覺格式化模型簡單來理解就是規(guī)定這些盒子應該怎么樣放置到頁面中去,這個模型在計算的時候會依賴到很多的因素,比如:盒子尺寸、盒子類型、定位方案(是浮動還是定位)、兄弟元素或者子元素以及一些別的因素。

          從上圖中可以看到視覺格式化模型涉及到的內(nèi)容很多,有興趣深入研究的可以結(jié)合上圖看這個 W3C 的文檔 Visual formatting model。所以這里就簡單介紹下盒子類型。

          盒子類型由 display 決定,同時給一個元素設(shè)置 display 后,將會決定這個盒子的 2 個顯示類型(display type):

          • outer display type(對外顯示):決定了該元素本身是如何布局的,即參與何種格式化上下文;
          • inner display type(對內(nèi)顯示):其實就相當于把該元素當成了容器,規(guī)定了其內(nèi)部子元素是如何布局的,參與何種格式化上下文;

          outer display type

          對外顯示方面,盒子類型可以分成 2 類:block-level box(塊級盒子) 和 inline-level box(行內(nèi)級盒子)。

          依據(jù)上圖可以列出都有哪些塊級和行內(nèi)級盒子:

          • 塊級盒子:display 為 block、list-item、table、flex、grid、flow-root 等;
          • 行內(nèi)級盒子:display 為 inline、inline-block、inline-table 等;

          所有塊級盒子都會參與 BFC,呈現(xiàn)垂直排列;而所有行內(nèi)級盒子都參會 IFC,呈現(xiàn)水平排列。

          除此之外,block、inline 和 inline-block 還有什么更具體的區(qū)別呢?

          block

          • 占滿一行,默認繼承父元素的寬度;多個塊元素將從上到下進行排列;
          • 設(shè)置 width/height 將會生效;
          • 設(shè)置 padding 和 margin 將會生效;

          inline

          • 不會占滿一行,寬度隨著內(nèi)容而變化;多個 inline 元素將按照從左到右的順序在一行里排列顯示,如果一行顯示不下,則自動換行;
          • 設(shè)置 width/height 將不會生效;
          • 設(shè)置豎直方向上的 padding 和 margin 將不會生效;

          inline-block

          • 是行內(nèi)塊元素,不單獨占滿一行,可以看成是能夠在一行里進行左右排列的塊元素;
          • 設(shè)置 width/height 將會生效;
          • 設(shè)置 padding 和 margin 將會生效;

          inner display type

          對內(nèi)方面,其實就是把元素當成了容器,里面包裹著文本或者其他子元素。container box 的類型依據(jù) display 的值不同,分為 4 種:

          • block container:建立 BFC 或者 IFC;
          • flex container:建立 FFC;
          • grid container:建立 GFC;
          • ruby container:接觸不多,不做介紹。

          值得一提的是如果把 img 這種替換元素(replaced element)申明為 block 是不會產(chǎn)生 container box 的,因為替換元素比如 img 設(shè)計的初衷就僅僅是通過 src 把內(nèi)容替換成圖片,完全沒考慮過會把它當成容器。

          參考:

          • CSS 原理 - 你所不知道的 display
          • 格式化上下文

          格式化上下文

          格式化上下文(Formatting Context)是 CSS2.1 規(guī)范中的一個概念,大概說的是頁面中的一塊渲染區(qū)域,規(guī)定了渲染區(qū)域內(nèi)部的子元素是如何排版以及相互作用的。

          不同類型的盒子有不同格式化上下文,大概有這 4 類:

          • BFC (Block Formatting Context) 塊級格式化上下文;
          • IFC (Inline Formatting Context) 行內(nèi)格式化上下文;
          • FFC (Flex Formatting Context) 彈性格式化上下文;
          • GFC (Grid Formatting Context) 格柵格式化上下文;

          其中 BFC 和 IFC 在 CSS 中扮演著非常重要的角色,因為它們直接影響了網(wǎng)頁布局,所以需要深入理解其原理。

          BFC

          塊格式化上下文,它是一個獨立的渲染區(qū)域,只有塊級盒子參與,它規(guī)定了內(nèi)部的塊級盒子如何布局,并且與這個區(qū)域外部毫不相干。

          BFC 渲染規(guī)則

          • 內(nèi)部的盒子會在垂直方向,一個接一個地放置;
          • 盒子垂直方向的距離由 margin 決定,屬于同一個 BFC 的兩個相鄰盒子的 margin 會發(fā)生重疊;
          • 每個元素的 margin 的左邊,與包含塊 border 的左邊相接觸(對于從左往右的格式化,否則相反),即使存在浮動也是如此;
          • BFC 的區(qū)域不會與 float 盒子重疊;
          • BFC 就是頁面上的一個隔離的獨立容器,容器里面的子元素不會影響到外面的元素。反之也如此。
          • 計算 BFC 的高度時,浮動元素也參與計算。

          如何創(chuàng)建 BFC?

          • 根元素:html
          • 非溢出的可見元素:overflow 不為 visible
          • 設(shè)置浮動:float 屬性不為 none
          • 設(shè)置定位:position 為 absolute 或 fixed
          • 定義成塊級的非塊級元素:display: inline-block/table-cell/table-caption/flex/inline-flex/grid/inline-grid

          BFC 應用場景

          1、 自適應兩欄布局

          應用原理:BFC 的區(qū)域不會和浮動區(qū)域重疊,所以就可以把側(cè)邊欄固定寬度且左浮動,而對右側(cè)內(nèi)容觸發(fā) BFC,使得它的寬度自適應該行剩余寬度。

          html復制代碼<div class="layout">
              <div class="aside">aside</div>
              <div class="main">main</div>
          </div>
          
          css復制代碼.aside {
              float: left;
              width: 100px;
          }
          .main {
              <!-- 觸發(fā) BFC -->
              overflow: auto;
          }
          

          2、清除內(nèi)部浮動

          浮動造成的問題就是父元素高度坍塌,所以清除浮動需要解決的問題就是讓父元素的高度恢復正常。而用 BFC 清除浮動的原理就是:計算 BFC 的高度時,浮動元素也參與計算。只要觸發(fā)父元素的 BFC 即可。

          css復制代碼.parent {
              overflow: hidden;
          }
          

          3、 防止垂直 margin 合并

          BFC 渲染原理之一:同一個 BFC 下的垂直 margin 會發(fā)生合并。所以如果讓 2 個元素不在同一個 BFC 中即可阻止垂直 margin 合并。那如何讓 2 個相鄰的兄弟元素不在同一個 BFC 中呢?可以給其中一個元素外面包裹一層,然后觸發(fā)其包裹層的 BFC,這樣一來 2 個元素就不會在同一個 BFC 中了。

          html復制代碼<div class="layout">
              <div class="a">a</div>
              <div class="contain-b">
                  <div class="b">b</div>
              </div>
          </div>
          
          css復制代碼.demo3 .a,
          .demo3 .b {
              border: 1px solid #999;
              margin: 10px;
          }
          .contain-b {
              overflow: hidden;
          }
          

          針對以上 3 個 示例 ,可以結(jié)合這個 BFC 應用示例 配合觀看更佳。

          參考:CSS 原理 - Formatting Context

          IFC

          IFC 的形成條件非常簡單,塊級元素中僅包含內(nèi)聯(lián)級別元素,需要注意的是當IFC中有塊級元素插入時,會產(chǎn)生兩個匿名塊將父元素分割開來,產(chǎn)生兩個 IFC。

          IFC 渲染規(guī)則

          • 子元素在水平方向上一個接一個排列,在垂直方向上將以容器頂部開始向下排列;
          • 節(jié)點無法聲明寬高,其中 margin 和 padding 在水平方向有效在垂直方向無效;
          • 節(jié)點在垂直方向上以不同形式對齊;
          • 能把在一行上的框都完全包含進去的一個矩形區(qū)域,被稱為該行的線盒(line box)。線盒的寬度是由包含塊(containing box)和與其中的浮動來決定;
          • IFC 中的 line box 一般左右邊貼緊其包含塊,但 float 元素會優(yōu)先排列。
          • IFC 中的 line box 高度由 line-height 計算規(guī)則來確定,同個 IFC 下的多個 line box 高度可能會不同;
          • 當內(nèi)聯(lián)級盒子的總寬度少于包含它們的 line box 時,其水平渲染規(guī)則由 text-align 屬性值來決定;
          • 當一個內(nèi)聯(lián)盒子超過父元素的寬度時,它會被分割成多盒子,這些盒子分布在多個 line box 中。如果子元素未設(shè)置強制換行的情況下,inline box 將不可被分割,將會溢出父元素。

          針對如上的 IFC 渲染規(guī)則,你是不是可以分析下下面這段代碼的 IFC 環(huán)境是怎么樣的呢?

          html復制代碼<p>It can get <strong>very complicated</storng> once you start looking into it.</p>
          

          對應上面這樣一串 HTML 分析如下:

          • p 標簽是一個 block container,對內(nèi)將產(chǎn)生一個 IFC;
          • 由于一行沒辦法顯示完全,所以產(chǎn)生了 2 個線盒(line box);線盒的寬度就繼承了 p 的寬度;高度是由里面的內(nèi)聯(lián)盒子的 line-height 決定;
          • It can get:匿名的內(nèi)聯(lián)盒子;
          • very complicated:strong 標簽產(chǎn)生的內(nèi)聯(lián)盒子;
          • once you start:匿名的內(nèi)聯(lián)盒子;
          • looking into it.:匿名的內(nèi)聯(lián)盒子。

          參考:Inline formatting contexts

          IFC 應用場景

          • 水平居中:當一個塊要在環(huán)境中水平居中時,設(shè)置其為 inline-block 則會在外層產(chǎn)生 IFC,通過 text-align 則可以使其水平居中。
          • 垂直居中:創(chuàng)建一個 IFC,用其中一個元素撐開父元素的高度,然后設(shè)置其 vertical-align: middle,其他行內(nèi)元素則可以在此父元素下垂直居中。

          偷個懶,demo 和圖我就不做了。

          層疊上下文

          在電腦顯示屏幕上的顯示的頁面其實是一個三維的空間,水平方向是 X 軸,豎直方向是 Y 軸,而屏幕到眼睛的方向可以看成是 Z 軸。眾 HTML 元素依據(jù)自己定義的屬性的優(yōu)先級在 Z 軸上按照一定的順序排開,而這其實就是層疊上下文所要描述的東西。

          我們對層疊上下文的第一印象可能要來源于 z-index,認為它的值越大,距離屏幕觀察者就越近,那么層疊等級就越高,事實確實是這樣的,但層疊上下文的內(nèi)容遠非僅僅如此:

          • z-index 能夠在層疊上下文中對元素的堆疊順序其作用是必須配合定位才可以;
          • 除了 z-index 之外,一個元素在 Z 軸上的顯示順序還受層疊等級和層疊順序影響;

          在看層疊等級和層疊順序之前,我們先來看下如何產(chǎn)生一個層疊上下文,特定的 HTML 元素或者 CSS 屬性產(chǎn)生層疊上下文,MDN 中給出了這么一個列表,符合以下任一條件的元素都會產(chǎn)生層疊上下文:

          • html 文檔根元素
          • 聲明 position: absolute/relative 且 z-index 值不為 auto 的元素;
          • 聲明 position: fixed/sticky 的元素;
          • flex 容器的子元素,且 z-index 值不為 auto;
          • grid 容器的子元素,且 z-index 值不為 auto;
          • opacity 屬性值小于 1 的元素;
          • mix-blend-mode 屬性值不為 normal 的元素;
          • 以下任意屬性值不為 none 的元素: transform filter perspective clip-path mask / mask-image / mask-border
          • isolation 屬性值為 isolate 的元素;
          • -webkit-overflow-scrolling 屬性值為 touch 的元素;
          • will-change 值設(shè)定了任一屬性而該屬性在 non-initial 值時會創(chuàng)建層疊上下文的元素;
          • contain 屬性值為 layout、paint 或包含它們其中之一的合成值(比如 contain: strict、contain: content)的元素。

          層疊等級

          層疊等級指節(jié)點在三維空間 Z 軸上的上下順序。它分兩種情況:

          • 在同一個層疊上下文中,它描述定義的是該層疊上下文中的層疊上下文元素在 Z 軸上的上下順序;
          • 在其他普通元素中,它描述定義的是這些普通元素在 Z 軸上的上下順序;

          普通節(jié)點的層疊等級優(yōu)先由其所在的層疊上下文決定,層疊等級的比較只有在當前層疊上下文中才有意義,脫離當前層疊上下文的比較就變得無意義了。

          層疊順序

          在同一個層疊上下文中如果有多個元素,那么他們之間的層疊順序是怎么樣的呢?

          以下這個列表越往下層疊優(yōu)先級越高,視覺上的效果就是越容易被用戶看到(不會被其他元素覆蓋):

          • 層疊上下文的 border 和 background
          • z-index < 0 的子節(jié)點
          • 標準流內(nèi)塊級非定位的子節(jié)點
          • 浮動非定位的子節(jié)點
          • 標準流內(nèi)行內(nèi)非定位的子節(jié)點
          • z-index: auto/0 的子節(jié)點
          • z-index > 0的子節(jié)點

          如何比較兩個元素的層疊等級?

          • 在同一個層疊上下文中,比較兩個元素就是按照上圖的介紹的層疊順序進行比較。
          • 如果不在同一個層疊上下文中的時候,那就需要比較兩個元素分別所處的層疊上下文的等級。
          • 如果兩個元素都在同一個層疊上下文,且層疊順序相同,則在 HTML 中定義越后面的層疊等級越高。

          參考:徹底搞懂CSS層疊上下文、層疊等級、層疊順序、z-index

          值和單位

          CSS 的聲明是由屬性和值組成的,而值的類型有許多種:

          • 數(shù)值:長度值 ,用于指定例如元素 width、border-width、font-size 等屬性的值;
          • 百分比:可以用于指定尺寸或長度,例如取決于父容器的 width、height 或默認的 font-size;
          • 顏色:用于指定 background-color、color 等;
          • 坐標位置:以屏幕的左上角為坐標原點定位元素的位置,比如常見的 background-position、top、right、bottom 和 left 等屬性;
          • 函數(shù):用于指定資源路徑或背景圖片的漸變,比如 url()、linear-gradient() 等;

          而還有些值是需要帶單位的,比如 width: 100px,這里的 px 就是表示長度的單位,長度單位除了 px 外,比較常用的還有 em、rem、vw/vh 等。那他們有什么區(qū)別呢?又應該在什么時候使用它們呢?

          px

          屏幕分辨率是指在屏幕的橫縱方向上的像素點數(shù)量,比如分辨率 1920×1080 意味著水平方向含有 1920 個像素數(shù),垂直方向含有 1080 個像素數(shù)。

          而 px 表示的是 CSS 中的像素,在 CSS 中它是絕對的長度單位,也是最基礎(chǔ)的單位,其他長度單位會自動被瀏覽器換算成 px。但是對于設(shè)備而言,它其實又是相對的長度單位,比如寬高都為 2px,在正常的屏幕下,其實就是 4 個像素點,而在設(shè)備像素比(devicePixelRatio) 為 2 的 Retina 屏幕下,它就有 16 個像素點。所以屏幕尺寸一致的情況下,屏幕分辨率越高,顯示效果就越細膩。

          講到這里,還有一些相關(guān)的概念需要理清下:

          設(shè)備像素(Device pixels)

          設(shè)備屏幕的物理像素,表示的是屏幕的橫縱有多少像素點;和屏幕分辨率是差不多的意思。

          設(shè)備像素比(DPR)

          設(shè)備像素比表示 1 個 CSS 像素等于幾個物理像素。

          計算公式:DPR=物理像素數(shù) / 邏輯像素數(shù);

          在瀏覽器中可以通過 window.devicePixelRatio 來獲取當前屏幕的 DPR。

          像素密度(DPI/PPI)

          像素密度也叫顯示密度或者屏幕密度,縮寫為 DPI(Dots Per Inch) 或者 PPI(Pixel Per Inch)。從技術(shù)角度說,PPI 只存在于計算機顯示領(lǐng)域,而 DPI 只出現(xiàn)于打印或印刷領(lǐng)域。

          計算公式:像素密度=屏幕對角線的像素尺寸 / 物理尺寸

          比如,對于分辨率為 750 * 1334 的 iPhone 6 來說,它的像素密度為:

          js復制代碼Math.sqrt(750 * 750 + 1334 * 1334) / 4.7=326ppi
          

          設(shè)備獨立像素(DIP)

          DIP 是特別針對 Android設(shè)備而衍生出來的,原因是安卓屏幕的尺寸繁多,因此為了顯示能盡量和設(shè)備無關(guān),而提出的這個概念。它是基于屏幕密度而計算的,認為當屏幕密度是 160 的時候,px=DIP。

          計算公式:dip=px * 160 / dpi

          em

          em 是 CSS 中的相對長度單位中的一個。居然是相對的,那它到底是相對的誰呢?它有 2 層意思:

          • 在 font-size 中使用是相對于父元素的 font-size 大小,比如父元素 font-size: 16px,當給子元素指定 font-size: 2em 的時候,經(jīng)過計算后它的字體大小會是 32px;
          • 在其他屬性中使用是相對于自身的字體大小,如 width/height/padding/margin 等;

          我們都知道每個瀏覽器都會給 HTML 根元素 html 設(shè)置一個默認的 font-size,而這個值通常是 16px。這也就是為什么 1em=16px 的原因所在了。

          em 在計算的時候是會層層計算的,比如:

          html復制代碼<div>
              <p></p>
          </div>
          
          css復制代碼div { font-size: 2em; }
          p { font-size: 2em; }
          

          對于如上一個結(jié)構(gòu)的 HTML,由于根元素 html 的字體大小是 16px,所以 p 標簽最終計算出來后的字體大小會是 16 * 2 * 2=64px

          rem

          rem(root em) 和 em 一樣,也是一個相對長度單位,不過 rem 相對的是 HTML 的根元素 html。

          rem 由于是基于 html 的 font-size 來計算,所以通常用于自適應網(wǎng)站或者 H5 中。

          比如在做 H5 的時候,前端通常會讓 UI 給 750px 寬的設(shè)計圖,而在開發(fā)的時候可以基于 iPhone X 的尺寸 375px * 812px 來寫頁面,這樣一來的話,就可以用下面的 JS 依據(jù)當前頁面的視口寬度自動計算出根元素 html 的基準 font-size 是多少。

          js復制代碼(function (doc, win) {
              var docEl=doc.documentElement,
                  resizeEvt='orientationchange' in window ? 'orientationchange' : 'resize',
                  psdWidth=750,  // 設(shè)計圖寬度
                  recalc=function () {
                      var clientWidth=docEl.clientWidth;
                      if ( !clientWidth ) return;
                      if ( clientWidth >=640 ) {
                          docEl.style.fontSize=200 * ( 640 / psdWidth ) + 'px';
                      } else {
                          docEl.style.fontSize=200 * ( clientWidth / psdWidth ) + 'px';
                      }
                  };
          
              if ( !doc.addEventListener ) return;
              // 綁定事件的時候最好配合防抖函數(shù)
              win.addEventListener( resizeEvt, debounce(recalc, 1000), false );
              doc.addEventListener( 'DOMContentLoaded', recalc, false );
              
              function debounce(func, wait) {
                  var timeout;
                  return function () {
                      var context=this;
                      var args=arguments;
                      clearTimeout(timeout)
                      timeout=setTimeout(function(){
                          func.apply(context, args)
                      }, wait);
                  }
              }
          })(document, window);
          

          比如當視口是 375px 的時候,經(jīng)過計算 html 的 font-size 會是 100px,這樣有什么好處呢?好處就是方便寫樣式,比如從設(shè)計圖量出來的 header 高度是 50px 的,那我們寫樣式的時候就可以直接寫:

          css復制代碼header {
              height: 0.5rem;
          }
          

          每個從設(shè)計圖量出來的尺寸只要除于 100 即可得到當前元素的 rem 值,都不用經(jīng)過計算,非常方便。偷偷告訴你,如果你把上面那串計算 html 標簽 font-size 的 JS 代碼中的 200 替換成 2,那在計算 rem 的時候就不需要除于 100 了,從設(shè)計圖量出多大 px,就直接寫多少個 rem。

          vw/vh

          vw 和 vh 分別是相對于屏幕視口寬度和高度而言的長度單位:

          • 1vw=視口寬度均分成 100 份中 1 份的長度;
          • 1vh=視口高度均分成 100 份中 1 份的長度;

          在 JS 中 100vw=window.innerWidth,100vh=window.innerHeight。

          vw/vh 的出現(xiàn)使得多了一種寫自適應布局的方案,開發(fā)者不再局限于 rem 了。

          相對視口的單位,除了 vw/vh 外,還有 vmin 和 vmax:

          • vmin:取 vw 和 vh 中值較小的;
          • vmax:取 vw 和 vh 中值較大的;

          顏色體系

          CSS 中用于表示顏色的值種類繁多,足夠構(gòu)成一個體系,所以這里就專門拿出一個小節(jié)來講解它。

          根據(jù) CSS 顏色草案 中提到的顏色值類型,大概可以把它們分為這幾類:

          • 顏色關(guān)鍵字
          • transparent 關(guān)鍵字
          • currentColor 關(guān)鍵字
          • RGB 顏色
          • HSL 顏色

          顏色關(guān)鍵字

          顏色關(guān)鍵字(color keywords)是不區(qū)分大小寫的標識符,它表示一個具體的顏色,比如 white(白),黑(black)等;

          可接受的關(guān)鍵字列表在CSS的演變過程中發(fā)生了改變:

          • CSS 標準 1 只接受 16 個基本顏色,稱為 VGA 顏色,因為它們來源于 VGA 顯卡所顯示的顏色集合而被稱為 VGA colors (視頻圖形陣列色彩)。
          • CSS 標準 2 增加了 orange 關(guān)鍵字。
          • 從一開始,瀏覽器接受其它的顏色,由于一些早期瀏覽器是 X11 應用程序,這些顏色大多數(shù)是 X11 命名的顏色列表,雖然有一點不同。SVG 1.0 是首個正式定義這些關(guān)鍵字的標準;CSS 色彩標準 3 也正式定義了這些關(guān)鍵字。它們經(jīng)常被稱作擴展的顏色關(guān)鍵字, X11 顏色或 SVG 顏色 。
          • CSS 顏色標準 4 添加可 rebeccapurple 關(guān)鍵字來紀念 web 先鋒 Eric Meyer。

          如下這張圖是 16 個基礎(chǔ)色,又叫 VGA 顏色。截止到目前為止 CSS 顏色關(guān)鍵字總共有 146 個,這里可以查看 完整的色彩關(guān)鍵字列表。

          需要注意的是如果聲明的時候的顏色關(guān)鍵字是錯誤的,瀏覽器會忽略它。

          transparent 關(guān)鍵字

          transparent 關(guān)鍵字表示一個完全透明的顏色,即該顏色看上去將是背景色。從技術(shù)上說,它是帶有 alpha 通道為最小值的黑色,是 rgba(0,0,0,0) 的簡寫。

          透明關(guān)鍵字有什么應用場景呢?

          實現(xiàn)三角形

          下面這個圖是用 4 條邊框填充的正方形,看懂了它你大概就知道該如何用 CSS 寫三角形了。

          css復制代碼div {
              border-top-color: #ffc107;
              border-right-color: #00bcd4;
              border-bottom-color: #e26b6b;
              border-left-color: #cc7cda;
              border-width: 50px;
              border-style: solid;
          }
          

          用 transparent 實現(xiàn)三角形的原理:

          • 首先寬高必須是 0px,通過邊框的粗細來填充內(nèi)容;
          • 那條邊需要就要加上顏色,而不需要的邊則用 transparent;
          • 想要什么樣姿勢的三角形,完全由上下左右 4 條邊的中有顏色的邊和透明的邊的位置決定;
          • 等腰三角形:設(shè)置一條邊有顏色,然后緊挨著的 2 邊是透明,且寬度是有顏色邊的一半;直角三角形:設(shè)置一條邊有顏色,然后緊挨著的任何一邊透明即可。

          看下示例:

          增大點擊區(qū)域

          常常在移動端的時候點擊的按鈕的區(qū)域特別小,但是由于現(xiàn)實效果又不太好把它做大,所以常用的一個手段就是通過透明的邊框來增大按鈕的點擊區(qū)域:

          css復制代碼.btn {
              border: 5px solid transparent;
          }
          

          currentColor 關(guān)鍵字

          currentColor 會取當前元素繼承父級元素的文本顏色值或聲明的文本顏色值,即 computed 后的 color 值。

          比如,對于如下 CSS,該元素的邊框顏色會是 red:

          css復制代碼.btn {
              color: red;
              border: 1px solid currentColor;
          }
          

          RGB[A] 顏色

          RGB[A] 顏色是由 R(red)-G(green)-B(blue)-A(alpha) 組成的色彩空間。

          在 CSS 中,它有兩種表示形式:

          • 十六進制符號;
          • 函數(shù)符;

          十六進制符號

          RGB 中的每種顏色的值范圍是 00~ff,值越大表示顏色越深。所以一個顏色正常是 6 個十六進制字符加上 # 組成,比如紅色就是 #ff0000。

          如果 RGB 顏色需要加上不透明度,那就需要加上 alpha 通道的值,它的范圍也是 00~ff,比如一個帶不透明度為 67% 的紅色可以這樣寫 #ff0000aa。

          使用十六進制符號表示顏色的時候,都是用 2 個十六進制表示一個顏色,如果這 2 個字符相同,還可以縮減成只寫 1 個,比如,紅色 #f00;帶 67% 不透明度的紅色 #f00a。

          函數(shù)符

          當 RGB 用函數(shù)表示的時候,每個值的范圍是 0~255 或者 0%~100%,所以紅色是 rgb(255, 0, 0), 或者 rgb(100%, 0, 0)。

          如果需要使用函數(shù)來表示帶不透明度的顏色值,值的范圍是 0~1 及其之間的小數(shù)或者 0%~100%,比如帶 67% 不透明度的紅色是 rgba(255, 0, 0, 0.67) 或者 rgba(100%, 0%, 0%, 67%)

          需要注意的是 RGB 這 3 個顏色值需要保持一致的寫法,要嘛用數(shù)字要嘛用百分比,而不透明度的值的可以不用和 RGB 保持一致寫法。比如 rgb(100%, 0, 0) 這個寫法是無效的;而 rgb(100%, 0%, 0%, 0.67) 是有效的。

          在第 4 代 CSS 顏色標準中,新增了一種新的函數(shù)寫法,即可以把 RGB 中值的分隔逗號改成空格,而把 RGB 和 alpha 中的逗號改成 /,比如帶 67% 不透明度的紅色可以這樣寫 rgba(255 0 0 / 0.67)。另外還把 rgba 的寫法合并到 rgb 函數(shù)中了,即 rgb 可以直接寫帶不透明度的顏色。

          HSL[A] 顏色

          HSL[A] 顏色是由色相(hue)-飽和度(saturation)-亮度(lightness)-不透明度組成的顏色體系。

          • 色相(H)是色彩的基本屬性,值范圍是 0360 或者 0deg360deg, 0 (或 360) 為紅色, 120 為綠色, 240 為藍色;
          • 飽和度(S)是指色彩的純度,越高色彩越純,低則逐漸變灰,取 0~100% 的數(shù)值;0% 為灰色, 100% 全色;
          • 亮度(L),取 0~100%,0% 為暗,100% 為白;
          • 不透明度(A),取 0100%,或者01及之間的小數(shù);

          寫法上可以參考 RGB 的寫法,只是參數(shù)的值不一樣。

          給一個按鈕設(shè)置不透明度為 67% 的紅色的 color 的寫法,以下全部寫法效果一致:

          css復制代碼button {
              color: #ff0000aa;
              color: #f00a;
              color: rgba(255, 0, 0, 0.67);
              color: rgb(100% 0% 0% / 67%);
              color: hsla(0, 100%, 50%, 67%);
              color: hsl(0deg 100% 50% / 67%);
          }
          

          小提示:在 Chrome DevTools 中可以按住 shift + 鼠標左鍵可以切換顏色的表示方式。

          媒體查詢

          媒體查詢是指針對不同的設(shè)備、特定的設(shè)備特征或者參數(shù)進行定制化的修改網(wǎng)站的樣式。

          你可以通過給 <link> 加上 media 屬性來指定該樣式文件只能對什么設(shè)備生效,不指定的話默認是 all,即對所有設(shè)備都生效:

          html復制代碼<link rel="stylesheet" src="styles.css" media="screen" />
          <link rel="stylesheet" src="styles.css" media="print" />
          

          都支持哪些設(shè)備類型?

          • all:適用于所有設(shè)備;
          • print:適用于在打印預覽模式下在屏幕上查看的分頁材料和文檔;
          • screen:主要用于屏幕;
          • speech:主要用于語音合成器。

          需要注意的是:通過 media 指定的 資源盡管不匹配它的設(shè)備類型,但是瀏覽器依然會加載它。

          除了通過 <link> 讓指定設(shè)備生效外,還可以通過 @media 讓 CSS 規(guī)則在特定的條件下才能生效。響應式頁面就是使用了 @media 才讓一個頁面能夠同時適配 PC、Pad 和手機端。

          css復制代碼@media (min-width: 1000px) {}
          

          媒體查詢支持邏輯操作符:

          • and:查詢條件都滿足的時候才生效;
          • not:查詢條件取反;
          • only:整個查詢匹配的時候才生效,常用語兼容舊瀏覽器,使用時候必須指定媒體類型;
          • 逗號或者 or:查詢條件滿足一項即可匹配;

          媒體查詢還支持眾多的媒體特性,使得它可以寫出很復雜的查詢條件:

          css復制代碼/* 用戶設(shè)備的最小高度為680px或為縱向模式的屏幕設(shè)備 */
          @media (min-height: 680px), screen and (orientation: portrait) {}
          

          常見需求

          自定義屬性

          之前我們通常是在預處理器里才可以使用變量,而現(xiàn)在 CSS 里也支持了變量的用法。通過自定義屬性就可以在想要使用的地方引用它。

          自定義屬性也和普通屬性一樣具有級聯(lián)性,申明在 :root 下的時候,在全文檔范圍內(nèi)可用,而如果是在某個元素下申明自定義屬性,則只能在它及它的子元素下才可以使用。

          自定義屬性必須通過 --x 的格式申明,比如:--theme-color: red; 使用自定義屬性的時候,需要用 var 函數(shù)。比如:

          css復制代碼<!-- 定義自定義屬性 -->
          :root {
              --theme-color: red;
          }
          
          <!-- 使用變量 -->
          h1 {
              color: var(--theme-color);
          }
          

          上圖這個是使用 CSS 自定義屬性配合 JS 實現(xiàn)的動態(tài)調(diào)整元素的 box-shadow,具體可以看這個 codepen demo。

          1px 邊框解決方案

          Retina 顯示屏比普通的屏幕有著更高的分辨率,所以在移動端的 1px 邊框就會看起來比較粗,為了美觀通常需要把這個線條細化處理。這里有篇文章列舉了 7 中方案可以參考一下:7種方法解決移動端Retina屏幕1px邊框問題

          而這里附上最后一種通過偽類和 transform 實現(xiàn)的相對完美的解決方案:

          只設(shè)置單條底部邊框:

          css復制代碼.scale-1px-bottom {
              position: relative;
              border:none;
          }
          .scale-1px-bottom::after {
              content: '';
              position: absolute;
              left: 0;
              bottom: 0;
              background: #000;
              width: 100%;
              height: 1px;
              -webkit-transform: scaleY(0.5);
              transform: scaleY(0.5);
              -webkit-transform-origin: 0 0;
              transform-origin: 0 0;
          }
          

          同時設(shè)置 4 條邊框:

          css復制代碼.scale-1px {
              position: relative;
              margin-bottom: 20px;
              border:none;
          }
          .scale-1px::after {
              content: '';
              position: absolute;
              top: 0;
              left: 0;
              border: 1px solid #000;
              -webkit-box-sizing: border-box;
              box-sizing: border-box;
              width: 200%;
              height: 200%;
              -webkit-transform: scale(0.5);
              transform: scale(0.5);
              -webkit-transform-origin: left top;
              transform-origin: left top;
          }
          

          清除浮動

          什么是浮動:浮動元素會脫離文檔流并向左/向右浮動,直到碰到父元素或者另一個浮動元素。

          為什么要清楚浮動,它造成了什么問題?

          因為浮動元素會脫離正常的文檔流,并不會占據(jù)文檔流的位置,所以如果一個父元素下面都是浮動元素,那么這個父元素就無法被浮動元素所撐開,這樣一來父元素就丟失了高度,這就是所謂的浮動造成的父元素高度坍塌問題。

          父元素高度一旦坍塌將對后面的元素布局造成影響,為了解決這個問題,所以需要清除浮動,讓父元素恢復高度,那該如何做呢?

          這里介紹兩種方法:通過 BFC 來清除、通過 clear 來清除。

          BFC 清除浮動

          前面介紹 BFC 的時候提到過,計算 BFC 高度的時候浮動子元素的高度也將計算在內(nèi),利用這條規(guī)則就可以清楚浮動。

          假設(shè)一個父元素 parent 內(nèi)部只有 2 個子元素 child,且它們都是左浮動的,這個時候 parent 如果沒有設(shè)置高度的話,因為浮動造成了高度坍塌,所以 parent 的高度會是 0,此時只要給 parent 創(chuàng)造一個 BFC,那它的高度就能恢復了。

          而產(chǎn)生 BFC 的方式很多,我們可以給父元素設(shè)置overflow: auto 來簡單的實現(xiàn) BFC 清除浮動,但是為了兼容 IE 最好用 overflow: hidden。

          css復制代碼.parent {
              overflow: hidden;
          }
          

          通過 overflow: hidden 來清除浮動并不完美,當元素有陰影或存在下拉菜單的時候會被截斷,所以該方法使用比較局限。

          通過 clear 清除浮動

          我先把結(jié)論貼出來:

          css復制代碼.clearfix {
              zoom: 1;
          }
          .clearfix::after {
              content: "";
              display: block;
              clear: both;
          }
          

          這種寫法的核心原理就是通過 ::after 偽元素為在父元素的最后一個子元素后面生成一個內(nèi)容為空的塊級元素,然后通過 clear 將這個偽元素移動到所有它之前的浮動元素的后面,畫個圖來理解一下。

          可以結(jié)合這個 codepen demo 一起理解上圖的 clear 清楚浮動原理。

          上面這個 demo 或者圖里為了展示需要所以給偽元素的內(nèi)容設(shè)置為了 ::after,實際使用的時候需要設(shè)置為空字符串,讓它的高度為 0,從而父元素的高度都是由實際的子元素撐開。

          該方式基本上是現(xiàn)在人人都在用的清除浮動的方案,非常通用。

          參考:CSS中的浮動和清除浮動,梳理一下

          消除瀏覽器默認樣式

          針對同一個類型的 HTML 標簽,不同的瀏覽器往往有不同的表現(xiàn),所以在網(wǎng)站制作的時候,開發(fā)者通常都是需要將這些瀏覽器的默認樣式清除,讓網(wǎng)頁在不同的瀏覽器上能夠保持一致。

          針對清除瀏覽器默認樣式這件事,在很早之前 CSS 大師 Eric A. Meyer 就干過。它就是寫一堆通用的樣式用來重置瀏覽器默認樣式,這些樣式通常會放到一個命名為 reset.css 文件中。比如大師的 reset.css 是這么寫的:

          css復制代碼html, body, div, span, applet, object, iframe,
          h1, h2, h3, h4, h5, h6, p, blockquote, pre,
          a, abbr, acronym, address, big, cite, code,
          del, dfn, em, img, ins, kbd, q, s, samp,
          small, strike, strong, sub, sup, tt, var,
          b, u, i, center,
          dl, dt, dd, ol, ul, li,
          fieldset, form, label, legend,
          table, caption, tbody, tfoot, thead, tr, th, td,
          article, aside, canvas, details, embed, 
          figure, figcaption, footer, header, hgroup, 
          menu, nav, output, ruby, section, summary,
          time, mark, audio, video {
              margin: 0;
              padding: 0;
              border: 0;
              font-size: 100%;
              font: inherit;
              vertical-align: baseline;
          }
          /* HTML5 display-role reset for older browsers */
          article, aside, details, figcaption, figure, 
          footer, header, hgroup, menu, nav, section {
              display: block;
          }
          body {
              line-height: 1;
          }
          ol, ul {
              list-style: none;
          }
          blockquote, q {
              quotes: none;
          }
          blockquote:before, blockquote:after,
          q:before, q:after {
              content: '';
              content: none;
          }
          table {
              border-collapse: collapse;
              border-spacing: 0;
          }
          

          他的這份 reset.css 據(jù)說是被使用最廣泛的重設(shè)樣式的方案了。

          除了 reset.css 外,后來又出現(xiàn)了 Normalize.css 。關(guān)于 Normalize.css, 其作者 necolas 專門寫了一篇文章介紹了它,并談到了它和 reset.css 的區(qū)別。這個是他寫那篇文章的翻譯版:讓我們談一談 Normalize.css。

          文章介紹到:Normalize.css 只是一個很小的CSS文件,但它在默認的 HTML 元素樣式上提供了跨瀏覽器的高度一致性。相比于傳統(tǒng)的 CSS reset,Normalize.css 是一種現(xiàn)代的、為 HTML5 準備的優(yōu)質(zhì)替代方案,現(xiàn)在已經(jīng)有很多知名的框架和網(wǎng)站在使用它了。

          Normalize.css 的具體樣式可以看這里 Normalize.css

          區(qū)別于 reset.css,Normalize.css 有如下特點:

          • reset.css 幾乎為所有標簽都設(shè)置了默認樣式,而 Normalize.css 則是有選擇性的保護了部分有價值的默認值;
          • 修復了很多瀏覽器的 bug,而這是 reset.css 沒做到的;
          • 不會讓你的調(diào)試工具變的雜亂,相反 reset.css 由于設(shè)置了很多默認值,所以在瀏覽器調(diào)試工具中往往會看到一大堆的繼承樣式,顯得很雜亂;
          • Normalize.css 是模塊化的,所以可以選擇性的去掉永遠不會用到的部分,比如表單的一般化;
          • Normalize.css 有詳細的說明文檔;

          長文本處理

          默認:字符太長溢出了容器

          字符超出部分換行

          字符超出位置使用連字符

          單行文本超出省略

          多行文本超出省略

          查看以上這些方案的示例: codepen demo

          有意思的是剛好前兩天看到 chokcoco 針對文本溢出也寫了一篇文章,主要突出的是對整塊的文本溢出處理。啥叫整塊文本?比如,下面這種技術(shù)標簽就是屬于整塊文本:

          另外他還對 iOS/Safari 做了兼容處理,感興趣的可以去閱讀下:CSS 整塊文本溢出省略特性探究。

          水平垂直居中

          讓元素在父元素中呈現(xiàn)出水平垂直居中的形態(tài),無非就 2 種情況:

          • 單行的文本、inline 或者 inline-block 元素;
          • 固定寬高的塊級盒子;
          • 不固定寬高的塊級盒子;

          以下列到的所有水平垂直居中方案這里寫了個 codepen demo,配合示例閱讀效果更佳。

          單行的文本、inline 或 inline-block 元素

          水平居中

          此類元素需要水平居中,則父級元素必須是塊級元素(block level),且父級元素上需要這樣設(shè)置樣式:

          css復制代碼.parent {
              text-align: center;
          }
          

          垂直居中

          方法一:通過設(shè)置上下內(nèi)間距一致達到垂直居中的效果:

          css復制代碼.single-line {
              padding-top: 10px;
              padding-bottom: 10px;
          }
          

          方法二:通過設(shè)置 height 和 line-height 一致達到垂直居中:

          css復制代碼.single-line {
              height: 100px;
              line-height: 100px;
          }
          

          固定寬高的塊級盒子

          方法一:absolute + 負 margin

          方法二:absolute + margin auto

          方法三:absolute + calc

          不固定寬高的塊級盒子

          這里列了 6 種方法,參考了顏海鏡 寫的文章 ,其中的兩種 line-height 和 writing-mode 方案看后讓我驚呼:還有這種操作?學到了學到了。

          方法一:absolute + transform

          方法二:line-height + vertical-align

          方法三:writing-mode

          方法四:table-cell

          方法五:flex

          方法六:grid

          常用布局

          兩欄布局(邊欄定寬主欄自適應)

          針對以下這些方案寫了幾個示例: codepen demo

          方法一:float + overflow(BFC 原理)

          方法二:float + margin

          方法三:flex

          方法四:grid

          三欄布局(兩側(cè)欄定寬主欄自適應)

          針對以下這些方案寫了幾個示例: codepen demo

          方法一:圣杯布局

          方法二:雙飛翼布局

          方法三:float + overflow(BFC 原理)

          方法四:flex

          方法五:grid

          多列等高布局

          結(jié)合示例閱讀更佳:codepen demo

          方法一:padding + 負margin

          方法二:設(shè)置父級背景圖片

          三行布局(頭尾定高主欄自適應)

          列了 4 種方法,都是基于如下的 HTML 和 CSS 的,結(jié)合示例閱讀效果更佳:codepen demo

          html復制代碼<div class="layout">
              <header></header>
              <main>
                  <div class="inner"></div>
              </main>
              <footer></footer>
          </div>
          
          css復制代碼html,
          body,
          .layout {
              height: 100%;
          }
          body {
              margin: 0;
          }
          header, 
          footer {
              height: 50px;
          }
          main {
              overflow-y: auto;
          }
          

          方法一:calc

          方法二:absolute

          方法三:flex

          方法四:grid

          結(jié)了個尾

          這是我斷斷續(xù)續(xù)寫了 2 周完成的文章,算是自己對 CSS 的一個總結(jié),雖然寫得很長,但不足以覆蓋所有 CSS 的知識,比如動畫和一些 CSS3 的新特性就完全沒涉及,因為這要寫下來估計得有大幾萬字(其實就是懶 )。

          碼字作圖不易,如果喜歡或者對你有絲毫幫助的話,幫忙點個 哈,點贊就是我的動力。同時也希望自己能堅持認真的寫下去,因為在總結(jié)提升自己的同時如果也能幫助更多的前端er,那將會讓我感覺很開心。


          作者:大海我來了
          鏈接:https://juejin.cn/post/6941206439624966152

          . 前言

          1.1 前端安全攻防的意義

          前端安全攻防的意義主要體現(xiàn)在以下幾個方面:

          1. 用戶隱私保護:前端作為用戶最先接觸到的界面,需要保障用戶私密信息(例如密碼、身份證號等)的安全,避免泄露或被竊取。
          2. 商業(yè)機密保護:頁面結(jié)構(gòu)、設(shè)計、業(yè)務流程等方面的保密性也同樣需要被保護,防止敏感信息被惡意利用。
          3. 防范攻擊:前端攻擊面廣、攻擊方式多樣,XSS、CSRF、Clickjacking等攻擊手段層出不窮,因此需要從前端層面考慮各種攻擊手段,提升系統(tǒng)安全性。
          4. 維護業(yè)務正常運行:前端代碼的安全性不僅僅涉及到網(wǎng)頁安全,還會對業(yè)務運行產(chǎn)生影響。比如,前端的RxJS代碼被篡改,會導致業(yè)務數(shù)據(jù)異常或丟失;前端的路由方式被竊取,會對系統(tǒng)性能造成不良影響。

          綜上所述,前端安全攻防的意義非常重要,必須要引起開發(fā)者的足夠重視與關(guān)注,從前端層面保障用戶和業(yè)務的安全。

          1.2 概述前端安全攻防的范疇和流程

          前端安全攻防的范疇主要包括 JavaScript、CSS、HTML 等前端代碼,以及網(wǎng)絡(luò)通信協(xié)議和構(gòu)建過程等多個層面。攻擊手段目前主要涵蓋 XSS、CSRF、Clickjacking 等方式。攻防流程主要包括:安全評估、漏洞挖掘、修復漏洞和安全培訓等環(huán)節(jié)。

          具體而言,前端安全攻防的流程包括以下步驟:

          1. 安全評估:了解前端代碼的攻擊面,評估系統(tǒng)安全性,確定攻擊面的重要性以及安全防范措施的缺陷等。
          2. 漏洞挖掘:主要包括源碼審計、代碼分析、滲透測試、模擬攻擊等方式,檢測系統(tǒng)漏洞并尋找風險點。
          3. 修復漏洞:對找到的漏洞逐一修復,并針對攻擊面提出相應的防范措施,如過濾、加密、驗證等。
          4. 安全培訓:加強對團隊成員的安全教育和意識培養(yǎng)、加強安全管理和監(jiān)督,避免重復或類似風險再次發(fā)生。
          5. 持續(xù)更新:由于攻擊手段可能會不斷變化和升級,前端開發(fā)人員需要及時了解安全最新動向,對代碼規(guī)范、協(xié)議以及工具進行不斷更新。

          綜上所述,前端安全攻防是一個協(xié)作的攻防流程,需要多個部門協(xié)作完成攻防任務,保障系統(tǒng)和用戶的安全。

          2. 攻擊技術(shù)

          2.1 XSS攻擊

          2.1.1 原理和類型

          XSS攻擊(Cross-Site Scripting攻擊)是一種利用Web應用程序中存在的漏洞,向客戶端注入惡意代碼,使之在用戶的瀏覽器上執(zhí)行的攻擊方式。

          XSS攻擊主要是利用Web應用程序沒有對用戶輸入的數(shù)據(jù)進行充分的過濾和驗證,使攻擊者得以在頁面上注入惡意代碼,從而在用戶訪問Web應用程序時,植入惡意代碼實現(xiàn)攻擊。

          XSS攻擊可以分為三個主要的類型:反射型 XSS、存儲型 XSS、DOM-based XSS

          具體的分類如下:

          1. 反射型 XSS:攻擊者通過構(gòu)造一些惡意的URL,將包含攻擊代碼的URL發(fā)送給目標用戶,使得用戶點擊該URL后,可以在用戶的瀏覽器上執(zhí)行惡意代碼,從而達到攻擊的效果。
          2. 存儲型 XSS:攻擊者將惡意代碼存儲在Web應用程序的服務器上,然后等待用戶訪問頁面,獲取存儲的惡意代碼并在用戶的瀏覽器上執(zhí)行。
          3. DOM-based XSS:攻擊者注入的惡意代碼會直接被頁面中的JavaScript解釋和執(zhí)行,繞過了服務器的編碼和過濾。

          綜上所述,XSS攻擊是通過對Web應用程序的注入攻擊達到攻擊效果的一種方式,攻擊者主要通過利用Web應用程序未能充分過濾和驗證用戶的輸入,將惡意代碼注入目標頁面進行攻擊,對于開發(fā)者來說需要注重應用中用戶輸入數(shù)據(jù)的過濾和驗證,防范XSS攻擊。

          2.1.2 預防和防御

          預防和防御 XSS 攻擊的方法包括以下幾個方面:

          1. 數(shù)據(jù)過濾和驗證:服務器端對輸入的數(shù)據(jù)進行過濾和驗證,確保其是合法、安全的數(shù)據(jù),包括數(shù)據(jù)類型、長度、格式等。可以使用現(xiàn)成的過濾函數(shù)或庫,也可以自定義開發(fā)數(shù)據(jù)過濾和驗證模塊。
          2. 防止代碼注入:盡量避免在頁面或JS代碼中出現(xiàn)用戶輸入的數(shù)據(jù),對于必須輸入的情況,可以使用轉(zhuǎn)義或加密等方式處理輸入的數(shù)據(jù),避免代碼被注入。
          3. HttpOnly:在設(shè)置 Cookies 時,使用 HttpOnly 屬性設(shè)置 CookiesHttpOnly 標記。這樣可以防止前端 JavaScript 讀取Cookies,因為Cookies中包含了一些敏感信息,如Session ID 等,防止 XSS 攻擊者利用CookiesXSS 攻擊。
          4. CSP:使用Content Security Policy(CSP)防止XSS攻擊。CSP規(guī)定了哪些資源可以被加載到頁面中,可以通過HTTP請求頭設(shè)置CSP。
          5. 安全編碼:在開發(fā)過程中,需要將安全編碼和安全設(shè)計作為考慮的重點,以便不斷提高對攻擊的抵御能力。
          6. 增強用戶意識:XSS攻擊大多針對用戶隨意點擊鏈接或輸入信息進行攻擊,因此對用戶進行安全意識的教育是預防和防御XSS攻擊的重要環(huán)節(jié)之一,如不隨意泄露個人信息和密碼等。

          綜上所述,對于開發(fā)人員來說,需要注意加強對XSS攻擊的防范,提高自身編碼水平,對用戶輸入的數(shù)據(jù)進行充分過濾和驗證,使用CSP配置, 安全編碼等措施加強代碼安全性。另外也需要注意與用戶的安全教育,提高用戶信息安全意識,避免被攻擊者利用和誤導。

          2.2 CSRF攻擊

          2.2.1 原理和類型

          CSRF攻擊(Cross-Site Request Forgery 攻擊)是一種利用用戶在已登錄的Web應用程序中的身份識別信息,通過從受害用戶處獲取的Cookie,偽造發(fā)起跨站請求的攻擊方式

          攻擊者通過構(gòu)造一個包含攻擊代碼的惡意鏈接,誘導用戶點擊,從而在用戶不知情的情況下將惡意代碼提交到目標網(wǎng)站,引發(fā)一系列滲透攻擊和數(shù)據(jù)竊取。

          CSRF攻擊可以分為兩種類型:GET型和POST型。

          具體而言

          • GET型 CSRF 攻擊可以通過構(gòu)造鏈接的方式,通常用于改變目標網(wǎng)站的狀態(tài)或進行輕量級的數(shù)據(jù)竊取;
          • POST型 CSRF 攻擊則需要偽造表單,惡意代碼通過 JavaScript 提交惡意表單信息到目標網(wǎng)站。

          綜上所述,CSRF攻擊利用用戶的登錄狀態(tài)偽造請求,從而越過了目標網(wǎng)站對用戶權(quán)限的防護。

          為了有效防御CSRF攻擊,業(yè)界提出了以下幾種預防和防御的策略:

          1. Token驗證:在表單提交中添加一個Token字段,通過生成唯一的Token,附加到提交的請求中,目標服務器會對Token和當前用戶的會話狀態(tài)進行驗證, 防止攻擊者偽造請求。
          2. Referer驗證:驗證請求中的Referer字段,判斷是否來源于信任的網(wǎng)頁,如果不是則認定為非法請求。
          3. 雙重 Cookie:在發(fā)送數(shù)據(jù)時,除了使用Session Cookies外,還可以通過直接在瀏覽器中設(shè)置一個隱藏字段帶有隨機值,之后在發(fā)送請求的時候?qū)⒃撾S機值同時發(fā)送到服務器端,然后服務器端再驗證該值是否正確,避免CSRF攻擊。
          4. 防止登錄跨站點:當用戶輸入密碼進行登錄時,要進行多次確認,確保用戶意識到當前已經(jīng)進入了目標站點。

          綜上所述,防御和預防CSRF攻擊需要綜合考慮多個方面,包括后端措施和前端措施,如在代碼實現(xiàn)中增加Token驗證、Referer驗證、使用雙重 Cookies、登錄跨站點確認等措施,結(jié)合用戶的安全教育,加強安全意識,提高應對CSRF攻擊能力。

          2.2.2 預防和防御

          預防和防御 CSRF 攻擊主要包括以下幾點:

          1. Token驗證:對于每個表單提交都增加一個Token值,并在服務器端驗證,來區(qū)分是合法的請求還是惡意的請求。
          2. Referer頭檢查:檢查HTTP請求頭中的Referer字段,如果該字段的值與當前請求的域名不一致,則可能是惡意請求。
          3. SameSite屬性設(shè)置:對于cookie使用SameSite屬性,在請求跨站時不會發(fā)送cookie,可以防止 CSRF 攻擊。
          4. 雙重驗證:比如在操作重要數(shù)據(jù)時,可以設(shè)置一個二步驗證,如短信或者郵件通知等。
          5. 防止自動提交:通過禁止自動提交表單、在請求中添加特殊的標識符、延遲提交等方式來防止惡意請求。
          6. 避免使用Cookie存儲敏感信息:當Cookie被盜取時,如果存儲敏感信息,可能會導致用戶的重要信息泄露。
          7. 加強安全教育:對于用戶,需要加強安全意識,提醒用戶保護好自己的賬戶,建議使用密碼管理器、不重復使用密碼等方式來避免CSRF攻擊。

          綜上所述,預防和防御CSRF攻擊需要在多個方面上下功夫。開發(fā)人員需要在代碼實現(xiàn)過程中增加Token驗證、Referer驗證、設(shè)置SameSite屬性、雙重驗證等措施,同時在用戶使用過程中,需要加強安全意識,比如不向陌生人泄露賬號信息等,從而避免攻擊者利用CSRF攻擊,保障用戶的安全和數(shù)據(jù)的保密性。

          3. 代碼層次

          3.1 JavaScript代碼安全

          3.1.1 客戶端JavaScript安全

          客戶端JavaScript安全主要包括以下幾個方面:

          1. 防止跨站腳本攻擊(XSS):在前端代碼中,要充分對用戶的輸入進行過濾和驗證,將用戶輸入的內(nèi)容轉(zhuǎn)義或進行編碼,以避免惡意腳本的注入或執(zhí)行。對于動態(tài)生成的內(nèi)容,也要謹慎檢查其來源和有效性,防止未知的腳本被執(zhí)行。
          2. 防止跨站請求偽造攻擊(CSRF):在Ajax請求中,要設(shè)置跨站請求偽造保護,例如添加 Token 或者使用 SameSite 屬性等方式來防止 CSRF 攻擊。
          3. 加密數(shù)據(jù)傳輸:在數(shù)據(jù)傳輸時,應使用 HTTPS 來加密數(shù)據(jù),防止敏感數(shù)據(jù)被攔截和篡改。
          4. 保護敏感數(shù)據(jù):將用戶的敏感信息,如身份證號、信用卡號等,加密保存,并使用適當?shù)拇鎯Π踩胧缡褂眉用芩惴ㄟM行傳輸、存儲加密等方式來保護用戶數(shù)據(jù)的安全。
          5. 防止代碼混淆和反編譯:使用 JavaScript 混淆工具將前端代碼進行混淆,避免惡意腳本攻擊。同時,也要注意保護代碼的發(fā)布環(huán)境和防止反編譯等反制措施。
          6. 加強用戶教育:提高用戶安全意識,避免被社交工程等方式利用,從而保障用戶信息的安全和私有性。

          綜上所述,客戶端JavaScript安全是Web應用開發(fā)中必須要非常注重的一個方面,主要需要開發(fā)人員從多個方面思考和考慮,包括充分過濾和驗證用戶的輸入數(shù)據(jù),使用 HTTPS 加密數(shù)據(jù)傳輸,使用 JavaScript 混淆工具等方式來保護前端代碼安全,同時也要針對用戶加強安全教育,提高其安全意識和預防風險的能力。

          3.1.2 服務器端JavaScript安全

          服務器端JavaScript安全主要包括以下幾個方面:

          1. 控制代碼執(zhí)行權(quán)限:對于服務器端執(zhí)行的 JavaScript 代碼,需要通過代碼控制和限制代碼執(zhí)行的權(quán)限,例如只允許執(zhí)行具體的一些函數(shù),或者只允許執(zhí)行某些特定的操作等,從而避免惡意代碼的執(zhí)行和危害。
          2. 防止注入攻擊:在編寫代碼時,需要重點考慮數(shù)據(jù)的輸入和輸出,避免注入攻擊竊取敏感數(shù)據(jù)或者進行其他惡意操作。常用方法包括數(shù)據(jù)過濾、輸入驗證、參數(shù)化查詢等。
          3. 安全的存儲:對于存儲敏感數(shù)據(jù),需要使用合適的加密算法進行加密存儲,從而保證數(shù)據(jù)的安全性和私密性。
          4. 防止拒絕服務攻擊:針對有惡意攻擊者可能發(fā)起的 DDOS 攻擊等拒絕服務攻擊,需要嚴格限制每個請求的處理時間,同時使用流量監(jiān)控、攻擊防護等方式緩解攻擊。
          5. 安全合規(guī)檢查:需要對服務器的安全進行定期的檢查和測試,發(fā)現(xiàn)和修復漏洞、提高安全意識,確保服務器端的代碼和系統(tǒng)的安全合規(guī)性。

          綜上所述,服務器端JavaScript安全是Web應用安全的重要環(huán)節(jié)之一,在服務端代碼的開發(fā)過程中必須要注重安全,充分考慮并控制代碼執(zhí)行的權(quán)限,防止注入攻擊和拒絕服務攻擊,使用合適的加密算法進行數(shù)據(jù)保護以及進行定期檢測測試,保證服務器端代碼的安全性和穩(wěn)定性。

          3.1.3 JavaScript代碼審計

          JavaScript 代碼審計是一種從代碼層面來分析、檢查和評估應用程序的安全性的方法,對于 Web 應用的開發(fā)和維護非常必要,可以有效地發(fā)現(xiàn)潛在的安全風險和漏洞,避免因漏洞造成的數(shù)據(jù)泄露、拒絕服務等安全問題。

          在 JavaScript 代碼審計的過程中,需要注意以下幾個方面:

          1. 檢查輸入過濾:輸入過濾是防止注入攻擊和 XSS 攻擊的關(guān)鍵。應該審計所有的輸入,包括 URL、表單提交、Cookie 等,并進行適當?shù)倪^濾和校驗,以避免攻擊者通過惡意輸入造成的安全漏洞。
          2. 分析數(shù)據(jù)流和控制流:在審計代碼時需要細致地分析代碼的數(shù)據(jù)流和控制流,了解變量和數(shù)據(jù)的來源,并考慮代碼中的判斷和分支。這樣有助于找到所有未被處理的輸入和輸出,以及代碼中存在的邏輯漏洞。
          3. 考慮客戶端和服務器端的安全性:在審計 JavaScript 代碼時,需要同時考慮客戶端和服務器端的安全性。因為 JavaScript 代碼通常會在客戶端和服務器端同時執(zhí)行,只有對兩端都進行審計,才能得到完整的安全評估結(jié)果。
          4. 尋找框架和庫的安全問題:因為開發(fā)人員通常會使用各種框架和庫來簡化代碼的開發(fā),審計 JavaScript 代碼時需要特別關(guān)注這些框架和庫的安全漏洞,注意版本更新和安全更新。
          5. 多種手段結(jié)合:審計 JavaScript 代碼不應僅僅通過手工閱讀代碼來進行。可以使用靜態(tài)分析工具、動態(tài)測試工具、模糊測試工具等多種手段進行結(jié)合使用。

          綜上所述,JavaScript 代碼審計是一項非常重要的安全工作,主要圍繞輸入過濾、數(shù)據(jù)流和控制流、客戶端和服務器端的安全性、框架和庫的安全問題以及多種手段的結(jié)合等方面來進行。只有從多個維度和角度進行審計,才能發(fā)現(xiàn)更多的潛在漏洞和安全風險,從而提高應用程序的安全性和穩(wěn)定性。

          3.2 CSS安全

          3.2.1 CSS注入攻擊

          CSS 注入攻擊是一種利用CSS樣式表的漏洞來進行攻擊的方式。攻擊者利用惡意 CSS 代碼,將樣式表中的一些屬性值改變,使網(wǎng)頁顯示出不正常的樣式。

          CSS注入攻擊的危害主要包括以下幾點:

          1. 篡改網(wǎng)頁內(nèi)容:攻擊者可以通過 CSS 注入,改變網(wǎng)頁的顏色、布局,混淆網(wǎng)頁,或者篡改網(wǎng)頁內(nèi)容,誘騙用戶進行惡意操作,例如點擊有害鏈接或者提供敏感信息等。
          2. 數(shù)據(jù)竊取:攻擊者可以通過 CSS 注入,對隱藏元素進行控制,達到竊取用戶敏感信息的目的。
          3. 拒絕服務攻擊:如果惡意CSS樣式表代碼導致網(wǎng)頁中的渲染和顯示過程出現(xiàn)錯誤,則會導致網(wǎng)站服務無法正常工作,如網(wǎng)站崩潰、頁面加載緩慢等。

          3.2.2 預防和防御

          下面是一些防范 CSS 注入攻擊的方法:

          1. 避免接受來自非信任源的 CSS 代碼,比如從網(wǎng)絡(luò)上任意下載的CSS代碼,需要先進行安全檢測之后再使用。
          2. 對于用戶提交的內(nèi)容,進行嚴格過濾和檢查,不接受來自未授權(quán)的 CSS 字符串。
          3. 防止 CSS 注入有關(guān)的操作,如限制遠程錨點鏈接的訪問,防止手動輸入 URL 等。
          4. 在開發(fā)代碼過程中,需要規(guī)范化使用 CSS,不使用能夠?qū)е伦⑷肼┒吹膭討B(tài) CSS 函數(shù)。
          5. 安全更新用戶輸入的最終結(jié)果,即用戶最終的 HTML 輸出結(jié)果,將用戶的輸入內(nèi)容進行過濾和轉(zhuǎn)義,確保用戶的輸入只作為數(shù)據(jù)不被作為代碼執(zhí)行。

          綜上所述,開發(fā)者需要重視 CSS 注入攻擊的預防和防御,并采取相應的措施,以避免安全事件的發(fā)生和用戶數(shù)據(jù)的泄露,從而保障網(wǎng)站的安全性和穩(wěn)定性。

          3.3 HTML安全

          3.3.1 HTML注入攻擊

          HTML 注入攻擊是一種利用HTML頁面的漏洞,往網(wǎng)站中插入惡意 HTML 代碼,從而導致用戶隱私數(shù)據(jù)被竊取的攻擊方式。

          常見的 HTML 注入攻擊主要包括以下幾種:

          1. XSS 攻擊:攻擊者通過惡意代碼,包括腳本和其他 HTML 代碼,注入到網(wǎng)站中,從而實現(xiàn)竊取用戶隱私數(shù)據(jù)、盜取身份驗證信息等損害行為。
          2. HTML 郵件注入攻擊:攻擊者通過電子郵件等方式,將包含惡意代碼的 HTML 電子郵件注入到網(wǎng)站中,達到篡改網(wǎng)站的目的。
          3. 對 HTML 表單的注入:攻擊者通過利用網(wǎng)站 HTML 表單的漏洞,為自己的目的在網(wǎng)站上插入惡意的 HTML 代碼,從而讓網(wǎng)站的提交數(shù)據(jù)帶有惡意代碼。

          3.3.2 預防和防御

          防止 HTML 注入攻擊需要采取以下措施:

          1. 過濾輸入數(shù)據(jù):抵御 HTML 注入攻擊最基本的方式是將所有輸入的數(shù)據(jù)進行過濾和校驗。此外,還需注意對 HTML 標記進行過濾和處理,比如替換 “<” 和 “>” 標記,使其無法被執(zhí)行。
          2. 限制所允許的 HTML 標記:可以在代碼中進行限制,只允許某些特定的 HTML 標記,從而防止注入惡意代碼。
          3. 對表單中的數(shù)據(jù)進行處理:在輸入表單中,需要對數(shù)據(jù)進行適當?shù)奶幚怼@纾瑢τ谖谋究蛑械奈谋荆枰コ孜部崭瘛TML 標記和特殊字符等。
          4. 防范 XSS 攻擊:使用 HTTP Only Cookie 設(shè)置,避免將 Cookie 數(shù)據(jù)暴露給腳本。此外,建議使用 CSP(Content-Security-Policy)等其他工具來防范 XSS 攻擊。

          綜上所述,為了防止 HTML 注入攻擊,需要重視輸入數(shù)據(jù)校驗和過濾、限制 HTML 標記、對表單數(shù)據(jù)進行處理和防范 XSS 攻擊等方面,從多個角度對 HTML 注入攻擊進行預防和防御。

          3.4 安全框架

          3.4.1 功能和優(yōu)點

          安全框架(Security Framework)是用來保證應用程序安全性的軟件框架,也稱之為安全開發(fā)框架(Secure Development Framework)。

          主要包含以下幾個方面的功能:

          1. 認證與授權(quán):安全框架提供了認證和授權(quán)的機制,可以實現(xiàn)用戶身份驗證、訪問控制和權(quán)限管理等功能,從而確保應用程序中的不同用戶只能訪問其授權(quán)的資源和操作。
          2. 輸入驗證與過濾:安全框架提供輸入驗證和過濾的功能,能夠防止 SQL 注入、XSS 跨站腳本注入、CSRF 跨站請求偽造等攻擊方式,從而保證應用程序輸入數(shù)據(jù)的安全性。
          3. 加密與解密:安全框架提供了數(shù)據(jù)加密和解密的功能,可以加密數(shù)據(jù)庫中的敏感數(shù)據(jù)、代碼和配置等信息,保護應用程序的機密信息被不法分子盜取。
          4. 日志記錄與審計:安全框架提供了日志記錄和審計的功能,可以記錄用戶的操作行為、訪問過程、錯誤信息等,從而便于開發(fā)人員進行漏洞排查和故障修復。

          安全框架的優(yōu)點有以下幾點:

          1. 減少安全問題:安全框架提供了一套安全標準和最佳實踐,可以有效的預防安全問題,減少潛在的安全漏洞和攻擊。
          2. 提高效率:使用安全框架可以讓開發(fā)人員專注于業(yè)務邏輯和實現(xiàn),同時也減輕了安全問題的開發(fā)負擔和時間成本,提高了開發(fā)效率。
          3. 方便集成:安全框架是基于編程框架或者編程語言的,可以方便地集成到已有的項目和代碼,避免了重復的工作,降低了集成難度。
          4. 提升用戶信任度:安全框架可以提高應用程序和系統(tǒng)的安全性,減少被攻擊或遭到數(shù)據(jù)泄露的幾率,從而提升用戶的信任度,保護企業(yè)信息資產(chǎn)價值。

          總之,安全框架是一種提高應用程序安全性的有效手段,能夠保護用戶的隱私數(shù)據(jù)、避免安全漏洞和攻擊等,從而避免因安全問題引起的業(yè)務風險和數(shù)據(jù)泄露等事件。

          3.4.2 常見的安全框架

          常見的安全框架有:

          1. Spring SecuritySpring SecuritySpring框架中常用的安全框架,它提供了認證(Authentication)和授權(quán)(Authorization)的標準化實現(xiàn),并且可以與其他Spring組件進行整合。
          2. Apache ShiroApache Shiro是一個靈活性極高的安全框架,其核心功能包括認證、授權(quán)、加密、會話管理和訪問控制等。
          3. Laravel SecurityLaravel SecurityLaravel框架中常用的安全框架,它提供了CSRF保護、XSS保護、加密和解密等功能,同時也可以與模板引擎、緩存、和最新版本Laravel框架進行整合。
          4. .NET Framework:.NET Framework提供了很多安全編程框架,包括 ASP.NET Core Identity、ASP.NET Web Forms、ASP.NET MVC 和ASP.NET Web API等,這些框架用于Web應用程序和服務器端的應用程序的安全防護。
          5. OWASPOWASP是一個開放的Web應用安全項目,它提供了一套開源的安全框架和工具,幫助開發(fā)人員發(fā)現(xiàn)和解決Web應用程序中的安全漏洞。

          以上是一些常見的安全框架,各有特點和應用場景,可以根據(jù)不同項目的需求和特點選擇合適的安全框架。同時,為了防止安全漏洞和攻擊,開發(fā)人員應該始終保持警惕,采取最佳實踐和標準來處理敏感數(shù)據(jù)和用戶隱私信息。

          4. 網(wǎng)絡(luò)通信層次

          4.1 HTTPS傳輸協(xié)議

          4.1.1 安全傳輸協(xié)議的意義

          HTTPS是通過加密通道實現(xiàn)HTTP協(xié)議通信的協(xié)議,通過使用加密技術(shù)確保數(shù)據(jù)在客戶端和服務器之間傳輸時不被竊取、篡改或偽造。HTTPS的意義有以下幾點:

          1. 提供了數(shù)據(jù)傳輸?shù)臋C密性:通過使用SSLTLS等安全技術(shù),通信雙方通過加密傳輸數(shù)據(jù),傳輸過程中數(shù)據(jù)被加密,避免了數(shù)據(jù)被竊取、篡改甚至偽造的風險。
          2. 增加了數(shù)據(jù)傳輸?shù)耐暾?/span>:HTTPS中使用的數(shù)字簽名技術(shù),保證數(shù)據(jù)傳輸過程中不被篡改,確保數(shù)據(jù)的完整性。如果有人試圖在傳輸過程中篡改數(shù)據(jù),SSL會檢測到,從而可以避免數(shù)據(jù)泄漏、被篡改的風險。
          3. 身份認證:本來HTTP協(xié)議沒有身份認證的機制,會存在冒充他人進行通信的問題。而HTTPS使用證書機制對客戶端和服務器進行了身份認證,確保了通信雙方的真實性和安全。
          4. 增強了用戶體驗和信任:HTTPS提供了數(shù)據(jù)加密、身份認證、數(shù)據(jù)完整性和數(shù)據(jù)保密性等多種安全機制,增加了用戶對網(wǎng)站的信任感,提高了用戶體驗。

          綜上所述,使用HTTPS安全傳輸協(xié)議可以保護用戶的隱私、防止網(wǎng)絡(luò)攻擊和黑客攻擊,同時增強了用戶對網(wǎng)站的信任感,提高了網(wǎng)站的安全性和品牌聲譽。目前,許多網(wǎng)站和應用程序因為安全問題加密了它們的通信協(xié)議,所以使用HTTPS協(xié)議已經(jīng)成為了 Web 安全的最佳實踐。

          4.1.2 HTTPS工作原理

          HTTPS(Hypertext Transfer Protocol Secure)是通過加密通道實現(xiàn)HTTP協(xié)議通信的協(xié)議,工作原理如下:

          1. 客戶端發(fā)出HTTPS請求:當用戶訪問需要使用HTTPS的網(wǎng)站時,客戶端會與Web服務器建立TCP連接,使用443端口發(fā)出HTTPS請求。
          2. 服務端發(fā)送SSL證書:Web服務器需要向客戶端發(fā)送證書,證書中包含了服務器公鑰、證書頒發(fā)機構(gòu)(CA)的信息以及證書的有效期等信息。
          3. 客戶端驗證SSL證書:客戶端從Web服務器接收到證書后,會驗證證書是否合法和有效,如果驗證不通過,則會彈出警告提示是否繼續(xù)訪問。
          4. 客戶端生成隨機數(shù)并加密:如果證書驗證通過,客戶端隨機生成一個用于加密數(shù)據(jù)的對稱密鑰,并將其用服務器公鑰加密,發(fā)送給服務器。這個過程稱為客戶端與服務端協(xié)商密鑰。
          5. 服務端使用密鑰對數(shù)據(jù)進行加密: Web服務器使用私鑰解密,得到了客戶端發(fā)來的對稱密鑰,然后使用該對稱密鑰對加密數(shù)據(jù)進行加密處理,并將加密后的數(shù)據(jù)發(fā)送給客戶端。
          6. 客戶端使用密鑰對數(shù)據(jù)進行解密:客戶端使用剛才生成的對稱密鑰解密服務器發(fā)來的加密數(shù)據(jù),得到了HTTP請求中的內(nèi)容。
          7. 客戶端和服務端進行加密通信:自此以后,客戶端和服務端就可以使用對稱密鑰進行加密通信,從而保證數(shù)據(jù)傳輸?shù)陌踩院蜋C密性。

          綜上所述,HTTPS的加密技術(shù)主要是基于公鑰和對稱密鑰機制實現(xiàn)。首先在握手階段通過公鑰加密方法協(xié)商生成會話密鑰,然后使用會話密鑰來對數(shù)據(jù)進行加密和解密,保證了網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)安全性。

          4.1.3 HTTP劫持攻擊和HTTPS劫持攻擊

          HTTP劫持攻擊(HTTP Hijacking)是指黑客截獲了用戶的HTTP請求,并在用戶不知情的情況下修改了HTTP請求或返回的結(jié)果。攻擊者可以讀取和修改HTTP報文中的內(nèi)容,篡改HTTP請求的參數(shù),獲取用戶敏感信息等。HTTP協(xié)議采用明文傳輸方式,容易被黑客進行竊聽和篡改,因此容易受到HTTP劫持攻擊。

          HTTPS劫持攻擊(HTTPS Hijacking)是指黑客通過欺騙或者偽造證書等方式,將HTTPS報文的加密通信解密,篡改或修改用戶的HTTPS請求或響應信息的一種攻擊方式。HTTPS采用的是加密傳輸方式,提高了數(shù)據(jù)的安全性,但只要攻擊者掌握合法的證書,即可欺騙受害者,使其誤認為通信雙方是正確的,而進行對話,同時,黑客則可以在通信過程中篡改或竊取受害者的信息。

          在HTTP劫持攻擊中,攻擊者可以直接讀取和修改HTTP報文中的內(nèi)容,而在HTTPS劫持攻擊中,攻擊者需要解密HTTPS加密通信才能對通信進行攻擊,難度更大,但一旦攻擊成功,造成的影響也會更加具有破壞性。

          為避免HTTP劫持攻擊和HTTPS劫持攻擊,我們應該使用安全的通信協(xié)議,如HTTPS協(xié)議,以確保通信過程的安全和機密性。此外,了解安全威脅和冷靜應對攻擊也是非常重要的。

          4.1.4 預防和防御

          為了預防和防御HTTP劫持攻擊或HTTPS劫持攻擊,我們可以采取以下措施:

          1. 使用加密的通信協(xié)議:如使用HTTPS協(xié)議來加密通信,避免數(shù)據(jù)泄露和篡改。此外,也可以采用VPN等安全通信協(xié)議,防止黑客對數(shù)據(jù)進行竊聽和篡改。
          2. 使用強密碼并定期更新:使用強密碼來加強賬戶安全性,同時也要定期更新密碼以防止黑客將賬戶密碼竊取,從而攻擊賬戶或篡改賬戶信息。
          3. 安全的網(wǎng)站訪問:必要時使用訪問控制或軟件層面的防護機制對網(wǎng)站或服務器進行保護,如限制IP訪問、設(shè)置防火墻、禁用ROOT賬號等。
          4. 防止網(wǎng)絡(luò)釣魚攻擊:黑客通過偽裝成合法機構(gòu)或個人掩蓋其身份,以獲取或競爭用戶的敏感信息。如果您收到了這樣的郵件或鏈接,請務必不要輕易點擊和填寫信息,對發(fā)件人或鏈接進行驗證。
          5. 教育和培訓員工:教育和培訓員工安全意識和隱私保護方面的知識,提高認識,防范機構(gòu)內(nèi)部的黑客攻擊。
          6. 使用安全DNS服務:有助于監(jiān)視網(wǎng)絡(luò)流量和預防網(wǎng)絡(luò)釣魚攻擊。這些服務會監(jiān)視黑名單和惡意軟件,并提供自動防御措施以保持網(wǎng)絡(luò)的穩(wěn)定性和安全性。

          綜上所述,能夠預防和防御HTTP劫持攻擊和HTTPS劫持攻擊需要采取多重措施,包括使用加密通信協(xié)議、加強安全意識培訓、設(shè)置訪問控制、使用安全DNS服務等。但是有一點我們需要明白,完全的安全是不存在的,只能不斷提升安全性,減少被攻擊概率。

          4.2 同源策略

          4.2.1 定義和作用

          同源策略(Same-Origin Policy)是一種安全機制,主要用于控制Web瀏覽器如何訪問來自不同源(即不同協(xié)議、主機名或端口)的網(wǎng)站資源。同源策略的作用是限制某個文檔或者腳本,僅在與其來源相同的環(huán)境中執(zhí)行,從而防止惡意代碼通過跨站點腳本攻擊(XSS攻擊)等方式竊取用戶的敏感數(shù)據(jù)或者執(zhí)行惡意操作。

          同源策略要求在同一個域名、端口和協(xié)議下的網(wǎng)頁腳本才能相互訪問,而不同源的網(wǎng)頁腳本之間是相互隔離的。同源策略可以防止惡意網(wǎng)站將各種資源注入到其它網(wǎng)站并獲取數(shù)據(jù),從而保護用戶的安全和隱私。

          比如,對于JavaScript腳本而言,如果一個頁面中加載了另一個來自不同源的網(wǎng)站的腳本,即使這個腳本是來自于一個已經(jīng)標記為危險的站點,也不能直接訪問頁面的DOM(文檔對象模型),從而避免了XSS攻擊。

          同源策略雖然提高了Web應用程序的安全性,但也帶來了一些限制,為了實現(xiàn)跨域的交互,需要使用一些跨域技術(shù),如JSONP、CORS等實現(xiàn)跨域消息傳遞。

          總之,同源策略可以防止Web應用程序中的安全漏洞,避免惡意網(wǎng)站竊取用戶的敏感信息并限制對互聯(lián)網(wǎng)信息資源的訪問。

          4.2.2 繞過同源策略的攻擊技術(shù)

          繞過同源策略的攻擊技術(shù)主要有以下幾種:

          1. 使用 JSONP:JSONP 是 JSON with padding 的縮寫,可以通過 script 標簽的跨域特性來獲取外部數(shù)據(jù)。攻擊者可以通過惡意站點將自己的 JavaScript 代碼注入到目標站點中,通過使用 JSONP 技術(shù)來竊取數(shù)據(jù)。
          2. 利用跨域資源共享(CORS):攻擊者可以通過在目標網(wǎng)站中添加惡意 JavaScript 或 HTML 代碼來實現(xiàn)跨域攻擊。CORS 規(guī)定了網(wǎng)站將哪些資源暴露給外部站點。惡意站點可以利用該機制竊取用戶數(shù)據(jù)。
          3. 使用 DNS 重綁定:攻擊者可以通過 DNS 重綁定技術(shù)將惡意網(wǎng)站偽裝成受信任的網(wǎng)站。當用戶訪問受信任網(wǎng)站時,實際上會訪問到惡意網(wǎng)站,攻擊者可以通過這種方式來竊取用戶信息。
          4. 利用 iframe:攻擊者可以通過 iframe 標簽將其網(wǎng)站嵌入到目標網(wǎng)站,從而竊取目標網(wǎng)站中的數(shù)據(jù)。攻擊者可以在 iframe 中注入惡意代碼,從而實現(xiàn)對用戶數(shù)據(jù)的竊取。

          請注意這些都是用于學術(shù)和研究目的,嚴禁用于不道德和違法用途。

          5. 總結(jié)

          5.1 前端安全攻防總結(jié)

          前端安全攻防可以從以下幾個方面進行總結(jié):

          1. XSS 攻擊

          跨站腳本攻擊(XSS)是指攻擊者通過注入惡意腳本,在受害者的瀏覽器中運行,以獲取受害者敏感信息或?qū)崿F(xiàn)其他攻擊行為。前端防御 XSS 攻擊可采取如下措施:

          • 輸入過濾和校驗:過濾掉用戶輸入的惡意腳本、特殊字符等。
          • 對敏感輸出進行轉(zhuǎn)義:將輸出的特殊字符替換為 HTML 實體,對于不應該被解析成 HTML 的內(nèi)容,使用textContent 或者innerText 輸出。
          • 設(shè)置 CSP:Content Security Policy(內(nèi)容安全策略)是定義瀏覽器如何執(zhí)行內(nèi)容的策略,可以指定允許執(zhí)行的腳本來源,有效地防止 XSS 攻擊。

          2. CSRF 攻擊

          跨站請求偽造(CSRF)是指攻擊者發(fā)起偽造請求,利用受害者的權(quán)限完成某些操作,例如轉(zhuǎn)賬、修改密碼等。前端防御 CSRF 攻擊可采取如下措施:

          • 利用 SameSite cookie 屬性:SameSite 限制了服務器只能在與當前網(wǎng)站同域的情況下才能向該網(wǎng)站設(shè)置 Cookie,從而使攻擊者無法偽造包含當前網(wǎng)站 Cookie 的請求。
          • 在請求中添加 CSRF Token:服務器在向客戶端發(fā)送 HTML、JS 或圖片等資源的同時也會隨機生成一個與之對應的 Token,每次發(fā)起請求的時候,需要將 Token 附加在請求體中,從而有效地防御 CSRF 攻擊。

          3. 點擊劫持攻擊

          點擊劫持(Clickjacking)是利用透明 iframe 將可點擊的目標偽裝成看似無關(guān)的按鈕或鏈接,使受害者在不知情的情況下執(zhí)行了一些惡意操作。前端防御點擊劫持攻擊可采取如下措施:

          • 設(shè)置 X-Frame-Options 響應頭:X-Frame-Options 是一個 HTTP 響應頭,只有在瀏覽器判斷請求來自同源站點時,才允許頁面在 iframe 中加載。
          • 使用 JavaScript 防范:通過檢查當前頁面中的 frame 或 top 屬性,以及 location.href 是否等于 top.location.href,判斷當前頁面是否被嵌套在 iframe 中。

          最后,需要強調(diào)的是,前端安全防御不能僅僅局限于前端,還需要結(jié)合后端、數(shù)據(jù)庫等其他方面進行綜合防御,從而確保整個 web 應用系統(tǒng)的安全。

          5.2 在實際項目中如何預防和處理安全問題

          在實際項目中,為了預防和處理安全問題,可以采取以下措施:

          1. 加強用戶輸入校驗:輸入數(shù)據(jù)時進行及時和有效的校驗,過濾非法內(nèi)容,包括特殊字符、SQL 注入語句、JavaScript 腳本等。
          2. 合理使用 HTTPS: 對重要數(shù)據(jù)采取 HTTPS 加密傳輸,確保數(shù)據(jù)傳輸安全。
          3. 前后端分離:將前端與后端分離,將后端對用戶輸入進行校驗并進行最終的處理,從而防止代碼注入和其他攻擊。
          4. 服務器層面的安全:加強服務器的安全,包括加強服務器的訪問授權(quán)、配置防火墻等技術(shù)手段。
          5. 不要使用過時的庫和框架:過時的庫和框架容易存在相應的漏洞,需要時刻更新核心庫和框架。
          6. 應用程序日志記錄:記錄應用程序日志,及時發(fā)現(xiàn)異常行為,集中監(jiān)測。
          7. 定期進行安全漏洞掃描:定期使用安全工具對應用程序進行及時安全漏洞掃描,并進行及時修補。
          8. 建立安全審計制度:建立安全審計制度,檢查和發(fā)現(xiàn)安全漏洞,及時處理問題。

          總之,針對安全問題,項目需要采取多種措施綜合防范和處理,確保系統(tǒng)的安全性。同時,需要時刻關(guān)注最新的安全問題和漏洞,并采取相應的措施予以解決。

          做項目的過程中,使用正則表達式來匹配一段文本中的特定種類字符,是比較常用的一種方式,下面是對常用的正則匹配做了一個歸納整理。

          1、匹配中文:[\u4e00-\u9fa5]

          2、英文字母:[a-zA-Z]

          3、數(shù)字:[0-9]

          4、匹配中文,英文字母和數(shù)字及下劃線:^[\u4e00-\u9fa5_a-zA-Z0-9]+$

          同時判斷輸入長度:

          [\u4e00-\u9fa5_a-zA-Z0-9_]{4,10}

          5、

          (?!_) 不能以_開頭

          (?!.*?_$) 不能以_結(jié)尾

          [a-zA-Z0-9_\u4e00-\u9fa5]+ 至少一個漢字、數(shù)字、字母、下劃線

          $ 與字符串結(jié)束的地方匹配

          6、只含有漢字、數(shù)字、字母、下劃線,下劃線位置不限:

          ^[a-zA-Z0-9_\u4e00-\u9fa5]+$

          7、由數(shù)字、26個英文字母或者下劃線組成的字符串

          ^\w+$

          8、2~4個漢字

          "^[\u4E00-\u9FA5]{2,4}$";

          9、最長不得超過7個漢字,或14個字節(jié)(數(shù)字,字母和下劃線)正則表達式

          ^[\u4e00-\u9fa5]{1,7}$|^[\dA-Za-z_]{1,14}$

          10、匹配雙字節(jié)字符(包括漢字在內(nèi)):[^x00-xff]

          評注:可以用來計算字符串的長度(一個雙字節(jié)字符長度計2,ASCII字符計1)

          11、匹配空白行的正則表達式:ns*r

          評注:可以用來刪除空白行

          12、匹配HTML標記的正則表達式:<(S*?)[^>]*>.*?|<.*? />

          評注:網(wǎng)上流傳的版本太糟糕,上面這個也僅僅能匹配部分,對于復雜的嵌套標記依舊無能為力

          13、匹配首尾空白字符的正則表達式:^s*|s*$

          評注:可以用來刪除行首行尾的空白字符(包括空格、制表符、換頁符等等),非常有用的表達式

          14、匹配Email地址的正則表達式:^[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]@[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$

          評注:表單驗證時很實用

          15、手機號:^((13[0-9])|(14[0-9])|(15[0-9])|(17[0-9])|(18[0-9]))\d{8}$

          16、身份證:(^\d{15}$)|(^\d{17}([0-9]|X|x)$)

          17、匹配網(wǎng)址URL的正則表達式:[a-zA-z]+://[^s]*

          評注:網(wǎng)上流傳的版本功能很有限,上面這個基本可以滿足需求

          18、匹配帳號是否合法(字母開頭,允許5-16字節(jié),允許字母數(shù)字下劃線):^[a-zA-Z][a-zA-Z0-9_]{4,15}$

          評注:表單驗證時很實用

          19、匹配國內(nèi)電話號碼:d{3}-d{8}|d{4}-d{7}

          評注:匹配形式如 0511-4405222 或 021-87888822

          20、匹配騰訊QQ號:[1-9][0-9]{4,}

          評注:騰訊QQ號從10000開始

          21、匹配中國郵政編碼:[1-9]d{5}(?!d)

          評注:中國郵政編碼為6位數(shù)字

          22、匹配身份證:d{15}|d{18}

          評注:中國的身份證為15位或18位

          23、匹配ip地址:d+.d+.d+.d+

          評注:提取ip地址時有用

          24、匹配特定數(shù)字:

          ^[1-9]d*$ //匹配正整數(shù)

          ^-[1-9]d*$ //匹配負整數(shù)

          ^-?[1-9]d*$ //匹配整數(shù)

          ^[1-9]d*|0$ //匹配非負整數(shù)(正整數(shù) + 0)

          ^-[1-9]d*|0$ //匹配非正整數(shù)(負整數(shù) + 0)

          ^[1-9]d*.d*|0.d*[1-9]d*$ //匹配正浮點數(shù)

          ^-([1-9]d*.d*|0.d*[1-9]d*)$ //匹配負浮點數(shù)

          ^-?([1-9]d*.d*|0.d*[1-9]d*|0?.0+|0)$ //匹配浮點數(shù)

          ^[1-9]d*.d*|0.d*[1-9]d*|0?.0+|0$ //匹配非負浮點數(shù)(正浮點數(shù) + 0)

          ^(-([1-9]d*.d*|0.d*[1-9]d*))|0?.0+|0$ //匹配非正浮點數(shù)(負浮點數(shù) + 0)

          評注:處理大量數(shù)據(jù)時有用,具體應用時注意修正

          25、匹配特定字符串:

          ^[A-Za-z]+$ //匹配由26個英文字母組成的字符串

          ^[A-Z]+$ //匹配由26個英文字母的大寫組成的字符串

          ^[a-z]+$ //匹配由26個英文字母的小寫組成的字符串

          ^[A-Za-z0-9]+$ //匹配由數(shù)字和26個英文字母組成的字符串

          ^w+$ //匹配由數(shù)字、26個英文字母或者下劃線組成的字符串

          26、

          在使用RegularExpressionValidator驗證控件時的驗證功能及其驗證表達式介紹如下:

          只能輸入數(shù)字:“^[0-9]*$”

          只能輸入n位的數(shù)字:“^d{n}$”

          只能輸入至少n位數(shù)字:“^d{n,}$”

          只能輸入m-n位的數(shù)字:“^d{m,n}$”

          只能輸入零和非零開頭的數(shù)字:“^(0|[1-9][0-9]*)$”

          只能輸入有兩位小數(shù)的正實數(shù):“^[0-9]+(.[0-9]{2})?$”

          只能輸入有1-3位小數(shù)的正實數(shù):“^[0-9]+(.[0-9]{1,3})?$”

          只能輸入非零的正整數(shù):“^+?[1-9][0-9]*$”

          只能輸入非零的負整數(shù):“^-[1-9][0-9]*$”

          只能輸入長度為3的字符:“^.{3}$”

          只能輸入由26個英文字母組成的字符串:“^[A-Za-z]+$”

          只能輸入由26個大寫英文字母組成的字符串:“^[A-Z]+$”

          只能輸入由26個小寫英文字母組成的字符串:“^[a-z]+$”

          只能輸入由數(shù)字和26個英文字母組成的字符串:“^[A-Za-z0-9]+$”

          只能輸入由數(shù)字、26個英文字母或者下劃線組成的字符串:“^w+$”

          驗證用戶密碼:“^[a-zA-Z]w{5,17}$”正確格式為:以字母開頭,長度在6-18之間,

          只能包含字符、數(shù)字和下劃線。

          驗證是否含有^%&',;=?$"等字符:“[^%&',;=?$x22]+”

          只能輸入漢字:“^[u4e00-u9fa5],{0,}$”

          驗證Email地址:“^w+[-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*$”

          驗證InternetURL:“^http://([w-]+.)+[w-]+(/[w-./?%&=]*)?$”

          驗證身份證號(15位或18位數(shù)字):“^d{15}|d{}18$”

          驗證一年的12個月:“^(0?[1-9]|1[0-2])$”正確格式為:“01”-“09”和“1”“12”

          驗證一個月的31天:“^((0?[1-9])|((1|2)[0-9])|30|31)$”

          正確格式為:“01”“09”和“1”“31”。

          匹配中文字符的正則表達式: [u4e00-u9fa5]

          匹配雙字節(jié)字符(包括漢字在內(nèi)):[^x00-xff]

          匹配空行的正則表達式:n[s| ]*r

          匹配HTML標記的正則表達式:/<(.*)>.*|<(.*) />/

          匹配首尾空格的正則表達式:(^s*)|(s*$)

          匹配Email地址的正則表達式:w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*

          匹配網(wǎng)址URL的正則表達式:http://([w-]+.)+[w-]+(/[w- ./?%&=]*)?


          主站蜘蛛池模板: 国产色欲AV一区二区三区| 国产情侣一区二区| 国产成人一区二区三中文| 无码国产伦一区二区三区视频| 丝袜人妻一区二区三区网站| 国产一区在线视频观看| 精品一区二区无码AV| 成人无码AV一区二区| 日韩精品乱码AV一区二区| 影音先锋中文无码一区| 精品中文字幕一区二区三区四区| 亲子乱av一区二区三区| 一区二区免费视频| 日韩AV片无码一区二区不卡| 成人区精品一区二区不卡 | 亚洲A∨精品一区二区三区下载| 国产拳头交一区二区| 国产激情无码一区二区| 国内精品一区二区三区最新| 成人精品视频一区二区三区| 国产香蕉一区二区精品视频| 精品3d动漫视频一区在线观看| 免费日本一区二区| 国产在线观看一区二区三区四区| 国产综合一区二区| 国产精品一区电影| 精品一区二区三区自拍图片区| 能在线观看的一区二区三区| 亚洲一区在线视频| 精品人体无码一区二区三区| 一本一道波多野结衣AV一区| 国产亚洲一区二区三区在线观看| 国产福利酱国产一区二区| 久久国产免费一区二区三区| 一区精品麻豆入口| 精品日韩一区二区| 国产美女在线一区二区三区| 国产精品毛片一区二区| 国产成人精品亚洲一区| 成人区精品一区二区不卡亚洲| 美女视频在线一区二区三区|