CSS學習摘要-定位實例

CSS學習摘要-定位實例

注:全文摘自MDN-CSS定位實例

列表消息盒子

我們研究的第一個例子是一個經典的選項卡消息框,你想用一塊小區域包括大量信息時,一個非常常用的特徵。這包括含有大信息量的應用,比如策略戰爭遊戲,比如從移動版的網頁,屏幕狹小、空間有限;比如你可能想要放置許多信息的緊湊消息框,不用就會充滿整個UI。我們簡單的例子完成後就會像下面這樣:

注意: 你能看完整的示例,可運行在 info-box.html (source code)。檢出它以理解你在本文章裏要建立什麼。

你可能會想:”爲什麼不僅僅做獨立的選項卡爲一個獨立的網頁,然後通過點擊不同的標籤來在不同的頁面跳轉來達到這個效果?“這樣代碼可能會簡單一些,是的。但是這樣每個獨立的”頁面“視圖將會實際上是一個新加載的網頁,跨視圖更難保存信息,並把這個特徵融入一個更大的UI設計。另外,所謂的”單頁應用“正在變得非常流行——尤其是移動網頁UI——因爲把一切的服務放在一個單獨的文件上可以減少HTTP請求的數量來瀏覽所有內容,從而提高性能。

注意: 一些網絡開發者甚至更超前,每次只加載一頁的信息,並且使用JavaScript諸如 XMLHttpRequest特徵動態改變信息顯示。在你學習的此刻,然而,我們希望儘可能保持簡單。接下來有一些JavaScript,但是隻有一點。

在開始之前,我們需要你拷貝文件到本地,當作起始的HTML文件—— info-box-start.html. 保存到你的計算機合適的位置,然後在你的編輯器裏打開。讓我們看看包含在 body 裏的HTML代碼:

<section class="info-box">
  <ul>
    <li><a href="#" class="active">Tab 1</a></li>
    <li><a href="#">Tab 2</a></li>
    <li><a href="#">Tab 3</a></li>
  </ul>
  <div class="panels">
    <article class="active-panel">
      <h2>The first tab</h2>

      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque turpis nibh, porttitor nec venenatis eu, pulvinar in augue. Vestibulum et orci scelerisque, vulputate tellus quis, lobortis dui. Vivamus varius libero at ipsum mattis efficitur ut nec nisl. Nullam eget tincidunt metus. Donec ultrices, urna maximus consequat aliquet, dui neque eleifend lorem, a auctor libero turpis at sem. Aliquam ut porttitor urna. Nulla facilisi.</p>
    </article>
    <article>
      <h2>The second tab</h2>

      <p>This tab hasn't got any Lorem Ipsum in it. But the content isn't very exciting all the same.</p>
    </article>
    <article>
      <h2>The third tab</h2>

      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque turpis nibh, porttitor nec venenatis eu, pulvinar in augue. And now an ordered list: how exciting!</p>

      <ol>
        <li>dui neque eleifend lorem, a auctor libero turpis at sem.</li>
        <li>Aliquam ut porttitor urna.</li>
        <li>Nulla facilisi</li>
      </ol>
    </article>
  </div>
</section>

這樣我們已經得到了一個<section>元素帶有類(class)爲 info-box。此元素又包含一個 <ul> 和一個 <div>。無序列表包含三個列表項,列表項有鏈接在內,實際上將成爲用於點擊後顯示內容面板的選項卡。 div 包含三個<article> (<article>元素表示文檔、頁面、應用或網站中的獨立結構,其意在成爲可獨立分配的或可複用的結構,如在發佈中,它可能是論壇帖子、雜誌或新聞文章、博客、用戶提交的評論、交互式組件,或者其他獨立的內容項目。) 元素,構成對應於每個選項卡的內容面板。 每個面板包含一些示例內容。

這裏的思路是我們將樣式化選項卡看起來是一個標準的水平導航菜單,使用絕對定位樣式化面板互相坐落其頂上。我們也給你一點JavaScript包含到你的頁面上,當選項卡被按下時,顯示對應的面板,並且樣式化選項卡本身。你不需要在這個階段瞭解JavaScript本身,但是你應該儘快學習一些基本的 JavaScript——你的用戶界面越複雜,越需要一些JavaScript來實現你渴望的功能。

一般設置

開始前,在<style>開閉標籤之間添加下面的代碼:

html {
  font-family: sans-serif;
}

* {
  box-sizing: border-box;
}

body {
  margin: 0;
}

