CSS layout (3) floating, positioning, multi-column layout

6. Floating

最初用于在文本块内浮动图像, the float attribute has become one of the most commonly used tools for creating multi-column layouts on web pages . With the advent of flexbox and grid, it is now back to its original purpose, as this article explains.

6.1 Floating background

The float attribute was introduced to allow web developers to implement layouts that contain images floating within a column of text, with the text wrapping to the left or right of it. Just like what you see on the pages of newspapers.

But web developers soon realized that you could float anything, not just images, so the use of floats expanded, for example, to create interesting layout effects like drop caps .

Floats are often used to create entire website layouts that contain multiple columns of information that are floated so they are next to each other (the default behavior is for columns to be arranged below one another in the same order as they appear in the source). There are newer and better layout techniques available. Using floating point numbers in this way should be considered a legacy technology .

In this article, we only focus on the correct use of floats.

6.2 Example of float

Let's explore the use of floating point numbers. We'll start with an example that involves floating a block of text around an element. You can create a new index.htmlfile on your computer, fill it with an HTML template , and insert the code below in the appropriate places. At the end of this section you can see an example demonstrating the final code.

First, we'll start with some HTML. Add the following code to your HTML body, removing anything that was previously in it:

<h1>Float example</h1>

<div class="box">Float</div>

<p>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus aliquam
  dolor, eu lacinia lorem placerat vulputate. Duis felis orci, pulvinar id metus
  ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at ultricies tellus
  laoreet sit amet.
</p>

<p>
  Sed auctor cursus massa at porta. Integer ligula ipsum, tristique sit amet
  orci vel, viverra egestas ligula. Curabitur vehicula tellus neque, ac ornare
  ex malesuada et. In vitae convallis lacus. Aliquam erat volutpat. Suspendisse
  ac imperdiet turpis. Aenean finibus sollicitudin eros pharetra congue. Duis
  ornare egestas augue ut luctus. Proin blandit quam nec lacus varius commodo et
  a urna. Ut id ornare felis, eget fermentum sapien.
</p>

<p>
  Nam vulputate diam nec tempor bibendum. Donec luctus augue eget malesuada
  ultrices. Phasellus turpis est, posuere sit amet dapibus ut, facilisis sed
  est. Nam id risus quis ante semper consectetur eget aliquam lorem. Vivamus
  tristique elit dolor, sed pretium metus suscipit vel. Mauris ultricies lectus
  sed lobortis finibus. Vivamus eu urna eget velit cursus viverra quis
  vestibulum sem. Aliquam tincidunt eget purus in interdum. Cum sociis natoque
  penatibus et magnis dis parturient montes, nascetur ridiculus mus.
</p>

Now apply the following CSS to your HTML (either using <style>an element or <link>to a separate .cssfile - your choice):

body {
    
    
  width: 90%;
  max-width: 900px;
  margin: 0 auto;
  font:
    0.9em/1.2 Arial,
    Helvetica,
    sans-serif;
}

.box {
    
    
  width: 150px;
  height: 100px;
  border-radius: 5px;
  background-color: rgb(207, 232, 220);
  padding: 1em;
}

If you save and refresh, you'll see something very similar to what you'd expect: the box above the text, in the normal flow.

6.2.1 Floating box

To float the box, add the float and margin-right properties to .boxthe rule:

.box {
    
    
  float: left;
  margin-right: 15px;
  width: 150px;
  height: 100px;
  border-radius: 5px;
  background-color: rgb(207, 232, 220);
  padding: 1em;
}

Now, if you save and refresh, you'll see something like this:
Insert image description here
Let's think about how floats work. The set floatelement (in this case, <div>the element) is taken out of the document's normal layout flow and pasted to the left of its parent container (in this case <body>). In the normal layout flow, any content behind the floated element will now wrap around it, filling the space to its right, up to the top of the floated element. There it will stop.

