Learn web development

定位实例练习

With the basics of positioning covered in the last article, we will now look at building some real world examples, to illustrate what kinds of things you can do with positioning.

在上一篇文章对定位基础学习后,我们将着眼于实现一些新的例子,来举例解释你能用定位来做什么。

Prerequisites:

需要的基础:

HTML basics (study Introduction to HTML), and an idea of How CSS works (study Introduction to CSS.)

Objective:

目标:

To get an idea of the practicalities of positioning

A tabbed info-box

 

The first example we'll look at is a classic tabbed info box — a very common feature used when you want to pack a lot of information into a small area. This includes information-heavy apps like strategy/war games, mobile versions of websites where the screen is narrow and space is limited, and compact information boxes where you might want to make lots of information available without having it fill the whole UI. Our simple example will look like this once we are finished:

列表消息盒子

我们研究的第一个例子就是一个经典的列表消息盒子,是你想打包一些信息到一个小区域时候常用的东西。这个含有大信息量的app像策略或战争游戏。从移动端的视角看网页,屏幕是狭小的,空间是有限的。紧凑的信息盒子是一个你可能想要放置许多信息而不占据整个用户界面的地方。我们简单的例子完成后就会像下面这样:

Note: You can see the finished example running live at info-box.html (source code). Check it out to get an idea of what you will be building in this section of the article.

你能点击链接来预览完成后的效果,看看哪些部分是你在这片文章里你要制作的。

You might be thinking "why not just create the separate tabs as separate webpages, and just have the tabs clicking through to the separate pages to create the effect?" This code would be simpler, yes, but then each separate "page" view would actually be a newly-loaded webpage, which would make it harder to save information across views, and integrate this feature into a larger UI design. In addition, so-called "single page apps" are becoming very popular — especially for mobile web UIs — because having everything served as a single file cuts down on the number of HTTP requests required to view all the content, thereby improving performance.

你可能会想:”为什么不仅仅做一个单独的表格当作一个单独的网页,然后通过点击不同的标签来在不同的页面跳转来创造效果?“这样代码可能会简单一些,是的。但是这样每一个单独的”页面“查看将会事实上变成一个新加载的页面,会让跨”页面“查看更难保存信息,也会把这种特点融入一个比之前更大的UI设计。另外,所谓的”单页应用“变得越来越流行——尤其是移动端网页用户界面设计——因为把所有的服务放在一个单独的文件上可以减少对HTTP请求的数量来显示整个内容,从而提高性能。

Note: Some web developers take things even further, only having one page of information loaded at once, and dynamically changing the information shown using a JavaScript feature such as XMLHttpRequest. At this point in your learning however we want to keep things as simple as possible. There is some JavaScript later on, but only a tiny bit.

笔记:一些web开发者甚至更超前,每次仅仅只加载一页信息,通过使用Javascript特性例如XMLHttpRequest来动态改变信息显示。这种观点运用在你的学习上用该是我们要保持东西尽可能简单。接下来有一些Javascript,但是我保证只有一点点。

To start with, we'd like you to make a local copy of the starting HTML file — info-box-start.html. Save this somewhere sensible on your local computer, and open it up in your text editor. Let's look at the HTML contained within the body:

在开始之前,我们需要你拷贝文件到本地,当作起始的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>

So here we've got a <section> element with a class of info-box, which contains a <ul> and a <div>. The unordered list contains three list items with links inside, which will become the actual tabs to click on for displaying our content panels. The div contains three <article> elements, which will make up the content panels that correspond to each tab. Each panel contains some sample content.

现在我们在info-box类里已经得到了一个section元素。元素包含一个ul和一个div。这个无序列表包含三个内部链接列表项(li),这实际将成为点击后显示内容面板的选项卡。Div标签包含三个article元素,这将构成对应于每个选项卡的内容面板。 每个面板包含一些示例内容。

The idea here is that we will style the tabs to look like a standard horizontal navigation menu, and style the panels to sit on top of one another using absolute positioning. We'll also give you a bit of JavaScript to include on your page to display the corresponding panel when a tab is pressed, and style the tab itself. You won't need to understand the JavaScript itself at this stage, but you should think about learning some basic JavaScript as soon as possible — the more complex your UI features become, the more likely it is that you'll need some JavaScript to implement your desired functionality.