這只是一些一般設置,在我們頁面上設置了無襯線的字體、使用 box-sizing 模型,去掉 <body> 默認外邊距。

下一步,在你早先的CSS下面加入如下代碼:

.info-box {
  width: 450px;
  height: 400px;
  margin: 0 auto;
}

這對內容設置具體的高度和寬度、在屏幕居中使用老把戲 margin: 0 auto 。在早先的課程中我們建議儘可能不固定內容容器的高度。這個情況下是可以的,因爲我們是在選項卡中固定的內容,如果每個標籤都有不同的高度,看起來也有些不和諧。

樣式化我們的選項卡

現在我們希望樣式化選項卡看上去像選項卡——基本,這些是一個水平的導航標籤,但不是點擊之後加載不同的網頁,和我們之前在課程中見到的不同,相反,他們在同一頁面上顯示不同的面板。首先,在你的CSS底部添加下列規則,從無序列表中移除默認的padding-leftmargin-top值:

.info-box ul {
  padding-left: 0;
  margin-top: 0;
}

注意: 我們正在使用後代選擇器,整個例子 .info-box 都位於鏈的開始——這樣頁面已經帶有其他內容時,我們可以插入這個特徵,不害怕與應用於頁面其他部分的樣式衝突。

接下來,我們將樣式化水平選項卡——列表項都要左浮動確保他們一行合起來,他們的list-style-type被設置爲 none 用以去除項目符號,寬度(width)設置爲 150px 以便於適應這個info-box。鏈接( <a>)元素設置爲display inline-block,這樣他們將在一行顯示,仍然保持樣式可設置,他們會被樣式化合適的選項卡按鈕,通過一系列的其他屬性。

添加下列的CSS:

.info-box li {
  float: left;
  list-style-type: none;
  width: 150px;
}

.info-box li a {
  display: inline-block;
  text-decoration: none;
  width: 100%;
  line-height: 3;
  background-color: red;
  color: black;
  text-align: center;
}

最後,對於本節,我們將會在鏈接狀態上設置一些樣式。首先,我們要設置標籤的 :focus:hover 狀態,讓他們在獲得焦點/鼠標懸浮的時候看起來不同,給用戶提供一些可視化反饋。其次,當某個選項卡的類( class )出現 active 時,我們爲其設置一條相同的樣式規則。我們將通過使用JavaScript來設置,當一個標籤被點擊時。把這些CSS放置在你的其他樣式後面:

.info-box li a:focus, .info-box li a:hover {
  background-color: #a60000;
  color: white;
}

.info-box li a.active {
  background-color: #a60000;
  color: white;
}

樣式化面板

下一步工作是樣式化我們的面板,現在開始吧!

首先,添加下列的規則去樣式化 .panels <div> 容器。我們簡單的設置一個固定的高度,確保面板包含在info-box裏面,position relative 設置 <div>爲定位上下文,這樣你能然後相對自身放置定位子元素,而不是相對<html>元素,最後我們清除(clear)浮動,設置在上面CSS中,這樣避免影響佈局的剩餘部分。

.info-box .panels {
  height: 352px;
  position: relative;
  clear: both;
}

在本節的最後,我們將對包含我們面板的單獨 <article>元素設置樣式。我們添加的第一條規則就是絕對定位面板,讓他們都位於<div>容器的左上角——這一部分對整個佈局特性是關鍵的,就像使面板互相位於頂部。規則設置面板爲和容器同樣的高度,給內容一些內邊距,設置字體顏色(color),和背景顏色(background-color)。

我們將添加的第二條規則,對帶有類( class )爲( active-panel )的面板,設置z-index爲 1,會讓他位於其他的面板之上(默認定位元素 z-index 的值是 0,會使默認元素位於下面)。同樣的,我們會在合適的時候用JavaScript 來添加這個類。

.info-box article {
  position: absolute;
  top: 0;
  left: 0;
  height: 352px;
  padding: 10px;
  color: white;
  background-color: #a60000;
}

.info-box .active-panel {
  z-index: 1;
}

添加我們的JavaScript

讓這些特性工作的最後一步是添加一些JavaScript。添加下列一塊代碼,準確的寫在你的開始和結束的<script>標籤之間(在接下來的HTML內容中你將會發現這些):

var tabs = document.querySelectorAll('.info-box li a');
var panels = document.querySelectorAll('.info-box article');

for(i = 0; i < tabs.length; i++) {
  var tab = tabs[i];
  setTabHandler(tab, i);
}

