[譯]HTML&CSS Lesson5: 定位

CSS最大的用處之一就是能夠將內容和元素定位到任何咱們想要的位置,使咱們的設計具備結構,使內容更加易懂。css

CSS有好幾種不一樣的定位屬性,每種都有本身的使用場景。在這節課中咱們會經過不一樣的案例——可複用的佈局和針對單元素的佈局——來介紹每種方法。html

浮動

定位的其中一種方法就是使用float屬性。float屬性很是好用,能夠用在不少地方。前端

本質來講,float屬性是使元素脫離正常的流式佈局,並將它放置在父元素的左側或右側。而後頁面中全部的元素都會環繞浮動元素佈局。例如咱們將段落間的一張圖片設置爲浮動,那麼這些段落都會圍繞圖片換行。segmentfault

當咱們將多個元素同時設置爲浮動元素,那麼這些元素將呈現相鄰或相對佈局,如多列布局。瀏覽器

float有好幾個值,最經常使用的值是leftright。使元素浮動到父級元素的左側或右側。bash

img {
  float: left;
}複製代碼

浮動練習

咱們先建立一個通用頁面,含有頁頭,頁腳,中間有兩列。最理想的狀況就是在<body>元素內建立第二節課"瞭解HTML"中提到的<header><section><aside><footer>元素。異步

<header>...</header>
<section>...</section>
<aside>...</aside>
<footer>...</footer>複製代碼

img
img

<section><aside>元素都是塊狀元素,它們默認上下佈局。但咱們實際上想要它們並排顯示。因此在此,咱們就能夠將<section>元素設爲左浮動,將<aside>元素設爲右浮動,使它們呈現彼此相對的兩列。
CSS代碼以下:ide

section {
  float: left;
}
aside {
  float: right;
}複製代碼

在此提一下,元素設爲浮動後,會浮動到父級元素的邊緣。若是沒有父級元素,那麼它會浮動到頁面的邊緣。佈局

當咱們設置一個元素爲浮動,咱們就將它從HTML文檔的正常流式佈局中取出,這就致使元素的默認寬度取決於其內容的寬度。有時咱們用可複用的佈局建立多列的時候並不但願如此,那就能夠爲列設置一個固定寬度。另外,爲了防止浮動元素緊靠在一塊兒,使內容彼此緊貼,可使用margin屬性來建立元素間的空隙。
以下所示:學習

section {
  float: left;
  margin: 0 1.5%;
  width: 63%;
}
aside {
  float: right;
  margin: 0 1.5%;
  width: 30%;
}複製代碼

img
img


浮動會改變元素display的狀態
有一個重要的點須要記住:將元素設爲浮動就是將它從正常的流式佈局中脫離,而這會改變元素默認的display值。float屬性依賴於display屬性爲block的元素。若是一個元素的默認display值不是block,那麼它會將默認值改爲block

例如,span是一個內聯元素,它默認的display值爲inline,widthheight值是不生效的。然而,若是咱們將這個內聯元素設置爲浮動,那麼它的默認display值會變成block,這時候widthheight值就生效了。

當咱們設置元素爲浮動時,都須要注意display值的變化。


若只有兩列,咱們能夠將其中一個元素設置爲左浮動,另外一個元素設置爲右浮動,但如果多列的時候就須要換一種方法。例如,咱們但願在<header><footer>元素之間添加一行三列的結構,能夠先刪掉以前寫的<aside>元素並使用三個<section>元素,以下所示:

<header>...</header>
<section>...</section>
<section>...</section>
<section>...</section>
<footer>...</footer>複製代碼

要將三個<section>元素並排顯示,咱們再也不用以前的左浮動加右浮動的模式,而是將三個元素都設置爲左浮動。同時也要爲元素設置寬度使其排列更合理。

section {
  float: left;
  margin: 0 1.5%;
  width: 30%;
}複製代碼