在这我们的标签的样式是看起来是一个标准的水平导航菜单,panel的样式位于另一个使用绝对定位的position的样式的上面。我们同样给你一些JavaScript代码来保证当你按下表的时候显示对应的页面,然后自己改变表的样式。你不需要在这个阶段了解JS,但是你应该尽快学习一些基础的JS——你的用户界面越复杂,越需要一些JS来实现你需要的功能。

General setup

一般设置

To begin with, add the following between your opening and closing <style> tags:

开始,在style标签里加上下面的代码:

html {
  font-family: sans-serif;
}
* {
  box-sizing: border-box;
}
body {
  margin: 0;
}

This is just some general setup to set a sans-serif font on our page, use the border-box box-sizing model, and get rid of the default <body> margin.

Next, add the following just below your previous CSS:

这仅仅是一些一般设置来设置字体,边框模型,去掉默认的margin.

然后,加入你的早先的CSS下面加入如下代码:

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

This sets a specific width and height on the content, and centers it on the screen using the old margin: 0 auto trick. Previously in the course we advised against setting a fixed height on content containers if at all possible; it is ok in this circumstance because we have fixed content in our tabs. It also looks a bit jarring to have different tabs at different heights.

对内容设置特别的高度和宽度,在使用古老的margin:0 auto 把戏,实现在屏幕居中。在早先的课程中我们建议反对设置内容容器固定的宽度,如果可能的话。在这里是允许的,因为我们固定我们标签的内容,如果每个标签都有不同的高度,看起来也有些不和谐。

Styling our tabs

对你的标签设置样式

Now we want to style tabs to look like tabs — basically, these are a horizontal navigation menu, but instead of loading different web pages when they are clicked on like we've seen previously in the course, they cause different panels to be displayed on the same page. First, add the following rule at the bottom of your CSS to remove the default padding-left and margin-top from the unordered list:

现在我们要让标签样式看起来更像标签——基本的,这里有一个水平的导航标签,但是和我们之前学的点击之后加载不同的界面,他们会显示不同的面板在同一个界面上。首先,在你的CSS底部添加下列规则,来从无序列表中移除默认的padding-left和margin-top 值:

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

Note: We are using descendant selectors with .info-box at the start of the chain throughout this example — this is so that we can insert this feature into a page with other content already on it, without fear of interfering with the styles applied to other parts of the page.

笔记:这个例子开始的链,我们使用.info-box 选择器的后裔——这样我们就能插入一个已经有其他内容的页面,不用担心干扰页面的其他部分。

Next, we'll style the horizontal tabs — the list items are all floated left to make them sit in a line together, their list-style-type is set to none to get rid of the bullets, and their width is set to 150px so they will comfortably fit across the info-box. The <a> elements are set to display inline-block so they will sit in a line but still be stylable, and they are styled appropriately for tab buttons, using a variety of other properties.

Add the following CSS:

接下来,我们要对水平的标签样式进行设计——列表项都要左浮动确保他们在一条直线上,他们的list-style-type被设置为none用以去除小圆点,宽度设置为150px以便于适应这个info-box。链接元素设置为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;
}

Finally for this section we'll set some styles on the link states. First, we'll set the :focus and :hover states of the tabs to look different when they are focused/hovered, providing users with some visual feedback. Secondly, we'll set a rule that puts the same styling on one of the tabs when a class of active is present on it. We will set this using JavaScript when a tab is clicked on. Place the following CSS below your other styles:

最后,对于这些section,我们将会设置一些样式在链接声明上。首先,我们要设置标签的focus 和 hover属性,让他们在聚焦/鼠标悬浮的时候看起来不同,给用户提供一些可视化反馈。其次,我们设置一条规则,使用相同的样式当active已经在其中已经使用过的标签,我们将通过使用来设置,当一个标签被点击。把这些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;
}

Styling the panels

对panels设置样式

The next job is to style our panels. Let's get going!