Floating content to the right has the exact same effect, but in reverse : the floated element will be attached to the right, while the content will wrap around it to the left. Try floatchanging the value to and replacing rightthe last rule set with and see what the result is.margin-rightmargin-left

6.2.2 Visualize floating effects

While we can add margins to floats to move text away from floats, we cannot add margins to text to move them away from floats . This is because the floated element is taken out of the normal flow, and the box for subsequent items actually runs behind the float. You can see this by making some changes to the example.

Add a class in the first paragraph of text special, immediately after the float, and then add the following rules in CSS. This will give our following paragraph a background color.

.special {
    
    
  background-color: rgb(148, 255, 172);
  padding: 10px;
  color: purple;
}

To make the effect easier to see, change the float margin-rightto marginso that there is space around the float. You can see that the background of the paragraph runs directly beneath the floated box, as shown in the example below.

Insert image description here
The line box of the element below us is shortened so that the text can run around the float, but since the float is removed from normal flow, the box around the paragraph remains full width.

6.3 Clear float

We've seen that floats are removed from the normal flow and other elements will appear next to them. If we want to prevent subsequent elements from moving up, we need to clear it; this is achieved via the clear property.

In the HTML from the previous example, add a clearedclass to the second paragraph below the float. Then add the following to the CSS:

.cleared {
    
    
  clear: left;
}

Insert image description here
You should see that the second paragraph now clears the floated element and no longer appears next to it. clearThe property accepts the following values:

  • left:Clear items floating to the left.
  • right:Clear items floating to the right.
  • both:Clear the left or right floating items.

6.4 Clear boxes around floating elements

Now you know how to clear content behind a floated element, but let's see what happens if you have a tall float and a short paragraph, with a box around both elements.

6.4.1 Problem

Change the document so that the first paragraph and the float box are wrapped with <div>a union, which should <div>have a wrapperclass.

<div class="wrapper">
  <div class="box">Float1</div>

  <p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus
    aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci,
    pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc, at
    ultricies tellus laoreet sit amet.
  </p>
</div>

Additionally, delete the original .clearedclass:

.cleared {
    
    
  clear: left;
}

You'll see that, just like our example of adding a background color to the paragraph, the background color runs behind the float.
Insert image description here
Again, this is because the float has been taken out of the normal flow . You might expect that by wrapping a floated box and the text surrounding the floated first paragraph, subsequent content will clear from the box . But as shown above, this is not the case. To solve this problem, the standard approach is to displaycreate a block formatting context (BFC) using attributes.

6.4.2 display: flow-root

To solve this problem, you can use displaythe value of the attribute flow-root. It exists simply to create BFCs without using hacks - there are no unintended consequences when you use it.

.wrapper {
    
    
  background-color: rgb(148, 255, 172);
  padding: 10px;
  color: purple;
  display: flow-root;
}

Insert image description here

6.5 Testing

Test your skills: float

7. Positioning

Positioning ( Positioning) allows you to take elements out of the normal document flow and make them behave differently , for example, by being placed on top of one another or always staying in the same position in the browser viewport. This article explains the different position values ​​and how to use them.

We want you to do the following exercises on your local computer. If possible, grab a copy of 0_basic-flow.html from our GitHub repo ( source code here) and use that as a starting point.

7.1 Positioning introduction

定位允许我们通过覆盖正常的文档流来产生有趣的结果. What if you want to slightly change the position of some boxes so that they deviate from the default flow position and give it a slightly quirky feel? Positioning is your tool. Or what if you want to create a UI element that floats on top of the rest of the page, or that is always in the same place in the browser window no matter how much the page is scrolled? Positioning makes this kind of layout work possible .

There are many different types of positioning that can be used for HTML elements. To activate a specific type of positioning on an element, we use the position attribute.

7.2 Static positioning

Static positioning is the default for every element. It means "Place the element in its normal position in the document flow - nothing special here."

<p>To see this (and set up an example for future chapters), first add a class to the second one in the HTML positioned :