如今呈如今咱們眼前的就是三列寬度和外邊距一致,都向左浮動的元素。

img
img

清除浮動

float元素最初的設置是爲了在內容中插入圖片,使內容天然地環繞圖片顯示。雖然它在圖片中使用很是完美,可是float屬性並非爲了定位和佈局設計的,因此在這方面存在一些缺陷。

其中一個缺陷就是浮動元素的下一個兄弟元素和父元素的樣式可能會渲染異常。當元素浮動時它脫離了正常佈局,致使圍繞在浮動元素周圍的元素的樣式都受到了影響。

最多見的就是marginpadding屬性值渲染異常,由於它們shi與浮動元素融爲一體。固然,也有一些其它的樣式也受到了影響。

另外一個缺陷是有時咱們不想內容圍繞環繞浮動元素顯示。浮動元素會從文件流中脫離,其餘元素會徹底佔有它周圍的空間,但不少時候咱們並不但願這樣。

在上述兩個元素並排顯示的例子中, 咱們將<section>元素和<aside>元素設爲浮動。在設置元素的width屬性以前,咱們能夠看到<footer>元素環繞兩個浮動元素顯示,佔用全部可用空間。如此,<footer>元素就顯示在兩個浮動元素之間的凹槽中。以下所示:

img
img

爲了不這種狀況,咱們就須要將浮動元素包裹起來或者清除浮動,使它們回到正常文件流中。接下來,咱們先着眼於如何清除浮動,再來介紹怎麼包裹浮動元素。

清除浮動

清除浮動須要用到clear屬性,它最經常使用的屬性值是:leftrightboth

div {
  clear: left;
}複製代碼

屬性值left清除左浮動,right清除右浮動。both清除同時左浮動和右浮動,這也是咱們最推薦使用的屬性值。

回到上例中,咱們爲<footer>元素添加clear:both屬性就能夠清除浮動了。清除浮動可使頁面迴歸正常文件流,因此很是重要。

footer {
  clear: both;
}複製代碼

img
img

包裹浮動元素

除了清除浮動,還能夠包裹浮動元素。這兩種方式頁面呈現的效果是差很少的,但包裹元素的方式還有助於確保樣式都渲染正常。

包裹元素就是將浮動元素置於父元素中,父元素做爲容器會置於正常的文件流中。咱們爲父元素添加一個class屬性group,併爲其設置CSS:

.group:before,
.group:after {
  content: "";
  display: table;
}
.group:after {
  clear: both;
}
.group {
  clear: both;
  zoom: 1;
}複製代碼

上述寫了不少代碼,但實際上就是爲class值爲group元素中的浮動元素清除浮動,使其迴歸正常文件流。

再具體點,代碼中使用了在第四節中有提到過的:before:after兩個僞類,它們在class爲group的元素先後分別添加了一個動態元素。這些元素不包含任何內容,並以與塊狀元素block很類似的表格元素table的形式呈現。動態生成的元素:after清除了class爲group的元素內的元素浮動。在.group中設置的清除浮動則清除了排版在它之上的兄弟元素的浮動。老版本的瀏覽器也能夠很好的兼容。

clear:both單獨聲明會很合適。

回到示例,咱們能夠將<section><aside>元素放置在一個父元素內,以下所示:

HTML

<header>...</header>
<div class="group">
  <section>...</section>
  <aside>...</aside>
</div>
<footer>...</footer>複製代碼

CSS

.group:before,
.group:after {
  content: "";
  display: table;
}
.group:after {
  clear: both;
}
.group {
  clear: both;
  zoom: 1;
}
section {
  float: left;
  margin: 0 1.5%;
  width: 63%;
}
aside {
  float: right;
  margin: 0 1.5%;
  width: 30%;
}複製代碼

img
img

這種包裹元素清除浮動的方式被稱爲clearfix,咱們能夠很容易在其它網站中找到定義它的class名clearfixcf。咱們示例中使用了group,它表明一組元素,更好地表達了內容的意義。