First, of all, add the following rule to style the .panels <div> container. Here we simply set a fixed height to make sure the panels fit snugly inside the info-box, position relative to set the <div> as the positioning context, so you can then place positioned child elements relative to it and not the <html> element, and finally we clear the float set in the CSS above so that it doesn't interfere with the remainder of the layout.

下一步设置你的panels样式,现在开始吧!

首先,添加下列的规则到样式 .panels容器中。我们简单的设置固定的高度属性确保panels紧紧的包含在info-box里面,将其设置为相对定位,以div为参考。所以你能把子元素以相对定位放置,不是以html元素为参考,最后我们清除浮动,避免影响其他的层。

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

Finally for this section, we will style the individual <article> elements that comprise our panels. The first rule we'll add will absolutely position the panels, and make them all sit flush to the top and left of their <div> container — this part is absolutely key to this whole layout feature, as it makes the panels sit on top of one another. The rule also gives the panels the same set height as the container, and gives the content some padding, a text color, and a background-color.

在这个section的最后,我们将对包含在我们面板内的article元素设置单独的样式。我们添加的第一条规则就是相对于面板的绝对定位,让他们对齐div容器的顶部和左边——这一部分对整个层的特性是关键的,就像使面板位于其他内容的顶部。规则同样给面板和容器同样的高度,给内容一些padding 边距,设置字体颜色,和背景颜色。

The second rule we'll add here makes it so that a panel with a class of active-panel set on it will have a z-index of 1 applied to it, which will make it sit above the other panels (positioned elements have a z-index of 0 by default, which would put them below). Again, we'll add this class using JavaScript at the appropriate time.

我们将添加的第二条规则对面板的active-panels类设置z-index为1,会让他位于其他的面板之上(定位元素z-index的默认值使0,会使默认元素位于下面)。同样的,我们会在合适的时候用一些JS来添加这个类。

 

.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;
}

Adding our JavaScript

添加我们的JS

The final step to getting this feature working is to add some JavaScript. Put the following block of code, exactly as written in between your opening and closing <script> tags (you'll find these below the HTML content):

最后一步让这些特性工作需要添加一些JS代码。添加下列块状代码,准确的写在你的开始和结束的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');
  }
}

This code does the following:

  • First we save a reference to all the tabs and all the panels in two variables called tabs and panels, so we can easily do things to them later on.
  • Then we use a for loop to cycle through all the tabs and run a function called setTabHandler() on each one, which sets up the functionality that should occur when each one is clicked on. When run, the function is passed a reference to the particular tab it is being run for, and an index number i that indentifies the tab's position in the tabs array.
  • In the setTabHandler() function, the tab has an onclick event handler set on it, so that when the tab is clicked, the following occurs:
    • A for loop is used to cycle through all the tabs and remove any classes that are present on them.
    • A class of active is set on the tab that was clicked on — remember from earlier that this class has an associated rule in the CSS that sets the same color and background-color on the tab as the panels are styled with.
    • A for loop is used to cycle through all the panels and remove any classes that are present on them.
    • A class of active-panel is set on the panel that corresponds to the tab that was clicked on — remember from earlier that this class has an associated rule in the CSS that sets its z-index to 1, making it appear over the top of the other panels.

That's it for the first example. Keep your code open, as we'll be adding to it in the second one.

这些代码做了如下工作:

首先分别在所有的“tab”和"panel"属性与两个变量tabs和panels建立引用,以便于我们能在接下来的时候简单的搞事情。

接下来我们用一个for循环对所有的tab属性运行setTabHandler()函数,当各自被点击发生时实现功能 。当运行时,这个函数被作为引用传递给特定的现有的运行的标签。目录数字 i 被用来标明标签在tabs数组中的位置。

在setTabHandler()函数中,这个标签创建了一个onclick事件来处理点击,所以当标签被点击的时候,接下来会发生:

一个for循环用开清除所有标签当前存在的类

当点击的时候在标签上创建了一个active 类——从相关联的元素中继承了CSS的一些属性,具有和panels的样式相同的颜色,背景颜色。

一个for循环用开清除所有面板当前存在的类