function setTabHandler(tab, tabPos) {
  tab.onclick = function() {
    for(i = 0; i < tabs.length; i++) {
      if(tabs[i].getAttribute('class')) {
        tabs[i].removeAttribute('class');
      }
    }

    tab.setAttribute('class', 'active');

    for(i = 0; i < panels.length; i++) {
      if(panels[i].getAttribute('class')) {
        panels[i].removeAttribute('class');
      }
    }

    panels[tabPos].setAttribute('class', 'active-panel');
  }
}

這些代碼做了如下工作:

  • 首先我們保存所有的選項卡和所有的面板引用到兩個變量中,名爲 tabspanels,這樣此後我們可以容易地爲它們做事。

  • 然後我們使用 for 循環遍歷所有的選項卡,並且在每一個上運行叫做setTabHandler() 的函數,此函數建立當每個選項卡被點擊時應該發生的功能。 運行時, 函數會被傳遞選項卡,和一個索引數i 指明選項卡在tabs 數組中的位置。

  • 在setTabHandler()函數中,這個標籤創建了一個onclick事件來處理點擊,所以當標籤被點擊的時候,接下來會發生:

    • 一個for循環用來清除所有標籤當前存在的類。

    • 當點擊的時候在標籤上創建了一個active 類——從相關聯的元素中繼承了CSS的一些屬性,具有和panels的樣式相同的顏色,背景顏色。

    • 一個for循環用於清除所有面板當前存在的類。

    • 當標籤被點擊的時候在和標籤相對應的面板上創建了一個active-panel 類——從相關聯的元素中繼承了CSS的一些屬性,使他的z-index屬性被設置爲1,讓他能位於所有的面板的上面。

效果如下:

一個固定位置的列表消息盒子

在我們的第二個例子中,我們將會採用我們的第一個例子——我們的消息盒子——把她加到一個滿的網頁之中去。但是不僅僅是這樣——我們將固定她的位置,以便於他能待在瀏覽器窗口的同一個位置。當主要內容滾動時,這個消息盒子將會待在屏幕的同一個位置。我們完工以後的例子長下面這樣:

注:你可以點擊藍字 fixed-info-box.html (source code)預覽完成後的效果,看看哪些部分是你在這篇文章裏你要製作的。

在開始的時候,你可以使用第一部分中完成的例子,或者從我們的Github倉庫中info-box.html 拷貝info-box.html到本地。

添加HTML

首先,我們需要一些額外的內容在當前的主內容中。添加下列部分在你的body標籤之中,在已存在的部分之中前:

<section class="fake-content">
  <h1>Fake content</h1>
  <p>This is fake content. Your main web page contents would probably go here.</p>
  <p>This is fake content. Your main web page contents would probably go here.</p>
  <p>This is fake content. Your main web page contents would probably go here.</p>
  <p>This is fake content. Your main web page contents would probably go here.</p>
  <p>This is fake content. Your main web page contents would probably go here.</p>
  <p>This is fake content. Your main web page contents would probably go here.</p>
  <p>This is fake content. Your main web page contents would probably go here.</p>
  <p>This is fake content. Your main web page contents would probably go here.</p>
</section>

注:你可以隨意更改內容,替換爲你想要內容。

更改存在的CSS

接下來我們需要對之前的Css進行一些小修改,讓消息盒子放置和定位的好一些。刪除你的margin: 0 auto (不需要居中顯示),添加fixed定位;調整top 屬性把她粘在瀏覽器的視域。

.info-box {
  width: 450px;
  height: 400px;
  position: fixed;
  top: 0;
}

對主內容樣式設計

對於這個例子來說唯一剩下的事情就是給主內容提供一些樣式設計。添加下面的規則到你剩下的Css 的下面:

.fake-content {
  background-color: #a60000;
  color: white;
  padding: 10px;
  height: 2000px;
  margin-left: 470px;
}

開始我們給這個內容和消息盒子面板一樣的背景顏色,顏色,內邊距。然後給他一個大的margin-left使他移動到右邊,爲消息盒子在左邊騰出位置,以便於各個部分不重疊。

這標誌着第二個例子的結束;我們希望你能感到第三個例子,完全是因爲興趣。

一個滑動隱藏的面板

最後一個我們在這裏介紹的例子是通過按圖標使面板滑動出現或者消失——就像前面提到的,這種場景在移動端的佈局很流行,因爲移動端的屏幕很小,所以你不希望使用大部分界面來顯示一個有用的內容而是用消息面板或者菜單代替。