<p class="positioned"></p>

Now add the following rules at the bottom of your CSS:

.positioned {
    
    
  position: static;
  background: yellow;
}

If you save and refresh, you won't see any difference other than the background color of the second paragraph updating. That's fine - as we said before, static positioning is the default behavior!

NOTE: You can see this example now at 1_static-positioning.html (see source code ).

7.3 Relative positioning

Relative positioning is the first position type we'll look at. This is very similar to static positioning, except that once the positioned element has taken its place in the normal flow, you can modify its final position, including making it overlap other elements on the page . Go ahead and update the location declaration in your code:

position: relative;

If you save and refresh at this stage, you won't see any changes to the results. So how do you modify the position of an element? You need to use the top , bottom , left and right properties, which we will explain in the next section.

top、bottom、left 和 right

top, bottom, left and right are used with position to specify the exact position to which the positioned element will be moved. To try it out, add the following declaration to the .positioning rule in your CSS:

top: 30px;
left: 30px;

Note: The values ​​of these properties can be in any unit you reasonably expect: pixels, mm, rems, %, etc.

If you save and refresh now, you'll get something like this:
Insert image description here
Cool, isn't it? Well, that's probably not what you want. If we specified topsum left, why would it move to the bottom and right? This seems counterintuitive. You need to think of it as having an invisible force pushing on a specific side of the box, causing it to move in the opposite direction. So for example, if you specify top: 30px;, it's as if a force will push the top of the box, making it move 30px down.

NOTE: You can see this example at 2_relative-positioning.html (see source code).

7.4 Absolute positioning

Absolute positioning brings completely different results.

Set position: absolute

Let's try changing the location declaration in the code as follows:

position: absolute;

If you save and refresh now, you should see something like this:
Insert image description here
First, notice that the gap in the document flow where the positioned element should have been is no longer there —the first and third elements are closed together, as if it no longer exists !In a way, this is true. Absolutely positioned elements are not in the normal document flow . Instead, it has its own layer, separate from everything else. This is very useful: it means we can create independent UI features without interfering with the layout of other elements on the page. For example, pop-up information boxes, control menus, scroll panels, UI features that can be dragged and dropped anywhere on the page, etc.

Second, notice that the position of the element has changed . 这是因为 top、bottom、left和 right在绝对定位时的行为方式不同. Rather than positioning elements based on their relative position in the normal document flow, they specify the distance between the element and each edge that contains the element . So in this example, we are saying that the absolutely positioned element should be positioned 30px from the top and 30px from the left of the "containing element". (In this case, the "containing element" is the initial containing block. See the section below for more information)

Note: You can use top, bottom, left and right to resize the element if needed. top: 0; bottom: 0; left: 0; right: 0;Try setting the and on the positioned element margin: 0;and see what happens! Then put it back...

Note: Yes, margins still affect positioned elements. However, the margins do not collapse.

NOTE: You can see this example at 3_absolute-positioning.html (see source code).

Positioning context

Which element is the "containing element ( containing element)" of an absolutely positioned element ? This depends largely on the attributes of the ancestor elements of the positioned element position(see Identifying Containing Blocks ).

If no ancestor element explicitly defines its position attribute, then all ancestor elements will have a static position by default . The result of this is that the absolutely positioned element will be contained within the initial containing block ( initial containing block). The initial containing block has the dimensions of the viewport and is also the containing <html>block . In other words, an absolutely positioned element will appear <html>outside of the element and positioned relative to the initial viewport.

The positioned element is nested within the HTML source <body>, but in the final layout it is 30px from the top and left edge of the page. We can change the positioning context ( positioning context), that is, which element an absolutely positioned element is positioned relative to . This is achieved by setting the positioning on one of the element's ancestors: one of the elements it is nested in (you can't position it relative to an element it is not nested in). To see this, add the following declaration to your bodyrule:

position: relative;