当标签被点击的时候在和标签相对应的面板上创建了一个active-panel 类——从相关联的元素中继承了CSS的一些属性,使他的z-index属性被设置为1,让他能位于所有的面板的上面。

 

A fixed position tabbed info-box

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

In our second example, we will take our first example — our info-box — and add it into the context of a full web page. But not only that — we'll give it fixed position so that it stays in the same position in the browser window. When the main content scrolls, the info-box will stay in the same position on the screen. Our finished example will look like this:

在我们的第二个栗子中,我们将会采用我们的第一个例子——我们的消息盒子——把她加到一个满的网页之中去。但是不仅仅是这样——我们将固定她的位置,以便于他能待在浏览器窗口的同一个位置。当主要内容滚动时,这个消息盒子将会待在屏幕的同一个位置。我们完工以后的例子长下面这样:

Note: You can see the finished example running live at fixed-info-box.html (source code). Check it out to get an idea of what you will be building in this section of the article.

笔记:你可以点击蓝字预览完成后的效果,看看哪些部分是你在这篇文章里你要制作的。

As a starting point, you can use your completed example from the first section of the article, or make a local copy of info-box.html from our Github repo.

在开始的时候,你可以使用第一部分中完成的例子,或者从我们的Github仓库中拷贝info-box.html到本地。

HTML additions

添加HTML 

First of all, we need some additional HTML to represent the web site main content. Add the following <section> just below your opening <body> tag, just before the existing section:


首先,我们需要一些额外的内容在当前的主内容中。添加下列部分在你的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>

Note: You can feel free to change the fake content for some real content if you like.

笔记:你可以随意更改更改假的内容,替换为你想要的真的内容。

Changes to the existing CSS

更改存在的CSS

Next we need to make some small changes to the existing CSS, to get the info-box placed and positioned. Change your .info-box rule to get rid of margin: 0 auto; (we no longer want the info-box centered), add position: fixed;, and stick it to the top of the browser viewport.

It should now look like this:

接下来我们需要对之前的Css进行一些小修改,让消息盒子放置和定位的好一些。删除你的margin: 0 auto (不需要居中显示),添加fixed定位;调整top 属性把她粘在浏览器的视域。

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

Styling the main content

对主内容样式设计

The only thing left for this example is to provide the main content with some styling. Add the following rule underneath the rest of your CSS:

对于这个例子来说唯一剩下的事情就是给主内容提供一些样式设计。添加下面的规则到你剩下的Css 的下面:

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

To start with, we give the content the same background-color, color, and padding as the info-box panels. We then give it a large margin-left to move it over to the right, making space for the info-box to sit in, so it is not overlapping anything else.

This marks the end of the second example; we hope you'll find the third just as interesting.

开始我们给这个内容和消息盒子面板一样的背景颜色,颜色,内边距。然后给他一个大的margin-left使他移动到右边,为消息盒子在左边腾出位置,以便于各个部分不重叠。

这标志着第二个例子的结束;我们希望你能感到第三个例子,完全是因为兴趣。

A sliding hidden panel

一个滑动隐藏的面板

The final example we'll present here is a panel that slides on and off the screen at the press of an icon — as mentioned earlier, this is popular for situations like mobile layouts, where the available screen spaces is small, so you don't want to use up most of it by showing a menu or info panel instead of the useful content.

最后一个我们在这里介绍的例子是通过按图标使面板滑动出现或者消失——就像前面提到的,这种场景在移动端的布局很流行,因为移动端的屏幕很小,所以你不希望使用大部分界面来显示一个有用的内容而是用消息面板或者菜单代替。

Our finished example will look like this:

我们完工后的例子长这样:

Note: You can see the finished example running live at hidden-info-panel.html (source code). Check it out to get an idea of what you will be building in this section of the article.

笔记:你可以点击蓝字预览完成后的效果,仔细看看哪些部分是你在这篇文章里你要制作的。

As a starting point, make a local copy of hidden-info-panel-start.html from our Github repo. This doesn't follow on from the previous example, so a fresh start file is required. Let's have a look at the HTML in the file:

在一开始,老规矩在我们的Githib代码仓库拷贝hideen-info-panel-start.html。这个例子并没有用先前的例子,所以我们需要一个新的开始文件。让我们来仔细观察一下这个HTML文件:

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