設置浮動元素時咱們要時刻注意它是否影響了頁面的佈局,並確認是否已根據須要清除浮動。不清除浮動會致使不少頭疼的問題,尤爲當頁面多行多列排版的時候。

練習

接下來,咱們打開「樣式討論會」網站來嘗試將一部份內容浮動。

  • 在設置元素浮動以前,咱們先在main.css中的grid樣式下添加清除浮動的樣式group,以下所示:
/* ======================================== Clearfix ======================================== */
.group:before,
.group:after {
  content: "";
  display: table;
}
.group:after {
  clear: both;
}
.group {
  clear: both;
  zoom: 1;
}複製代碼
  • 如今咱們要將<header>元素內的<h1>設置爲左浮動,其餘元素環繞這個元素顯示。
    先爲<h1>添加一個class屬性,值爲logo,並在CSS中將其設置爲左浮動:

HTML

<h1 class="logo">
  <a href="index.html">Styles Conference</a>
</h1>複製代碼

CSS

/* ======================================== Primary header ======================================== */

.logo {
  float: left;
}複製代碼
  • 這步完成以後,咱們爲logo添加更多細節。先在單詞"Style"和"Conference"之間添加一個<br/>元素,使兩個單詞分兩行顯示。
    在CSS中咱們爲logo添加上邊框和縱向的padding

HTML

<h1 class="logo">
  <a href="index.html">Styles <br> Conference</a>
</h1>複製代碼

CSS

.logo {
  border-top: 4px solid #648880;
  padding: 40px 0 22px 0;
  float: left;
}複製代碼
  • 因爲咱們將<h1>設置爲浮動,那麼就須要在最靠近它的父級元素<header>上添加class屬性值group來清除浮動:
<header class="container group">
  ...
</header>複製代碼
  • <header>元素上的操做已經完成,接着咱們來處理<footer>元素。與<header>元素設置類似,咱們將包含版權信息的<small>設置爲左浮動,其餘元素圍繞這個元素顯示。
    不過與<header>不一樣的是,咱們不直接在浮動元素上添加class屬性設置浮動。咱們先爲其父元素添加一個class屬性值,而且使用這惟一的選擇器選中元素設置浮動。首先在<footer>上添加class屬性值primary-footer。因爲咱們已事先知道了要將<footer>元素中的某個元素設爲浮動,因此在<footer>中添加class屬性值group
<footer class="primary-footer container group">
  ...
</footer>複製代碼
  • 如今咱們已在<footer>上添加了class屬性值primary-footer。咱們能夠以其爲預選擇器選中<small>元素並添加左浮動。以下所示:
/* ======================================== Primary footer ======================================== */

.primary-footer small {
  float: left;
}複製代碼
  • 上述代碼中咱們選中的是class屬性值爲primary-footer的元素內的<small>元素,例子中對應的就是<footer>元素。
  • 最後一步,咱們爲<footer>元素設置縱向padding,使<footer>的內容與其它內容分離。咱們能夠直接在primary-footer上添加樣式:
.primary-footer {
  padding-bottom: 44px;
  padding-top: 44px;
}複製代碼
  • 完成了<header><footer>的設置以後,咱們要將這些修改應用到每一個頁面中。

img
img

Inline-Block

除了浮動,咱們也能夠經過display:inline-block來佈局定位。它主要是幫助咱們作頁面佈局或同行元素間的的佈局。

在此回顧一下,display:inline-block使元素同行顯示外,接受全部盒子模型的屬性,包括heightwidthpaddingbordermargininline-block能夠充分使用盒子模型的全部屬性,而且不須要清除浮動。

Inline-Block練習

咱們來看上述三列並排顯示的例子,HTML結構以下:

<header>...</header>
<section>...</section>
<section>...</section>
<section>...</section>
<footer>...</footer>複製代碼