This should result in the following:
Insert image description here
the positioned element is now relative to <body>the element.

Note: You can see an example now in 4_positioning-context.html (see source code).

Introducing z-index

All this absolute positioning is interesting, but there's another feature we haven't considered yet. When elements start to overlap, what determines which elements appear above other elements and which elements appear below others ? In the example we've seen so far, we only have one positioned element in the positioning context, and it appears At the top, because positioned elements win out over non-positioned elements. What if there is more than one?

Try adding the following to your CSS so that the first paragraph is fully positioned as well:

p:nth-of-type(1) {
    
    
  position: absolute;
  background: lime;
  top: 10px;
  right: 30px;
}

At this point, you'll see that the first paragraph is painted lime gray, moved out of the document flow, and positioned a little higher than its original position. It is also stacked underneath the two overlapping original .positionedparagraphs. This is because .positionedthe paragraph is the second paragraph in the source order, and positioned elements later in the source order trump earlier positioned elements in the source order.

Can you change the stacking order? Yes, you can, by using the z-index property . “z-index”是对z轴的引用. You may remember from previous points in the course that we discussed web pages using horizontal (x-axis) and vertical (y-axis) coordinates to work out positioning things like background images and drop shadow offsets. For languages ​​that run from left to right, (0,0) is in the upper left corner of the page (or element), and the x- and y-axes run to the right and down the page.

Web pages also have a z-axis: an imaginary line from the surface of the screen to your face (or whatever you want to see in front of the screen). z-indexThe value affects the position of positioned elements on that axis; positive values ​​move them up in the stack, negative values ​​move them down in the stack. By default, positioned elements z-indexare autopositioned with a value of 0.

To change the stacking order, try p:nth-of-type(1)adding the following statement to the rule:

z-index: 1;

You should now see the lime segment at the top:
Insert image description here
note that z-indexonly unitless index values ​​are accepted ; you can't specify that you want an element to be 23 pixels on the z-axis - that won't work. Higher values ​​will be higher than lower values, depending on what value you use. Using a value of 2 or 3 will have the same effect as 300 or 40000.

NOTE: You can see an example at 5_z-index.html (see source code)

7.5 Fixed positioning

Now let's look at fixed positioning. This is exactly the same as absolute positioning, with one key difference:尽管绝对定位在相对于其最接近的定位祖先(初始包含块如果没有一个)的位置上修复了一个元素,但固定定位(fixed positioning)通常会修复相对于viewport可见部分的元素 . (The exception occurs if one of the element's ancestors is a fixed block because its transform property has a nonevalue other than a value.) This means you can create useful UI items that are fixed, such as persistent navigation menus. , it is visible no matter how much the page is scrolled.

Let's use a simple example to illustrate what we mean. p:nth-of-type(1)First, remove the existing and rules from the CSS .positioned.

Now update bodythe rule to remove position: relative;the declaration and add a fixed height, like this:

body {
    
    
  width: 500px;
  height: 1400px;
  margin: 0 auto;
}

Now we have to take h1the element position: fixed;and place it on top of the viewport. Add the following rules to your CSS:

h1 {
    
    
  position: fixed;
  top: 0;
  width: 500px;
  margin-top: 0;
  background: white;
  padding: 10px;
}

top: 0;Need to make it stick to the top of the screen. We give the header the same width as the content column, then a white background and some padding and margins so the content can't be seen underneath it.

If you save and refresh, you'll see a funny little effect of the header staying fixed - the content seems to scroll underneath it and disappear . But please note that some content was originally edited under the title. This is because the positioned heading no longer appears in the document flow, so the rest of the content moves to the top. We can improve this by moving these paragraphs a bit. We can do this by putting some caps on the first paragraph. Join now:

p:nth-of-type(1) {
    
    
  margin-top: 60px;
}

7.6 Sticky positioning