To start with here we've got a <label> element and an <input> element — <label> elements are normally used to associate a text label with a form element for accessibility purposes (allowing a screen user to see what description goes with what form element). Here it is associated with the <input> checkbox using the for and id attributes.

//label 的 for属性规定label属性绑定到哪个表单元素。

开始,我们看到了一个label 元素和input元素——<label>元素普遍用来联系文字标签和表单,目的是能更好的理解表单(允许用户查看表单元素的描述)。这里通过for属性绑定id到了<input>标签的checkbox元素。

 

Note: We've put a special question mark character into our HTML to act as our info icon — this represents the button that will be pressed to show/hide the panel.

笔记:我们已经设置了一个特殊的问题标记特性到我们的HTML中,来当作我们的信息图标——这代表着这个按钮将可以按下显示或隐藏面板。

Here we are going to use these elements for a slightly different purpose — another useful side effect of <label> elements is that you can click a checkbox's label to check the checkbox, as well as just the checkbox itself. This has led to the well-known checkbox hack, which provides a JavaScript-free way of controlling an element by toggling a button. The element we'll be controlling is the <aside> element that follows the other two (we've left its contents out of the above code listing for brevity).

In the below sections we'll explain how this all works.

现在我们使用这些元素在稍稍不同的目的——另一个<label>标签有用的副作用使你能通过点击checkbox的label标签来选择这个checkbox,就好像点击了这个checkbox自己一样。这就会实现有名的checkbox hack 技术,可以提供无JS的方法来控制一个元素,通过一个按钮的联系。我们将控制的元素使aside元素,通过其他两个(为了简洁起见,我们已将其内容从上述代码列表中删除)。

在下面的部分我们将解释这一切如何运作。

Styling the form elements

设置表单元素样式

First let's deal with the form elements — add the following CSS in between your <style> tags:

首先让我们处理表单元素 - 在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;
}

The first rule styles the <label>; here we've:

  • Set a large font-size to make the icon nice and big.
  • Set position absolute on it, and used top and right to position it nicely in the top-right corner.
  • Set a z-index of 1 on it — this is so that when the info panel is styled and shown, it doesn't cover up the icon; instead the icon will sit on top of it so it can be pressed again to hide the info pane.
  • Used the cursor property to change the mouse cursor when it is hovering over the icon to a hand pointer (like the one you see when links are hovered over), as an extra visual clue to users that the icon does something interesting.

The second rule sets position absolute on the actual checkbox <input> element, and hides it off the top of the screen. We don't actually want to see this on our UI.

第一条label样式的规则,我们有:

设置字体大小使图标更美观。

设置为绝对定位,使用top属性和right属性来让他能很合适的位于右上角。

设置z-index属性为1——因此当信息面板被赋予样式和显示的时候,不会覆盖我们的图标;相反图标依然会位于最上层能够再次被按下来隐藏信息平板。

使用cursor属性来说改变鼠标的指针,当鼠标悬浮在图标上面的时候变成一个手形指针(就像你看到的当悬浮在链接上一样),作为一个额外的可视化线索告诉用户这个图标可以做一些有趣的事情。

第二条规则是在实际的<input>checkbox元素上设置绝对定位属性,并隐藏在顶部的上面,我们并不希望在我们的用户界面里看到她。

Styling the panel

设置面板的样式

Now it's time to style the actual sliding panel itself. Add the following rule to the bottom of your CSS:

现在是时候为实际的滑动面板设计风格了。在你的css底部添加下列规则:

aside {
  background-color: #a60000;
  color: white;
  width: 340px;
  height: 98%;
  padding: 10px 1%;
  position: fixed;
  top: 0;
  right: -370px;
  transition: 0.6s all;
}