以前咱們爲<section>元素設置了浮動,如今咱們以display:inline-block來代替,並保留以前設置的marginwidth。 CSS呈現以下:

section {
  display: inline-block;
  margin: 0 1.5%;
  width: 30%;
}複製代碼

此時,代碼並無很好的解決問題,最後一個<section>元素掉到了下一行。行內塊元素是行內一個接着一個佈局,但它們之間有一個空格。當咱們將空格佔用的空間和全部元素的widthmargin相加,那麼佔用寬度會很是大,會將最後一個<section>擠到下一行。爲了讓全部<section>顯示在同一行,咱們就須要把這些空格移除。

img
img

移除inline-block元素之間的空格

有好幾種方法能夠移除掉空格,但有些方法會相對複雜一些。咱們將介紹兩種最簡單的方法,都是應用在HTML中的。

第一中解決方案是將<section>的開始標籤和前一個<section>的結束標籤寫在同一行。一行內的代碼以開始標籤爲結尾,以下所示:

<header>...</header>
<section>
  ...
</section><section>
  ...
</section><section>
  ...
</section>
<footer>...</footer>複製代碼

用這種方法要確保HTML在書寫時元素之間時沒有空格,那麼最終渲染時頁面也不會呈現出空格。

img
img

另外一種方法是在元素之間添加註釋。結束標籤和開始標籤之間以註釋鏈接,註釋必須緊跟元素。這麼寫能夠容許HTML元素在書寫時換行,代碼以下:

<header>...</header>
<section>
  ...
</section><!-- --><section>
  ...
</section><!-- --><section>
  ...
 </section>
 <footer>...</footer>複製代碼

這兩種方法沒有一種是很是完美的,但它們都很好用。我(做者)更傾向於添加註釋的方案,由於它更利於排版,但你徹底能夠根據你的喜愛來選擇。

建立可複用的佈局

在構建網站時,編寫可複用的模塊是很是有益的,而可複用的佈局就是可複用代碼中很是重要的一部分。佈局可使用float或者inline-block元素的方法實現,但那一種方法更好呢?

這是值得商榷。我(做者)的作法是使用inline-block元素實現頁面的網格或佈局,而當我想讓某部份內容環繞某個元素顯示時會使用floatfloat原本是用於處理圖片的)。並且我也發現inline-block元素的佈局方式更簡單,更易處理。

和前面說的同樣,你能夠根據本身的須要選擇最合適的方案,若是你對其中一種方法更滿意,那你就能夠選擇它。

目前,新的CSS規範提到了flexgrid-開頭的屬性——它們有助於實現頁面的最佳佈局。要時常關注留意這些新的方法。

練習

對可複用的佈局有所瞭解以後,咱們將其實施到咱們的Styles Conference網站。

  • 咱們將使用inline-block元素來實現一個一排三列的可複用佈局。能夠將其分爲等寬的三列,或者分爲兩列,一列佔2/3寬,一列佔1/3寬。
    首先,咱們使用class選擇器定義列寬width,在main.css文件中定義佔1/3寬的選擇器col-1-3,佔2/3寬的選擇器col-2-3。以下所示:
.col-1-3 {
  width: 33.33%;
}
.col-2-3 {
  width: 66.66%;
}複製代碼
  • 咱們想使這些列都以inline-block元素的方式呈現,咱們就須要確保它們垂直對齊爲頂部對齊。
    代碼以下所示,建立由兩個選擇器共享的樣式:
.col-1-3,
.col-2-3 {
  display: inline-block;
  vertical-align: top;
}複製代碼
  • 這段css代碼中,col-1-3col-2-3之間用逗號,隔開。逗號表示第一個選擇器結尾,後面跟着第二個選擇器。第二個選擇器後跟隨大括號{標識樣式開始申明。用逗號隔開選擇器可讓共用的樣式同時綁定到多個選擇器上。
  • 接下來咱們想在每列之間存設置空隙,使內容隔開。咱們能夠在選擇器中添加橫向的padding
    設置以後咱們能夠看到,當兩列元素挨着排列時,它們之間的空隙會是行開始和末尾空隙的兩倍,爲了使空隙一致,咱們使用一個元素將這些列包裹起來,併爲它設置相同的padding屬性。
  • 咱們爲這個包裹元素設置一個名爲gridclass選擇器,將其添加到共用的padding定義中。代碼以下所示,選擇器以前一樣用逗號隔開:
.grid,
.col-1-3,
.col-2-3 {
  padding-left: 15px;
  padding-right: 15px;
}複製代碼
  • 當咱們設置橫向padding後,咱們須要當心。上節課中,咱們建立了一個寬度爲960px,class名爲container的元素,並相對於頁面左右居中。如今若是咱們將grid元素嵌入container元素中,那麼它們的橫向padding就會相加,咱們的列與其餘的部分呈現出的寬度會不一致。
    咱們不但願發生這樣的事,因此咱們要讓containergrid選擇器共享一部分樣式。具體的來講,就是共享寬度width(確保咱們的頁面固定在960px寬)和外邊距margin(使grid元素居中),代碼以下所示:
.container,
.grid {
  margin: 0 auto;
  width: 960px;
}
.container {
  padding-left: 30px;
  padding-right: 30px;
}複製代碼
  • 如今每一個class屬性包含有container或者grid的元素寬度都爲960px,並相對於頁面居中。此外,咱們也將container選擇器的橫向padding分離寫到了另外一個樣式集中。

  • 到目前爲止,全部繁重的可複用網格佈局的樣式已經寫完了。如今咱們要將其添加到HTML中,看看它們呈現的結果。
    咱們從index.html主頁的三個宣傳欄開始,將它們設置爲三列。如今它們由一個class名爲container<section>包裹。咱們要將這個container替換爲grid,以下所示:

<section class="grid">
  ...
</section>複製代碼
  • 隨後咱們將class屬性col-1-3添加到每一個gird元素內的<section>元素上:
<section class="grid">

  <section class="col-1-3">
    ...
  </section>

  <section class="col-1-3">
    ...
  </section>

  <section class="col-1-3">
    ...
  </section>

</section>複製代碼
  • 最後,由於咱們的列都是inline-block元素,咱們要確保咱們移除了它們之間的間隙。咱們用註釋來完成這一工做,並在每塊中添加一些模塊說明,以便更好的組織咱們的代碼。
<section class="grid">

  <!-- Speakers -->

  <section class="col-1-3">
    ...
  </section><!-- Schedule --><section class="col-1-3">
    ...
  </section><!-- Venue --><section class="col-1-3">
    ...
  </section>

</section>複製代碼
  • 上述代碼中,咱們在第3行的中添加了用以標識的註釋「Speakers」第7行咱們在結束標籤<\section>後緊跟了註釋,在第9行添加了用以標識的註釋「Schedule」,並在11行開始標籤<section>前閉合了註釋。相同的註釋結構貫穿第13行和第17行,標識內容替換爲Venue。總的來講咱們已經將全部的間隙都註釋掉了併爲每一塊<section>添加了標識。
    如今咱們有了可複用的三列網格,可使用1/3寬的列和2/3寬的列。主頁中咱們用它來佈局了宣傳欄,最終結果如圖所示:

img
img

演示源代碼

這是練習的源代碼。點擊下載

獨特的定位元素

咱們經常想要定位一個元素,但floatinline-block並不能知足這種需求。浮動將元素從正常的文檔流中移除,常常出現咱們不但願獲得的環繞浮動元素顯示的佈局。inline-block元素,除非咱們建立多列,不然不易實現咱們想要的定位。針對這些狀況,咱們可使用position屬性來作位置偏移。

position屬性表示元素應該怎樣定位在頁面中,是否按正常文檔流顯示。這須要結合盒子的位移屬性——toprightbottomleft——經過定義位移值設置不一樣方向的位p移來定位元素在什麼位置顯示。

position屬性的默認值爲static,他表示元素以正常文檔流呈現,而且不接受盒子位移屬性。static經常會被relativeabsolute這兩個值複寫。這就是咱們接下來要講的內容。

相對定位

position:relative在容許元素以正常文檔流呈現,保留元素的空間不被其餘元素佔用外,也容許元素經過修改位移屬性來定位,以下所示:

HTML

<div>...</div>
<div class="offset">...</div>
<div>...</div>複製代碼

CSS

div {
  height: 100px;
  width: 100px;
}
.offset {
  left: 20px;
  position: relative;
  top: 20px;
}複製代碼

img
img

例子中第二個<div>元素設置了class屬性爲offsetoffset選擇器設置了position:relative和兩個位移屬性lefttop。這保留了元素原來的位置,不會被其餘元素佔用。另外位移屬性從新定位了元素的位置,使它向右偏移20px,向下偏移20px

使用相對定位有一個重要的點要知道:盒子位移屬性是根據元素自己的位置來進行位移的。因此設置left:20px就是將元素從左向右位移20pxtop:20px就是元素至上向下位移20px

當使用position對元素進位移時,該元素會與其餘元素重疊,而不是將其餘元素像使用了marginpadding同樣移到下面。

絕對定位

position:absolute爲絕對定位,它與相對定位不一樣,絕對定位脫離了文檔流,而它原有的位置不會被保留。

另外,絕對定位的元素位移與離他最近的設置了相對定位的父級元素有關。若是沒有相對定位的父級元素,那麼絕對定位會根據<body>來定位(譯者:根據個人實踐,瀏覽器在絕對定位的元素沒有相對定位的父級元素時,並非根據<body>定位,而是經過視窗的位置定位,有興趣的讀者能夠嘗試一下)。這裏的信息量比較多,咱們經過例子來看一下:
HTML

<section>
  <div class="offset">...</div>
</section>複製代碼

CSS

section {
  position: relative;
}
div {
  position: absolute;
  right: 20px;
  top: 20px;
}複製代碼

img
img

在這個例子中,<section>元素是不包含位移屬性的相對定位的元素,因此它沒有位移。div元素設置了包含position: absoluteclass屬性offset。因爲<section>是離它最近的設置了相對定位的父級元素,因此div依賴<section>元素的位置進行偏移

因爲設置了righttop位移,<div>根據<section>元素從右向左位移20px,從上向下位移20px

因爲<div>元素是絕對定位,它不在頁面的正常文檔流中,會與它周圍的元素重疊。另外,<div>元素原來的位置也沒有被保留,其餘元素能夠佔據這個位置。

一般狀況下,大多數的定位都不須要經過定位和位移屬性來處理,但在某些狀況下它們確實很是有用。

總結

學習如何經過HTML和CSS來定位內容是掌握這兩門語言很是重要的一步。再加上盒子模型,咱們正走在成爲前端開發者的路上。

回顧一下,在這節課中咱們所碰到的知識點:

  • 什麼是浮動,怎麼經過浮動定位內容
  • 怎麼清除和包裹浮動元素。
  • 怎麼經過inline-block元素定位內容。
  • 怎麼移除inline-block元素間的間隙。
  • 怎麼使用相對定位和絕對定位定位內容。

咱們每節課都在學習新的技能,因此讓咱們繼續。接下來,排版!

文章來源

learn.shayhowe.com/html-css/po…

最後的最後:
據說寫文章能夠得異步社區的書,異步社區做爲國內頂尖的IT專業圖書社區,它的書我很是想要,尤爲是這本書《HTML5 Canvas開發詳解》,你們若是以爲好給我點個贊吧

《HTML5 Canvas開發詳解》
《HTML5 Canvas開發詳解》
相關文章
相關標籤/搜索