There is another position value available, calledposition: sticky , which is a little newer than the other position values. This is basically a mix of relative position and fixed position. It allows a positioned element to behave like it's relatively positioned until it is scrolled to a specific threshold (e.g. 10px from the top of the viewport), after which it becomes fixed.

basic example

For example, you can use sticky positioning so that the navigation bar scrolls with the page until it reaches a certain point and then sticks to the top of the page.

.positioned {
    
    
  position: sticky;
  top: 30px;
  left: 30px;
}

rolling index

position: stickyAn interesting and common use of is to create a scrolling index page where different headings stick to the top of the page as you reach it . The markup for such an example might look like this:

<h1>Sticky positioning</h1>

<dl>
  <dt>A</dt>
  <dd>Apple</dd>
  <dd>Ant</dd>
  <dd>Altimeter</dd>
  <dd>Airplane</dd>
  <dt>B</dt>
  <dd>Bird</dd>
  <dd>Buzzard</dd>
  <dd>Bee</dd>
  <dd>Banana</dd>
  <dd>Beanstalk</dd>
  <dt>C</dt>
  <dd>Calculator</dd>
  <dd>Cane</dd>
  <dd>Camera</dd>
  <dd>Camel</dd>
  <dt>D</dt>
  <dd>Duck</dd>
  <dd>Dime</dd>
  <dd>Dipstick</dd>
  <dd>Drone</dd>
  <dt>E</dt>
  <dd>Egg</dd>
  <dd>Elephant</dd>
  <dd>Egret</dd>
</dl>

The CSS might look like this. In normal flow, <dt>the element will scroll with the content. When we position: stickyadd to <dt>the element and topset the value 0to , supporting browsers will stick the title to the top of the viewport when it reaches that position. Each subsequent title will replace the previous one as it scrolls up to that position.

dt {
    
    
  background-color: black;
  color: white;
  padding: 10px;
  position: sticky;
  top: 0;
  left: 0;
  margin: 1em 0;
}

A sticky element has a "scrolling mechanism" relative to its nearest ancestor, which is determined by its ancestor's position property.

7.7 Testing

Test your skills: Positioning

8. Multi-column layout

Multi-column layout specifications give you a way to lay out your content in columns, like you would see in a newspaper . This article explains how to use this feature.

8.1 A basic example

Let's explore how to use multi-column layout - commonly known asmulticol . You can download the multicol starting point file and add the CSS to the appropriate location. At the bottom of this section you can see an example of what the final code should look like.

three column layout

Our starting file contains some very simple HTML: a containerwrapper with a class that contains a heading and some paragraphs.

The one with containerthe class <div>will be our multicol container. We enable multicol by using one of two properties: column-count or column-width . column-countThe property takes a number as its value and creates that number of columns. If you add the following CSS to your stylesheet and reload the page, you will get three columns:

.container {
    
    
  column-count: 3;
}

The columns you create have flexible widths - the browser figures out how much space to allocate to each column.
Insert image description here

Set column-width

Change your CSS to use column width as follows:

.container {
    
    
  column-width: 200px;
}

The browser will now give you as many columns as you specify; any remaining space will then be shared between existing columns . This means that you won't get the specified width unless your container is divisible by the specified width.

Insert image description here

8.2 Stylized columns

Columns created by multicol cannot be styled individually . There is no way to make one column larger than the others, nor to change the background or text color of an individual column. There are two ways to change how columns are displayed:

  • Use column-gap to change the size of the space between columns.
  • Use column-rule to add rules between columns.

Using the example above, column-gapchange the size of the spacing by adding properties. You can use different values ​​- the property accepts any length unit.

Now column-ruleadd a rule between columns. Similar to the border properties you encountered in previous lessons , column-rule is shorthand for column-rule-color , column-rule-style , and column-rule-widthborder and accepts the same values ​​as column-rule-color.

.container {
    
    
  column-count: 3;
  column-gap: 20px;
  column-rule: 4px dotted rgb(79, 185, 227);
}

Try adding different styles and colors of rules.
Insert image description here