There's a lot going on here — let's discuss it bit by bit:

  • First, we set some simple background-color and color on the info box.
  • Next, we set a fixed width on the panel, and make its height the entire height of the browser viewport.
  • We also include some padding to make up the width/height to the total value we want (this was necessary as we've not set box-sizing: border-box; on this example).
  • Next we set position: fixed; on the panel so it will always appear in the same place, even if the page has content to scroll. We glue it to the top of the viewport, and set it so that by default it is offscreen to the right.
  • Finally, we set a transition on the element. Transitions are an interesting feature that allow you to make changes between states happen smoothly, rather than just going "on", "off" abruptly. In this case we are intending to make the panel slide smoothly onscreen when the checkbox is checked. (Or to put it another way, when the question mark icon is clicked — remember, clicking the <label> will check the associated checkbox! We told you it was a hack.) You will learn a lot more about...

这里有很多项——让我们一点一点讨论:

首先,我们在信息盒子中设置了一些简单的背景颜色和颜色。

然后,我们在面板上设置一个固定的宽度,让她的高度充满整个浏览器窗口的高度。

我们同样包括一些内边距来组成我们小那个要的高度和宽度总体的值(如果我们没有设置box-sizing:border-box来说的话是很必要的,正如这个例子)

然后,我们设置面板的定位为fixed,即使页面的内容在滚动,也总是显示在同一个位置。我们把设置top属性让窗口粘在顶部,然后设置默认情况下远离屏幕,设置right属性使其位于屏幕的右边。

最后我们设置transition属性,Transitions是一个有意思的特性,允许你在状态改变的时候平滑的过渡,而不是粗暴的“变”或“还原”。在这个例子中我们尝试在checkbox被选中时让面板平滑的滑动到屏幕上。(或者换句话说,当问题标记图标被点击以后——记住,点击<label>标签也会选择相对应的checkbox!我们已经告诉你这是一种hack了)你将会学到更多。。。

 

Setting the checked state

设置选择后的状态

There is one final bit of CSS to add — put the following at the bottom of your CSS:

这是最后的css添加——把这些放到你的css底部:

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

The selector is pretty complex here — we are selecting the <aside> element adjacent to the <input> element, but only when it is checked (note the use of the :checked pseudo-class to achieve this). When this is the case, we are setting the right property of the <aside> to 0px, which causes the panel to appear on the screen again (smoothly due to the transition). Clicking the label again unchecks the checkbox, which hides the panel again.

这里的选择器是复杂的——我们选择<input>元素邻接的<aside>元素,但是仅仅在他被选择(请注意使用checked伪类来实现此目的),在这种情况下,我们将right属性设置为0px,会造成面板再次出现在屏幕上(由于过渡属性会平滑的出现)。再一次点击这个标签会取消选中checkbox,面板将会跟着再一次消失。

So there you have it — a rather clever JavaScript-free way to create a toggling button effect. This will work in IE9 and above (the smooth transition will work in IE10 and above.) This effect does have some concerns — this is a bit of an abuse of form elements (they weren't intended for this purpose), and the effect is not great in terms of accessibilty — the label is not focusable by default, and the non-semantic use of the form elements could cause issues with screenreaders. JavaScript and a link or button might be more appropriate, but it is still fun to experiment with.

所以你有它 ——一个相当巧妙的避免使用JavaScript来创建一个切换按钮效果方式。 这将在IE9及以上版本中起作用(平滑过渡将在IE10及更高版本中起作用)。这种效果确实有一些问题 ——这是有点滥用表单元素(它们不是为了这个目的),并且在可访问性方面效果不是很好 - 标签在默认情况下不可聚焦,并且表单元素的非语义使用可能会导致屏幕朗读器出现问题。 JavaScript和链接或按钮可能更合适,但这样的实验仍然很有趣。

Summary

总结

So that rounds off our look at positioning — by now, you should have an idea of how the basic mechanics work,as well as understanding how to start applying these to building some interesting UI features. Don't worry if you didn't get this all immediately — positioning is a fairly advanced topic, and you can always work through the articles again to aid your understanding. The next subject we'll turn to is Flexbox.

这样我们就完成了我们对定位属性的观看——现在,你应该对基本技能的工作原理有了基本的了解,同样理解了怎样引用这些知识去构建一些有趣的用户界面功能,不要由于你还未完全理解所有的知识而担心——定位是一个相当高级的话题,你可以随时读这篇文章来帮助你的理解。下一个主题是Flexbox.

文档标签和贡献者