我們完工後的例子長這樣:

提示:你可以點擊藍字hidden-info-panel.html (source code)預覽完成後的效果,仔細看看哪些部分是你在這篇文章裏你要製作的。

在一開始,老規矩在我們的Githib代碼倉庫拷貝hideen-info-panel-start.html(源碼)。

<!DOCTYPE html>
<html lang="en-us">
<head>
    <meta charset="utf-8">
    <title>Hidden info panel</title>

  <style>
    /* || Checkbox hack to control information box display */
    label[for="toggle"] {
      font-size: 3rem;
      position: absolute;
      top: 4px;
      right: 5px;
      z-index: 1;
      cursor: pointer;
    }
    input[type="checkbox"] {
       position: absolute;
       top: -100px;
    }
    /* information box styling */
    aside {
      background-color: #a60000;
      color: white;
      width: 340px;
      height: 100%;
      padding: 0 20px;
      position: fixed;
      top: 0;
      right: -370px;
      transition: 0.6s all;
    }
    /* Second part of the checkbox hack — the checked state */
    input[type=checkbox]:checked + aside {
      right: 0px;
    }
  </style>

</head>
<body>


  <label for="toggle">?</label>
  <input type="checkbox" id="toggle">
  <aside>
    <h2>Information</h2>

    <p>Some very important information about your app:</p>

    <ol>
      <li>It has a really cool slide-out information box.</li>
      <li>This information box uses a combination of fixed positioning and a CSS transition for the smooth sliding.</li>
      <li>It also uses a cool technique called the <a href="https://css-tricks.com/the-checkbox-hack/">checkbox hack</a>.</li>
      <li>This allows you to create a nice "toggle on/toggle off" UI effect without using any JavaScript, which will work in IE9 and above (the smooth transition will work in IE10 and above.)</li>

    </ol>

  </aside>
</body>
</html>

這個例子並沒有用先前的例子,所以我們需要一個新的開始文件。讓我們來仔細觀察一下這個HTML文件:

<label for="toggle">❔</label>
<input type="checkbox" id="toggle">
<aside>

  ...

</aside>

//label的 for屬性規定label屬性綁定到哪個表單元素。

開始,我們看到了一個label 元素和input元素——<label>元素普遍用來聯繫文字標籤和表單,目的是能更好的理解表單(允許用戶查看錶單元素的描述)。這裏通過for屬性綁定id到了<input>標籤的checkbox元素。

提示:我們已經設置了一個特殊的問題標記特性到我們的HTML中,來當作我們的信息圖標——這代表着這個按鈕將可以按下顯示或隱藏面板。

現在我們使用這些元素稍稍不同的目的——另一個<label>標籤有副作用使你能通過點擊checkbox的label標籤來選擇這個checkbox,就好像點擊了這個checkbox自己一樣。這就會實現有名的checkbox hack 技術,可以提供無JS的方法來控制一個元素,通過一個按鈕的聯繫。我們將控制的元素使aside元素,通過其他兩個(爲了簡潔起見,我們已將其內容從上述代碼列表中刪除)。

在下面的部分我們將解釋這一切如何運作。

設置表單元素樣式

首先讓我們處理表單元素 - 在style標籤之間添加以下CSS:

label[for="toggle"] {
  font-size: 3rem;
  position: absolute;
  top: 4px;
  right: 5px;
  z-index: 1;
  cursor: pointer;
}

input[type="checkbox"] {
  position: absolute;
  top: -100px;
}
  • 第一條label樣式的規則,我們有:

    • 設置字體大小使圖標更美觀。

    • 設置爲絕對定位,使用top屬性和right屬性來讓他能很合適的位於右上角。

    • 設置z-index屬性爲1——因此當信息面板被賦予樣式和顯示的時候,不會覆蓋我們的圖標;相反圖標依然會位於最上層能夠再次被按下來隱藏信息平板。

    • 使用cursor屬性來說改變鼠標的指針,當鼠標懸浮在圖標上面的時候變成一個手形指針(就像你看到的當懸浮在鏈接上一樣),作爲一個額外的可視化線索告訴用戶這個圖標可以做一些有趣的事情。

  • 第二條規則是在實際的<input>checkbox元素上設置絕對定位屬性,並隱藏在頂部的上面,我們並不希望在我們的用戶界面裏看到她。

設置面板的樣式

現在是時候爲實際的滑動面板設計風格了。在你的css底部添加下列規則:

aside {
  background-color: #a60000;
  color: white;

  width: 340px;
  height: 98%;
  padding: 10px 1%;

  position: fixed;
  top: 0;
  right: -370px;

  transition: 0.6s all;
}

這裏有很多項——讓我們一點一點討論:

  • 首先,我們在信息盒子中設置了一些簡單的背景顏色和顏色。

  • 然後,我們在面板上設置一個固定的寬度,讓她的高度充滿整個瀏覽器窗口的高度。

  • 我們同樣包括一些內邊距來組成我們小於那個要的高度和寬度總體的值(如果我們沒有設置box-sizing:border-box來說的話是很必要的,正如這個例子)

  • 然後,我們設置面板的定位爲fixed,即使頁面的內容在滾動,也總是顯示在同一個位置。我們把設置top屬性讓窗口粘在頂部,然後設置默認情況下遠離屏幕,設置right屬性使其位於屏幕的右邊。

  • 最後我們設置transition屬性,Transitions是一個有意思的特性,允許你在狀態改變的時候平滑的過渡,而不是粗暴的“變”或“還原”。在這個例子中我們嘗試在checkbox被選中時讓面板平滑的滑動到屏幕上。(或者換句話說,當問題標記圖標被點擊以後——記住,點擊

設置選擇後的狀態

這是最後的css添加——把這些放到你的css底部:

input[type=checkbox]:checked + aside {
  right: 0px;
}

這裏的選擇器是複雜的——我們選擇<input>元素鄰接的<aside>元素,但是僅僅在他被選擇(請注意使用checked僞類來實現此目的),在這種情況下,我們將right屬性設置爲0px,會造成面板再次出現在屏幕上(由於過渡屬性會平滑的出現)。再一次點擊這個標籤會取消選中checkbox,面板將會跟着再一次消失。

所以你有它 ——一個相當巧妙的避免使用JavaScript來創建一個切換按鈕效果方式。 這將在IE9及以上版本中起作用(平滑過渡將在IE10及更高版本中起作用)。這種效果確實有一些問題 ——這是有點濫用表單元素(它們不是爲了這個目的),並且在可訪問性方面效果不是很好 - 標籤在默認情況下不可聚焦,並且表單元素的非語義使用可能會導致屏幕朗讀器出現問題。 JavaScript和鏈接或按鈕可能更合適,但這樣的實驗仍然很有趣。

最後完成的代碼如下:
(另外這裏我使用了?來取代那個問號的圖標,效果是一樣的。)

<!DOCTYPE html>
<html lang="en-us">
<head>
    <meta charset="utf-8">
    <title>Hidden info panel</title>

  <style>
    /* || Checkbox hack to control information box display */
    label[for="toggle"] {
      font-size: 3rem;
      position: absolute;
      top: 4px;
      right: 5px;
      z-index: 1;
      cursor: pointer;
    }
    input[type="checkbox"] {
       position: absolute;
       top: -100px;
    }
    /* information box styling */
    aside {
      background-color: #a60000;
      color: white;
      width: 340px;
      height: 98%;
      padding: 10px 1%;
      position: fixed;
      top: 0;
      right: -370px;
      transition: 0.6s all;
    }
    /* Second part of the checkbox hack — the checked state */
    input[type=checkbox]:checked + aside {
      right: 0px;
    }
  </style>

</head>
<body>


  <label for="toggle">?</label>
  <input type="checkbox" id="toggle">
  <aside>
    <h2>Information</h2>

    <p>Some very important information about your app:</p>

    <ol>
      <li>It has a really cool slide-out information box.</li>
      <li>This information box uses a combination of fixed positioning and a CSS transition for the smooth sliding.</li>
      <li>It also uses a cool technique called the <a href="https://css-tricks.com/the-checkbox-hack/">checkbox hack</a>.</li>
      <li>This allows you to create a nice "toggle on/toggle off" UI effect without using any JavaScript, which will work in IE9 and above (the smooth transition will work in IE10 and above.)</li>

    </ol>

  </aside>
</body>
</html>

gif效果圖:

總結

這樣完成了我們對定位的關注——現在,你應該理解基本機制的工作原理,同樣理解了怎樣應用這些知識去構建一些有趣的用戶界面功能,不要由於你還未完全理解所有的知識而擔心——定位是一個相當高級的話題,你可以隨時讀這篇文章來幫助你的理解。下一個主題我們將轉向Flexbox。

【end】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章