8.3 Crossing columns

You can make elements span all columns. In this case, the content breaks where the generated element is introduced, then continues below the element, creating a new set of columns. To make the element span all columns, specify a value of all for the column-span attribute.

Note: It is not possible to make an element span only some columns. This property can only have values ​​of none(default) or all.

Insert image description here

8.4 Columns and content fragments

The content of multi-column layout is split. It essentially behaves the same way content in page media behaves, such as when you print a web page. When you convert content into a multi-column container, it is split into columns. In order for the content to do this, it must be split ( break).

split box

Sometimes this schism occurs where it results in a poor reading experience . In the example below, I'm using multicolto lay out a series of boxes, each with a title and some text. If the column is split between title and text, title and text will be separated.

<div class="container">
  <div class="card">
    <h2>I am the heading</h2>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus
      aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci,
      pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc,
      at ultricies tellus laoreet sit amet. Sed auctor cursus massa at porta.
      Integer ligula ipsum, tristique sit amet orci vel, viverra egestas ligula.
    </p>
  </div>

  <div class="card">
    <h2>I am the heading</h2>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus
      aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci,
      pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc,
      at ultricies tellus laoreet sit amet. Sed auctor cursus massa at porta.
      Integer ligula ipsum, tristique sit amet orci vel, viverra egestas ligula.
    </p>
  </div>

  <div class="card">
    <h2>I am the heading</h2>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus
      aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci,
      pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc,
      at ultricies tellus laoreet sit amet. Sed auctor cursus massa at porta.
      Integer ligula ipsum, tristique sit amet orci vel, viverra egestas ligula.
    </p>
  </div>
  <div class="card">
    <h2>I am the heading</h2>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus
      aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci,
      pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc,
      at ultricies tellus laoreet sit amet. Sed auctor cursus massa at porta.
      Integer ligula ipsum, tristique sit amet orci vel, viverra egestas ligula.
    </p>
  </div>

  <div class="card">
    <h2>I am the heading</h2>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus
      aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci,
      pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc,
      at ultricies tellus laoreet sit amet. Sed auctor cursus massa at porta.
      Integer ligula ipsum, tristique sit amet orci vel, viverra egestas ligula.
    </p>
  </div>

  <div class="card">
    <h2>I am the heading</h2>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus
      aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci,
      pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc,
      at ultricies tellus laoreet sit amet. Sed auctor cursus massa at porta.
      Integer ligula ipsum, tristique sit amet orci vel, viverra egestas ligula.
    </p>
  </div>

  <div class="card">
    <h2>I am the heading</h2>
    <p>
      Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla luctus
      aliquam dolor, eu lacinia lorem placerat vulputate. Duis felis orci,
      pulvinar id metus ut, rutrum luctus orci. Cras porttitor imperdiet nunc,
      at ultricies tellus laoreet sit amet. Sed auctor cursus massa at porta.
      Integer ligula ipsum, tristique sit amet orci vel, viverra egestas ligula.
    </p>
  </div>
</div>
.container {
    
    
  column-width: 250px;
  column-gap: 20px;
}

.card {
    
    
  background-color: rgb(207, 232, 220);
  border: 2px solid rgb(79, 185, 227);
  padding: 10px;
  margin: 0 0 1em 0;
}

Insert image description here

Set break-inside

To control this behavior we can use properties in the CSS fragment specification . This specification provides us with properties to control content segmentation in multicol and paginated media. For example, by .cardadding the attribute break-inside to the rule with a value of avoid. This is a container for the title and text, so we don't want it to fragment.

.card {
    
    
  break-inside: avoid;
  background-color: rgb(207, 232, 220);
  border: 2px solid rgb(79, 185, 227);
  padding: 10px;
  margin: 0 0 1em 0;
}

Insert image description here

8.5 Testing

Test your skills: Multicol

Guess you like

Origin blog.csdn.net/chinusyan/article/details/132838571