🎜*
🎜🎜Wildcard-Selektor🎜Alle Typen tag 🎜🎜2🎜🎜√🎜🎜🎜🎜Level Selector
Selector |
alias |
Beschreibung |
Version |
Häufig verwendet |
elemP elemC elemP elemC
|
后代选择器 |
元素的后代元素
|
1 |
√ |
elemP>elemC |
子代选择器 |
元素的子代元素
|
2 |
√ |
elem1+elem2 |
相邻同胞选择器 |
元素相邻的同胞元素
|
2 |
√ |
elem1~elem2 |
通用同胞选择器 |
元素后面的同胞元素
|
3 |
√ |
集合选择器
选择器 |
别名 |
说明 |
版本 |
常用 |
elem1,elem2 |
并集选择器 |
多个指定的元素
|
1 |
√ |
elem.class |
交集选择器 |
指定类名的元素
|
1 |
√ |
条件选择器
选择器 |
说明 |
版本 |
常用 |
:lang |
指定标记语言的元素
|
2 |
× |
:dir() |
指定编写方向的元素
|
4 |
× |
:has |
包含指定元素的元素
|
4 |
× |
:is |
指定条件的元素
|
4 |
× |
:not |
非指定条件的元素
|
4 |
√ |
:where |
指定条件的元素
|
4 |
× |
:scope |
指定元素 作为参考点 |
4 |
× |
:any-link |
所有包含href 的链接元素
|
4 |
× |
:local-link |
所有包含href 且属于绝对地址的链接元素 |
Selektor code><td align="center"> </td>
<td>Das <code>nachkommende Element des Elements
1 |
√
🎜🎜elemP>elemC 🎜🎜Kinderselektor 🎜 |
Die untergeordneten Elemente des Elements 🎜🎜2🎜🎜√🎜🎜🎜🎜elem1+elem2 🎜🎜Angrenzende Geschwisterselektor 🎜 |
Benachbarte sibling elements 🎜🎜2🎜🎜√🎜🎜🎜🎜elem1~elem2 🎜🎜Universeller Geschwisterselektor 🎜 |
Sibling Element nach dem Element 🎜🎜 Häufig verwendet 🎜🎜🎜🎜🎜🎜elem1,elem2 🎜🎜Union-Selektor 🎜 |
Mehrere angegebene Elemente🎜🎜1🎜 🎜√🎜🎜🎜🎜<code>elem.class 🎜🎜Intersection Selector 🎜 |
Element, das den Klassennamen angibt 🎜🎜1🎜🎜√ 🎜🎜🎜🎜🎜🎜Bedingter Selektor🎜🎜🎜🎜🎜🎜Selektor🎜🎜Beschreibung🎜🎜Version🎜🎜Häufig verwendet🎜🎜🎜 🎜🎜🎜:lang 🎜 |
Markup-Sprache angebenElement🎜🎜2🎜🎜×🎜🎜🎜🎜:dir() 🎜 |
Element, das die Schreibrichtung angibt 🎜🎜4🎜🎜× 🎜🎜🎜🎜:has 🎜 |
Das element , das das angegebene Element enthält🎜🎜4🎜🎜×🎜🎜🎜🎜: ist 🎜Elemente, die Bedingungen angeben 🎜🎜4🎜🎜×🎜🎜🎜🎜:nicht 🎜 |
Elemente, die dies nicht tun Bedingungen angeben 🎜🎜 4🎜🎜√🎜🎜🎜🎜:where 🎜 |
Element, das Bedingungen angibt 🎜🎜4🎜🎜×🎜🎜🎜🎜 :scope 🎜 |
Geben Sie element als Referenzpunkt an🎜🎜4🎜🎜×🎜🎜🎜🎜:any-link 🎜 |
Alle, die das link-Element von href enthalten🎜🎜4🎜🎜×🎜🎜🎜🎜:local-link 🎜 |
alle enthalten href und sind absolute Link-Elemente der Adresse 🎜🎜4🎜🎜×🎜🎜🎜🎜Statusauswahl
Auswahl |
Beschreibung |
Version |
Häufig verwendet |
:aktiv :active
|
鼠标激活的元素
|
1 |
× |
:hover |
鼠标悬浮的元素
|
1 |
√ |
:link |
未访问的链接元素
|
1 |
× |
:visited |
已访问的链接元素
|
1 |
× |
:target |
当前锚点的元素
|
3 |
× |
:focus |
输入聚焦的表单元素
|
2 |
√ |
:required |
输入必填的表单元素
|
3 |
√ |
:valid |
输入合法的表单元素
|
3 |
√ |
:invalid |
输入非法的表单元素
|
3 |
√ |
:in-range |
输入范围以内的表单元素
|
3 |
× |
:out-of-range |
输入范围以外的表单元素
|
3 |
× |
:checked |
选项选中的表单元素
|
3 |
√ |
:optional |
选项可选的表单元素
|
3 |
× |
:enabled |
事件启用的表单元素
|
3 |
× |
:disabled |
事件禁用的表单元素
|
3 |
√ |
:read-only |
只读的表单元素
|
3 |
× |
:read-write |
可读可写的表单元素
|
3 |
× |
:target-within |
内部锚点元素处于激活状态的元素
|
4 |
× |
:focus-within |
内部表单元素处于聚焦状态的元素
|
4 |
√ |
:focus-visible |
输入聚焦的表单元素
|
4 |
× |
:blank |
输入为空的表单元素
|
4 |
× |
:user-invalid |
输入合法的表单元素
|
4 |
× |
:indeterminate |
选项未定的表单元素
|
4 |
× |
:placeholder-shown |
占位显示的表单元素
|
4 |
√ |
:current() |
浏览中的元素
|
4 |
× |
:past() |
已浏览的元素
|
4 |
× |
:future() |
未浏览的元素
|
4 |
× |
:playing |
开始播放的媒体元素
|
4 |
× |
:paused |
暂停播放的媒体元素
|
Mausaktiviertes -Element |
1... /code> |
Unbesuchtes Link-Element
|
| 1
× 🎜🎜🎜:visited 🎜 |
Besuchtes Link-Element 🎜🎜1🎜🎜×🎜🎜🎜🎜:target 🎜 |
Das Element des aktuellen Ankers 🎜🎜3🎜🎜×🎜🎜🎜 🎜: Fokus 🎜 |
Eingabefokussiertes Formularelement 🎜🎜2🎜🎜√🎜🎜🎜🎜:erforderlich 🎜 |
Eingabe erforderliche Formularelemente 🎜🎜3🎜🎜√🎜🎜🎜🎜:valid 🎜 |
Geben Sie zulässige Formularelemente ein🎜🎜3 🎜🎜√🎜🎜🎜🎜:invalid 🎜 |
Geben Sie ein ungültiges Formularelement ein🎜🎜3🎜🎜√🎜🎜🎜🎜:in-range🎜<td>
<code> Formularelemente innerhalb des Eingabebereichs 🎜🎜3🎜🎜×🎜🎜🎜🎜:out-of-range 🎜 |
Außerhalb des Eingabebereichs Formularelement 🎜🎜3🎜🎜×🎜🎜🎜🎜:checked 🎜 |
Option ausgewählt Formularelement 🎜🎜3🎜🎜 √🎜🎜🎜🎜:optional 🎜 |
Optionales Formularelement 🎜🎜3🎜🎜×🎜🎜🎜🎜:aktiviert 🎜 |
Ereignisaktiviertes Formularelement🎜🎜3🎜🎜×🎜🎜🎜🎜<code>:disabled 🎜 | Event-disabled form element 🎜🎜3🎜🎜√🎜🎜🎜🎜:read-only 🎜 |
Read-only form element 🎜🎜3🎜🎜×🎜🎜🎜🎜:read-write 🎜 |
Lesbares und beschreibbares Formularelement 🎜🎜3🎜🎜×🎜🎜🎜🎜:target-within 🎜Das Element, in dem das interne Ankerelement aktiviert ist 🎜🎜4🎜🎜×🎜🎜🎜🎜:focus-within 🎜 |
Das interne Formularelement ist im Fokus element 🎜🎜4🎜🎜√ 🎜🎜🎜🎜:focus-visible 🎜 |
Geben Sie das fokussierte Formularelement ein 🎜🎜4🎜🎜 ×🎜🎜🎜🎜:blank 🎜 |
Eingabe ist leer Formularelement 🎜🎜4🎜🎜×🎜🎜🎜🎜:user-invalid code>🎜<td>Geben Sie ein zulässiges <code>Formularelement ein code>🎜🎜4🎜🎜×🎜🎜🎜🎜<code>:indeterminate 🎜 | Option unbestimmt Formularelement🎜🎜4🎜🎜×🎜🎜🎜🎜<code>: placeholder-shown 🎜 |
Formularelement angezeigt durch Platzhalter 🎜🎜4🎜🎜√🎜🎜🎜 🎜:current() 🎜 |
Element beim Durchsuchen 🎜🎜4🎜🎜×🎜🎜🎜🎜:past() 🎜Durchsuchtes element 🎜🎜4🎜🎜×🎜🎜 🎜🎜:future() 🎜 |
Unbrowsed element 🎜 🎜 4🎜🎜 /code>🎜 |
Wiedergabe anhalten media element 🎜 🎜4🎜🎜×🎜🎜🎜🎜Strukturauswahl
Selektor |
Beschreibung |
Version |
Häufig verwendet |
:root :root
|
文档的根元素
|
3 |
× |
:empty |
无子元素的元素
|
3 |
√ |
:nth-child(n) |
元素中指定顺序索引的元素
|
3 |
√ |
:nth-last-child(n) |
元素中指定逆序索引的元素
|
3 |
× |
:first-child |
元素中为首的元素
|
2 |
√ |
:last-child |
元素中为尾的元素
|
3 |
√ |
:only-child |
父元素仅有该元素的元素
|
3 |
√ |
:nth-of-type(n) |
标签中指定顺序索引的标签
|
3 |
√ |
:nth-last-of-type(n) |
标签中指定逆序索引的标签
|
3 |
× |
:first-of-type |
标签中为首的标签
|
3 |
√ |
:last-of-type |
标签中为尾标签
|
3 |
√ |
:only-of-type |
父元素仅有该标签的标签
|
3 |
√ |
属性选择器
选择器 |
说明 |
版本 |
常用 |
[attr] |
指定属性的元素
|
2 |
√ |
[attr=val] |
属性等于指定值的元素
|
2 |
√ |
[attr*=val] |
属性包含指定值的元素
|
3 |
√ |
[attr^=val] |
属性以指定值开头的元素
|
3 |
√ |
[attr$=val] |
属性以指定值结尾的元素
|
3 |
√ |
[attr~=val] |
属性包含指定值(完整单词)的元素 (不推荐使用) |
2 |
× |
[attr|=val] |
属性以指定值(完整单词)开头的元素 (不推荐使用) |
2 |
× |
伪元素
选择器 |
说明 |
版本 |
常用 |
::before |
在元素前插入的内容
|
2 |
√ |
::after |
在元素后插入的内容
|
2 |
√ |
::first-letter |
元素的首字母
|
1 |
× |
::first-line |
元素的首行
|
1 |
× |
::selection |
鼠标选中的元素
|
3 |
× |
::backdrop |
全屏模式的元素
|
4 |
× |
::placeholder |
表单元素的占位
|
Stammelement des Dokuments code> |
3 |
× |
:empty 🎜 |
Element ohne untergeordnete Elemente 🎜🎜3🎜🎜√🎜🎜🎜🎜 : nth-child(n) 🎜 |
Das Element mit dem angegebenen sequentiellen Index 🎜🎜3🎜🎜√🎜🎜🎜🎜:nth-last-child(n ) Das 🎜 |
-Element gibt den umgekehrten Reihenfolgeindex des element 🎜🎜3🎜🎜×🎜🎜🎜🎜:first-child 🎜 |
-Elements an Das führende element 🎜🎜2🎜🎜√🎜🎜🎜🎜:last-child 🎜 |
-Element ist das Schwanz-element 🎜🎜 3 🎜🎜√🎜🎜🎜🎜:only-child 🎜 |
Das übergeordnete Element hat nur das element dieses Elements🎜🎜3🎜🎜√🎜🎜🎜🎜:nth-of-type(n)🎜 |
-Tag, das den sequentiellen Index im Tag angibt 🎜🎜3🎜🎜√🎜🎜🎜🎜:nth- last-of-type(n) 🎜 |
-Tag, das den umgekehrten Index des -Tags 🎜🎜3🎜🎜×🎜🎜🎜🎜:first-of-type angibt 🎜 |
Das erste Tag im Tag 🎜🎜3🎜🎜√🎜🎜🎜🎜:last-of-type 🎜 |
Das letzte Tag im TagTag 🎜🎜3🎜🎜√🎜🎜🎜🎜:only-of-type 🎜 |
Das übergeordnete Element hat nur das tag dieses Tags🎜🎜 3🎜🎜√🎜🎜🎜🎜🎜🎜Attribute-Selektor🎜🎜🎜🎜🎜🎜Selector🎜🎜Beschreibung🎜🎜Version🎜🎜Häufig verwendet🎜🎜 🎜🎜🎜🎜<code>[attr] 🎜<td> <code>Element mit dem angegebenen Attribut 🎜🎜2🎜🎜√🎜🎜🎜🎜[attr=val] 🎜 |
Element mit dem Attribut gleich dem angegebenen Wert 🎜🎜2🎜🎜√🎜🎜🎜🎜<code>[attr*=val] 🎜 | Das Element, dessen Attribut den angegebenen Wert enthält🎜🎜3🎜🎜√🎜🎜🎜🎜 <code>[attr^=val] 🎜 |
Element, dessen Attribut mit dem angegebenen Wert beginnt 🎜🎜3🎜🎜 √🎜🎜🎜🎜[attr$=val] 🎜 |
Element, dessen Attribut mit dem angegebenen Wert endet 🎜🎜3🎜🎜√🎜🎜🎜🎜 [attr~=val] 🎜 |
Attribut Element , das den angegebenen Wert (vollständiges Wort) enthält (veraltet) 🎜🎜2🎜🎜×🎜🎜🎜🎜[attr| =val] 🎜 |
-Attribut mit Element , beginnend mit dem angegebenen Wert (vollständiges Wort) (veraltet) 🎜🎜2🎜🎜×🎜🎜🎜🎜🎜🎜Pseudoelement 🎜🎜🎜 🎜🎜🎜Selektor 🎜🎜 Beschreibung 🎜🎜 Version 🎜 🎜Häufig verwendet🎜🎜🎜🎜🎜🎜::before 🎜 |
Inhalt vor dem Element eingefügt 🎜🎜2🎜 🎜√🎜🎜🎜🎜:: after 🎜 |
content 🎜🎜2🎜🎜√🎜🎜🎜🎜::first-letter 🎜 |
element Anfangsbuchstabe 🎜🎜1🎜🎜×🎜🎜🎜🎜::first-line 🎜 |
Die erste Zeile 🎜🎜1🎜 des Elements 🎜×🎜🎜🎜🎜::selection 🎜 |
Das mit der Maus ausgewählte element 🎜🎜3🎜🎜×🎜🎜🎜🎜 ::backdrop 🎜 |
Vollbildmodus element 🎜🎜4🎜🎜×🎜🎜🎜🎜::placeholder 🎜 |
Form Element Platzhalter code>🎜🎜4🎜🎜√🎜🎜🎜🎜Techniken
Mit den oben genannten Vorkenntnissen folgen wir dem Autor, um zu erfahren, wie er verschiedene reine CSS-Entwicklungstechniken geschickt einsetzt, um einige allgemeine oder spezielle Layouts zu vervollständigen. Damit der Browser bestimmte Stile automatisch berechnen kann, muss box-sizing:border-box global festgelegt werden. Bitte führen Sie vor dem Codieren den reset.css. 常见或特殊的布局排版 吧。为了方便浏览器自动计算某些样式,需全局设置box-sizing:border-box ,编码前请引入笔者整理的reset.css。
主体布局
主体布局指在大部分情况下通用且具备统一特征的占位布局。掌握主体布局 是一个前端必不可少的技能,养成看设计图就能大概规划出整体布局的前提是必须熟悉这些主体布局 的特点与构造。
全屏布局
经典的全屏布局由顶部 、底部 和主体 三部分组成,其特点为三部分左右满屏拉伸 、顶部底部高度固定 和主体高度自适应 。该布局很常见,也是大部分Web应用主体的主流布局。通常使用<header></header> 、<footer></footer> 和<main></main> 三个标签语义化排版,<main></main> 内还可插入<aside></aside> 侧栏或其他语义化标签。
<div class="fullscreen-layout">
<header></header>
<main></main>
<footer></footer>
</div> position + left/right/top/bottom
三部分统一声明left:0 和right:0 将其左右满屏拉伸;顶部和底部分别声明top:0 和bottom:0 将其吸顶和吸底,并声明俩高度为固定值;将主体的top 和bottom 分别声明为顶部高度和底部高度。通过绝对定位的方式将三部分固定在特定位置,使其互不影响。 .fullscreen-layout {
position: relative;
width: 400px;
height: 400px;
header,
footer,
main {
position: absolute;
left: 0;
right: 0;
}
header {
top: 0;
height: 50px;
background-color: #f66;
}
footer {
bottom: 0;
height: 50px;
background-color: #66f;
}
main {
top: 50px;
bottom: 50px;
background-color: #3c9;
}
} flex
使用flex 实现会更简洁。display:flex 默认会令子节点横向排列,需声明flex-direction:column 改变子节点排列方向为纵向排列;顶部和底部高度固定,所以主体需声明flex:1 让高度自适应。 .fullscreen-layout {
display: flex;
flex-direction: column;
width: 400px;
height: 400px;
header {
height: 50px;
background-color: #f66;
}
footer {
height: 50px;
background-color: #66f;
}
main {
flex: 1;
background-color: #3c9;
}
} 若<main></main> 需表现成可滚动状态,千万不要声明overflow:auto 让容器自适应滚动,这样做有可能因为其他格式化上下文的影响而导致自适应滚动失效或产生其他未知效果。需在<main></main> 内插入一个<div>并声明如下。<pre class="brush:css;toolbar:false;">div {
overflow: hidden;
height: 100%;
}</pre><h6 data-id="heading-5"><strong>两列布局</strong></h6>
<p>经典的<strong>两列布局</strong>由<code>左右两列 组成,其特点为一列宽度固定 、另一列宽度自适应 和两列高度固定且相等 。以下以左列宽度固定和右列宽度自适应为例,反之同理。
<div class="two-column-layout">
<div class="left"></div>
<div class="right"></div>
</div> float + margin-left/right
左列声明float:left 和固定宽度,由于float 使节点脱流,右列需声明margin-left 为左列宽度,以保证两列不会重叠。 .two-column-layout {
width: 400px;
height: 400px;
.left {
float: left;
width: 100px;
height: 100%;
background-color: #f66;
}
.right {
margin-left: 100px;
height: 100%;
background-color: #66f;
}
} overflow + float
左列声明同上,右列声明overflow:hidden 使其形成BFC区域 与外界隔离。 .two-column-layout {
width: 400px;
height: 400px;
.left {
float: left;
width: 100px;
height: 100%;
background-color: #f66;
}
.right {
overflow: hidden;
height: 100%;
background-color: #66f;
}
} flex
使用flex 实现会更简洁。左列声明固定宽度,右列声明flex:1 自适应宽度。 .two-column-layout {
width: 400px;
height: 400px;
.left {
float: left;
width: 100px;
height: 100%;
background-color: #f66;
}
.right {
overflow: hidden;
height: 100%;
background-color: #66f;
}
} 三列布局
经典的三列布局由左中右三列 组成,其特点为连续两列宽度固定 、剩余一列宽度自适应 和三列高度固定且相等 。以下以左中列宽度固定和右列宽度自适应为例,反之同理。整体的实现原理与上述两列布局一致。
<div class="three-column-layout">
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
</div> 为了让右列宽度自适应计算,就不使用float + margin-left 的方式了,若使用margin-left
Hauptlayout
Hauptlayout bezieht sich auf das Platzhalterlayout, das üblich ist und in den meisten Situationen einheitliche Eigenschaften aufweist. Die Beherrschung des Hauptlayouts ist eine wesentliche Frontend-Fähigkeit. Um anhand von Entwurfszeichnungen einen groben Plan des Gesamtlayouts zu entwickeln, müssen Sie mit den Eigenschaften und der Struktur dieses Hauptlayouts . <blockquote>
<h6 data-id="heading-4"></h6>
<p>Vollbild-Layout</p>🎜Klassisches 🎜Vollbild-Layout🎜 besteht aus <code>oben , unten und Der Hauptkörper besteht aus drei Teilen und seine Eigenschaften sind die drei Teile sind auf den gesamten Bildschirm gestreckt , die Höhe oben und unten ist festgelegt code> und <code>die Höhe des Hauptkörpers ist adaptiv . Dieses Layout ist weit verbreitet und auch das Mainstream-Layout der meisten Webanwendungskörper. Normalerweise werden drei Tags <header></header> , <footer></footer> und <main></main> für den semantischen Schriftsatz verwendet, kann auch die Seitenleiste <aside></aside> oder andere semantische Tags einfügen. 🎜🎜🎜.three-column-layout {
width: 400px;
height: 400px;
.left {
float: left;
width: 50px;
height: 100%;
background-color: #f66;
}
.center {
float: left;
width: 100px;
height: 100%;
background-color: #66f;
}
.right {
overflow: hidden;
height: 100%;
background-color: #3c9;
}
} 🎜 🎜Position + links/rechts/oben/unten🎜🎜🎜Die drei Teile deklarieren left:0 und right:0 , um es nach links und rechts auf dem Bildschirm auszudehnen; die Ober- und Unterseite Deklarieren Sie top:0 und bottom:0 , um die Ober- und Unterseite zu absorbieren, und deklarieren Sie die beiden Höhen als feste Werte, um die top und bottom werden als obere bzw. untere Höhe deklariert. Die drei Teile werden durch absolute Positionierung an bestimmten Positionen fixiert, sodass sie sich nicht gegenseitig beeinflussen. 🎜.three-column-layout {
display: flex;
width: 400px;
height: 400px;
.left {
width: 50px;
background-color: #f66;
}
.center {
width: 100px;
background-color: #66f;
}
.right {
flex: 1;
background-color: #3c9;
}
} 🎜🎜flex🎜🎜🎜Die Verwendung von flex wird prägnanter sein. display:flex ordnet die untergeordneten Knoten standardmäßig horizontal an. Sie müssen flex-direction:column deklarieren, um die Anordnungsrichtung der untergeordneten Knoten in eine vertikale Anordnung zu ändern und untere Höhen sind fest, daher muss der Hauptkörper als flex:1 Höhe adaptiv deklariert werden. 🎜<div class="grail-layout-x">
<div class="left"></div>
<div class="right"></div>
<div class="center"></div>
</div> 🎜Wenn <main></main> in einem scrollbaren Zustand angezeigt werden muss, deklarieren Sie nicht overflow:auto , um ein adaptives Scrollen des Containers zu ermöglichen Formatierungsprobleme Der Einfluss des Kontexts kann dazu führen, dass das adaptive Scrollen fehlschlägt oder andere unbekannte Effekte hervorruft. Sie müssen einen in <main></main> einfügen und ihn wie folgt deklarieren. 🎜 .grail-layout-x {
padding: 0 100px;
width: 400px;
height: 400px;
.left {
float: left;
margin-left: -100px;
width: 100px;
height: 100%;
background-color: #f66;
}
.right {
float: right;
margin-right: -100px;
width: 100px;
height: 100%;
background-color: #66f;
}
.center {
height: 100%;
background-color: #3c9;
}
} 🎜Zweispaltiges Layout🎜🎜Das klassische 🎜zweispaltige Layout🎜 besteht aus zwei Spalten links und rechts , und seine Eigenschaften sind Eine Spalte hat eine feste Breite , die andere Spalte hat eine adaptive Breite und zwei Spalten haben eine feste und gleiche Höhe . Im Folgenden wird als Beispiel die feste Breite der linken Spalte und die adaptive Breite der rechten Spalte verwendet und umgekehrt. 🎜🎜 🎜 <div class="grail-layout-y">
<div class="left"></div>
<div class="right"></div>
<div class="center">
<div></div>
</div>
</div> 🎜 🎜float + margin-left/right🎜🎜🎜Die linke Spalte deklariert float:left und eine feste Breite. Da float den Knoten entfließen lässt, muss die rechte Spalte margin -left ist die Breite der linken Spalte, um sicherzustellen, dass sich die beiden Spalten nicht überlappen. 🎜 .grail-layout-y {
width: 400px;
height: 400px;
.left {
float: left;
width: 100px;
height: 100%;
background-color: #f66;
}
.right {
float: right;
width: 100px;
height: 100%;
background-color: #66f;
}
.center {
margin: 0 100px;
height: 100%;
background-color: #3c9;
}
} 🎜🎜overflow + float🎜🎜🎜Die linke Spalte deklariert dasselbe wie oben, und die rechte Spalte deklariert overflow:hidden , um einen BFC-Bereich zu bilden und diesen zu isolieren die Außenwelt. 🎜 <div class="grail-layout">
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
</div> 🎜🎜flex🎜🎜🎜Die Verwendung von flex wird prägnanter sein. Die linke Spalte deklariert eine feste Breite und die rechte Spalte deklariert die adaptive Breite flex:1 . 🎜 .grail-layout {
display: flex;
width: 400px;
height: 400px;
.left {
width: 100px;
background-color: #f66;
}
.center {
flex: 1;
background-color: #3c9;
}
.right {
width: 100px;
background-color: #66f;
}
} 🎜Dreispaltiges Layout🎜🎜Das klassische 🎜dreispaltige Layout🎜 besteht aus drei Spalten links, in der Mitte und rechts und seine Eigenschaften sind: code>Die Breite von zwei aufeinanderfolgenden Spalten ist fest, Die Breite der verbleibenden Spalte ist adaptiv und Die Höhe von drei Spalten ist fest und gleich . Im Folgenden werden als Beispiel die feste Breite der linken mittleren Spalte und die adaptive Breite der rechten Spalte verwendet und umgekehrt. Das allgemeine Implementierungsprinzip stimmt mit dem oben genannten zweispaltigen Layout überein. 🎜🎜 🎜 <div class="average-layout">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
<div class="four"></div>
</div> 🎜 Um die Breite der rechten Spalte adaptiv zu berechnen, wird die Methode float + margin-left nicht verwendet. Wenn margin-left verwendet wird, muss sie berechnet werden in Verbindung mit der Breite der linken mittleren Spalte. 🎜🎜🎜Überlauf + Float🎜🎜 .one {
background-color: #f66;
}
.two {
background-color: #66f;
}
.three {
background-color: #f90;
}
.four {
background-color: #09f;
} 🎜🎜flex🎜 .three-column-layout {
display: flex;
width: 400px;
height: 400px;
.left {
width: 50px;
background-color: #f66;
}
.center {
width: 100px;
background-color: #66f;
}
.right {
flex: 1;
background-color: #3c9;
}
} 圣杯布局/双飞翼布局
经典的圣杯布局和双飞翼布局都是由左中右三列 组成,其特点为左右两列宽度固定 、中间一列宽度自适应 和三列高度固定且相等 。其实也是上述两列布局和三列布局的变体,整体的实现原理与上述N列布局一致,可能就是一些细节需注意。
圣杯布局 和双飞翼布局 在大体相同下也存在一点不同,区别在于双飞翼布局 中间列需插入一个子节点。在常规实现方式里也是在这个中间列里做文章,如何使中间列内容不被左右列遮挡 。
<li>相同
<li>中间列放首位且声明其宽高占满父节点
<li>被挤出的左右列使用float 和margin负值 将其拉回与中间列处在同一水平线上
<li>不同
<li>圣杯布局:父节点声明padding 为左右列留出空位,将左右列固定在空位上
<li>双飞翼布局:中间列插入子节点并声明margin 为左右列让出空位,将左右列固定在空位上
圣杯布局float + margin-left/right + padding-left/right
由于浮动节点在位置上不能高于前面或平级的非浮动节点,否则会导致浮动节点下沉。因此在编写HTML结构时,将中间列节点挪到右列节点后面。 <div class="grail-layout-x">
<div class="left"></div>
<div class="right"></div>
<div class="center"></div>
</div> .grail-layout-x {
padding: 0 100px;
width: 400px;
height: 400px;
.left {
float: left;
margin-left: -100px;
width: 100px;
height: 100%;
background-color: #f66;
}
.right {
float: right;
margin-right: -100px;
width: 100px;
height: 100%;
background-color: #66f;
}
.center {
height: 100%;
background-color: #3c9;
}
} 双飞翼布局float + margin-left/right
HTML结构大体同上,只是在中间列里插入一个子节点<div>。根据两者区别,CSS声明会与上述圣杯布局有一点点出入,可观察对比找出不同地方。<pre class="brush:html;toolbar:false;"><div class="grail-layout-y">
<div class="left"></div>
<div class="right"></div>
<div class="center">
<div></div>
</div>
</div></pre><pre class="brush:css;toolbar:false;">.grail-layout-y {
width: 400px;
height: 400px;
.left {
float: left;
width: 100px;
height: 100%;
background-color: #f66;
}
.right {
float: right;
width: 100px;
height: 100%;
background-color: #66f;
}
.center {
margin: 0 100px;
height: 100%;
background-color: #3c9;
}
}</pre><blockquote><p>圣杯布局/双飞翼布局flex</p></blockquote>
<p>使用flex实现<code>圣杯布局/双飞翼布局 可忽略上述分析,左右两列宽度固定,中间列宽度自适应。 <div class="grail-layout">
<div class="left"></div>
<div class="center"></div>
<div class="right"></div>
</div> .grail-layout {
display: flex;
width: 400px;
height: 400px;
.left {
width: 100px;
background-color: #f66;
}
.center {
flex: 1;
background-color: #3c9;
}
.right {
width: 100px;
background-color: #66f;
}
} 均分布局
经典的均分布局由多列 组成,其特点为每列宽度相等 和每列高度固定且相等 。总体来说也是最简单的经典布局,由于每列宽度相等,所以很易找到合适的方式处理。
<div class="average-layout">
<div class="one"></div>
<div class="two"></div>
<div class="three"></div>
<div class="four"></div>
</div> .one {
background-color: #f66;
}
.two {
background-color: #66f;
}
.three {
background-color: #f90;
}
.four {
background-color: #09f;
} float + width
每列宽度声明为相等的百分比,若有4列则声明width:25% 。N列就用公式100 / n 求出最终百分比宽度,记得保留2位小数,懒人还可用width:calc(100% / n) 自动计算呢。 .average-layout {
width: 400px;
height: 400px;
div {
float: left;
width: 25%;
height: 100%;
}
} flex
使用flex实现会更简洁。节点声明display:flex 后,生成的FFC容器 里所有子节点的高度都相等,因为容器的align-items 默认为stretch ,所有子节点将占满整个容器的高度。每列声明flex:1 自适应宽度。 .average-layout {
display: flex;
width: 400px;
height: 400px;
div {
flex: 1;
}
} 居中布局
居中布局由父容器 与若干个子容器 组成,子容器在父容器中横向排列或竖向排列且呈水平居中或垂直居中。居中布局是一个很经典的问题,相信大家都会经常遇到。
在此直接上一个目前最简单最高效的居中方式。display:flex 与margin:auto 的强行组合,同学们自行体会。 <div class="center-layout">
<div></div>
</div> .center-layout {
display: flex;
width: 400px;
height: 400px;
background-color: #f66;
div {
margin: auto;
width: 100px;
height: 100px;
background-color: #66f;
}
} 自适布局
自适布局指相对视窗任何尺寸都能占据特定百分比的占位布局。自适布局 的容器都是根据视窗尺寸计算,即使父节点 或祖先节点 的尺寸发生变化也不会影响自适布局 的容器尺寸。
搭建自适布局 就离不开视窗比例单位。在CSS3里增加了与viewport 相关的四个长度单位,随着时间推移,目前大部分浏览器对这四个长度单位都有较好的兼容性,这也是未来最建议在伸缩方案里使用的长度单位。
<li>
1vw 表示1% 视窗宽度
<li>
1vh 表示1% 视窗高度
<li>
1vmin 表示1% 视窗宽度和1% 视窗高度里最小者
<li>
1vmax 表示1% 视窗宽度和1% 视窗高度里最大者
视窗宽高在JS里分别对应window.innerWdith 和window.innerHeight 。若不考虑低版本浏览器兼容性,完全可用一行CSS代码秒杀所有移动端的伸缩方案。 /* 基于UI width=750px DPR=2的网页 */
html {
font-size: calc(100vw / 7.5);
} 上述代码使用calc() 实现font-size 的动态计算。calc() 是自适布局 里的核心存在,无它就不能愉快地实现自适布局 所有动态计算了。
calc() 用于动态计算单位,数值 、长度 、角度 、时间 和百分比 都能作为参数。由于执行数学表达式 后返回运算后的计算值,所以可减少大量人工计算甚至无需人工计算。
calc() 饥不择食,所有计量单位都能作为参数参加整个动态计算。
calc() 虽然好用,但新手难免会遇到一些坑,谨记以下特点,相信就能玩转calc() 了。
<li>四则运算:只能使用+ 、- 、* 、/ 作为运算符号
<li>运算顺序:遵循加减乘除运算顺序,可用() 提升运算等级
<li>符号连接:每个运算符号必须使用空格 间隔起来
<li>混合计算:可混合不同计量单位动态计算
第三点尤为重要,若未能遵守,浏览器直接忽略该属性。
上述font-size:calc(100vw / 7.5) 其实就是根据设计图与浏览器视窗的比例动态计算 的font-size :100/750 = x/100vw 。
在SPA里有遇过因为有滚动条或无滚动条而导致页面路由在跳转过程里发生向左或向右的抖动吗?这让强迫症患者很难受,此时可用calc() 巧妙解决该问题。 .elem {
padding-right: calc(100vw - 100%);
} 不直接声明padding-right 为滚动条宽度是因为每个浏览器的默认滚动条宽度都可能不一致。100vw 是视窗宽度,100% 内容宽度,那么100vw - 100% 就是滚动条宽度,声明padding-right 用于保留滚动条出现的位置,这样滚动条出不出现都不会让页面抖动了。
有了calc() 做保障就可迅速实现一些与视窗尺寸相关的布局了。例如实现一个视窗宽度都为50% 的弹窗。
<div class="modal">
<div class="modal-wrapper"></div>
</div> .modal {
display: flex;
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
justify-content: center;
align-items: center;
background-color: rgba(0, 0, 0, .5);
&-wrapper {
width: 50vw;
height: 200px;
background-color: #f66;
}
} 当然使用calc() 也不一定结合视窗比例单位 计算。例如自适布局 已知部分节点高度,不想手动计算最后节点高度但又想其填充布局剩余空间。
<ul class="selfadaption-layout">
<div class="box-1"></div>
<div class="box-2"></div>
<div class="box-3"></div>
</ul> .selfadaption-layout {
width: 200px;
height: 567px;
.box-1 {
height: 123px;
background-color: #f66;
}
.box-2 {
height: 15%;
background-color: #3c9;
}
.box-3 {
height: calc(100% - 123px - 15%);
background-color: #09f;
}
} 吸附布局
吸附布局指相对视窗任何滚动都能占据特定位置的占位布局。视窗滚动到特定位置,布局固定在该位置,后续不随视窗滚动而滚动。该布局产生的效果俗称吸附效果 ,是一种常见网页效果。譬如吸顶效果 和吸底效果 都是该范畴,经常在跟随导航 、移动广告 和悬浮提示 等应用场景里出现。
In der jQuery-Ära gab es viele Adsorptionseffekt-Plug-Ins. Jetzt verfügen die drei großen Front-End-Frameworks auch über eigene Adsorptionseffekt-Komponenten von Drittanbietern. Sie alle haben ein gemeinsames Implementierungsprinzip: Hören Sie sich das Ereignis scroll an, bestimmen Sie den Standortbereich von scrollTop und target node und legen Sie den Ziel, wenn die Bedingungen erfüllt sind. Wenn Sie die <code>Position eines Knotens als fest deklarieren, wird der Zielknoten relativ zum Fenster positioniert. Der Benutzer scheint an der angegebenen Position im Fenster angeheftet zu sein.
jQuery时代 就有很多吸附效果插件,现在三大前端框架也有自身第三方的吸附效果组件。它们都有着共通的实现原理:监听 scroll 事件,判断 scrollTop 和 目标节点 的位置范围,符合条件则将 目标节点 的 position 声明为 fixed 使 目标节点 相对于视窗定位,让用户看上去就像钉在视窗指定位置上。 JS实现吸附效果的代码在网上一搜一大堆,更何况笔者喜欢耍CSS,在此就不贴相关的JS代码了。在此推荐一个很少见很少用的CSS属性position:sticky 。简单的两行核心CSS代码就能完成十多行核心JS代码的功能,何乐而不为呢。
简单回顾position 属性值,怎样用就不说了,大家应该都熟悉。
取值 |
功能 |
版本 |
inherit |
继承 |
2 |
static |
标准流 |
2 |
relative |
相对定位 |
2 |
absolute |
绝对定位 |
2 |
fixed |
固定定位 |
2 |
sticky |
粘性定位 Es gibt viele Codes für JS, um einen Adsorptionseffekt im Internet zu erzielen, ganz zu schweigen davon, dass der Autor gerne mit CSS spielt, daher werde ich den relevanten JS-Code hier nicht veröffentlichen. Hier empfehlen wir eine selten verwendete CSS-Eigenschaft position:sticky . Einfache zwei Zeilen Kern-CSS-Code können die Funktionen von mehr als zehn Zeilen Kern-JS-Code vervollständigen, also warum nicht? | Ein kurzer Überblick über den Attributwert position . Ich werde nicht näher darauf eingehen, wie man ihn verwendet.
Wert |
Funktion |
Version |
|
inherit
Inherit
🎜2🎜🎜
🎜 static 🎜🎜Standardfluss 🎜🎜2🎜🎜
🎜relativ🎜🎜Relative Positionierung 🎜🎜2🎜🎜🎜absolut🎜🎜Absolute Positionierung 🎜🎜2🎜🎜
🎜fest🎜🎜Feste Positionierung 🎜 🎜2🎜🎜
🎜klebrige🎜🎜klebrige Positionierung 🎜🎜3🎜🎜🎜🎜当值为sticky 时将节点变成粘性定位 。粘性定位是相对定位 和固定定位 的结合体,节点在特定阈值 跨越前为相对定位 ,跨越后为固定定位 。
<div class="adsorption-position">
<ul>
<li>Top 1</li>
<li>Top 2</li>
<li>Normal</li>
<li>Bottom 1</li>
<li>Bottom 2</li>
</ul>
</div> .adsorption-position {
overflow: auto;
position: relative;
width: 400px;
height: 280px;
outline: 1px solid #3c9;
ul {
padding: 200px 0;
}
li {
position: sticky;
height: 40px;
line-height: 40px;
text-align: center;
color: #fff;
&:nth-child(1) {
top: 0;
z-index: 9;
background-color: #f66;
}
&:nth-child(2) {
top: 40px;
z-index: 9;
background-color: #66f;
}
&:nth-child(3) {
background-color: #f90;
}
&:nth-child(4) {
bottom: 0;
z-index: 9;
background-color: #09f;
}
&:nth-child(5) {
bottom: 40px;
z-index: 9;
background-color: #3c9;
}
}
} 两行核心CSS代码分别是position:sticky 和top/bottom:npx 。上述5个节点都声明position:sticky ,但由于top/bottom 赋值有所不同就产生不同吸附效果。
细心的同学可能发现这些节点在某些滚动时刻处于相对定位,在特定滚动时刻处于固定定位 。
<li>第1个<li> :top 为0px ,滚动到容器顶部 就固定
<li>第2个<li> :top 为40px ,滚动到距离容器顶部40px 就固定
<li>第3个<li> :未声明top/bottom ,就一直保持相对定位
<li>第4个<li> :bottom 为40px ,滚动到距离容器底部40px 就固定
<li>第5个<li> :bottom 为0px ,滚动到容器底部 就固定
当然,换成left 或right 也一样能实现横向的吸附效果 。
值得注意,粘性定位 的参照物并不一定是position:fixed 。当目标节点 的任意祖先节点 都未声明position:relative|absolute|fixed|sticky ,才与position:fixed 表现一致。当离目标节点 最近的祖先节点 声明position:relative|absolute|fixed|sticky ,目标节点 就相对该祖先节点 产生粘性定位 。简单来说确认参照物的方式与position:absolute 一致。
兼容性勉强还行,近2年发版的浏览器都能支持,Safari 和Firefox 的兼容性还是挺赞的。有吸附效果 需求的同学建议一试,要兼容IExplorer 就算了。期待该属性有更好的发展,毕竟吸附布局 真的是一种常见布局。
横向布局
横向布局指容器内节点以水平方向排列且溢出部分被隐藏的占位布局。竖向布局 很常见,声明overflow:hidden;width:xpx;height:ypx 就能实现,但横向布局 却不能使用类似方式实现。
为了方便使用多种方式实现横向布局 ,以下将通用代码拆分出来。
<div class="horizontal-layout">
<ul>
<li>Alibaba</li>
<li>Tencent</li>
<li>Baidu</li>
<li>Jingdong</li>
<li>Ant</li>
<li>Netease</li>
<li>Meituan</li>
<li>ByteDance</li>
<li>360</li>
<li>Sina</li>
</ul>
</div> .horizontal-layout {
overflow: hidden;
width: 300px;
height: 100px;
ul {
overflow-x: auto;
cursor: pointer;
&::-webkit-scrollbar {
height: 10px;
}
&::-webkit-scrollbar-track {
background-color: #f0f0f0;
}
&::-webkit-scrollbar-thumb {
border-radius: 5px;
background-color: #f66;
}
}
li {
overflow: hidden;
height: 90px;
background-color: #66f;
line-height: 90px;
text-align: center;
font-size: 16px;
color: #fff;
&:not(:first-child) {
margin-left: 10px;
}
}
} 有些同学可能会使用行内元素 实现横向排版,但必须声明overflow-y:hidden 使容器在Y轴 方向隐藏溢出部分。由于行内元素 在当前行排版产生溢出会自动将其余节点排版到下一行,因此还需声明white-space:nowrap 使所有行内元素 在一行内排版完毕。若产生滚动条,还需对容器的height 做适当的微调。 .horizontal-layout.inline {
height: 102px;
ul {
overflow-y: hidden;
white-space: nowrap;
}
li {
display: inline-block;
width: 90px;
}
} 上述方式在笔者在开发认知里觉得太繁琐,实质上将所有节点当成文本排列,也是醉了。笔者推荐使用flex布局 完成上述布局,flex布局 作为目前最常见的布局方式 ,相信也不用笔者多说。以下实现方式不知大家是否见过呢?在移动端上体验会更棒喔! .horizontal-layout.flex {
ul {
display: flex;
flex-wrap: nowrap;
justify-content: space-between;
}
li {
flex-shrink: 0;
flex-basis: 90px;
}
} 凸显布局
凸显布局指容器内节点以同一方向排列且存在一个节点在某个方向上较突出的占位布局。该布局描述起来可能比较拗口,直接看以下效果吧,这是一个横向列表,节点从左往右排列,最右边的节点特别突出。这就是凸显布局 的特征,凸显的节点可在凸显布局 任意位置,上下左右 ,左上左下右上右下 都行。
这里巧妙运用margin-*:auto 实现了凸显布局 。相信大家实现水平居中固定宽度的块元素 都会使用margin:0 auto 。
在此同样原理,当节点声明margin-*:auto 时,浏览器会自动计算剩余空间并将该值赋值给该节点。在使用该技巧时必须基于flex布局 。
<ul class="highlight-layout">
<li>Alibaba</li>
<li>Tencent</li>
<li>Baidu</li>
<li>Jingdong</li>
<li>Ant</li>
<li>Netease</li>
</ul> .highlight-layout {
display: flex;
align-items: center;
padding: 0 10px;
width: 600px;
height: 60px;
background-color: #3c9;
li {
padding: 0 10px;
height: 40px;
background-color: #3c9;
line-height: 40px;
font-size: 16px;
color: #fff;
}
&.left li {
&:not(:first-child) {
margin-left: 10px;
}
&:last-child {
margin-left: auto;
}
}
&.right li {
&:not(:last-child) {
margin-right: 10px;
}
&:first-child {
margin-right: auto;
}
}
&.top {
flex-direction: column;
width: 120px;
height: 400px;
li {
&:not(:first-child) {
margin-top: 10px;
}
&:last-child {
margin-top: auto;
}
}
}
&.bottom {
flex-direction: column;
width: 120px;
height: 400px;
li {
&:not(:last-child) {
margin-bottom: 10px;
}
&:first-child {
margin-bottom: auto;
}
}
}
} 在此还有一个小技巧,那就是:not() 与:first-child 和:last-child 的巧妙运用。这样组合让特殊位置的节点直接减少属性覆盖的问题,不仅易读还能装逼。
间距布局
间距布局指容器内节点从左往右从上往下排列且以特定间距间隔的占位布局。间距布局 常见于各大列表,是笔者认为最重要的布局之一。为何如此简单的布局还是花费一些篇幅讲解呢?最近笔者查看了Github 上很多与间隔布局 相关的CSS代码,虽然整体效果看上去无大碍,但margin/padding 和结构选择器 却乱用,因此笔者想从零到一纠正间距布局 的正确编码方式。
在进入编码环节前,笔者想重点讲解:nth-child() 的点睛之笔。大部分同学可能只认得:nth-child(n) 、:nth-child(2n-1) 、:nth-child(2n) 和:nth-child(xn) 的日常用法,但其实还有一些你可能未见过的用法。在此笔者借这次机会将:nth-child() 所有用法总结下,n/x/y 代表正整数,最小值为1 。
分析间距布局 的一切特点,捕获特征很有利于将特征转换成CSS代码。
<li>
A:确定容器间的间距,使用margin 声明
<li>
B:确定容器内的间距,使用padding 声明,后续方便声明background-color (该步骤很易与上一步骤混淆,请特别注意)
<li>
C:确定靠近容器边界的节点与容器的间距,使用padding 声明容器而不是使用margin 声明节点(该步骤说明上一步骤的处理结果)
<li>
D:确认每行节点的左右间距,使用margin-left/margin-right (二选一)声明节点
<li>
E:确认最左列节点或最右列节点与容器的间距,使用margin-left:0 声明最左列节点或使用margin-right:0 声明最右列节点
<li>
F:除了首行节点,使用margin-top 声明其余节点
<li>
G:若希望容器顶部底部留空,使用border-top/border-bottom 代替padding-top/padding-bottom
全部步骤串联起来理解可能会产生混乱,但结合以下代码理解相信就能很快熟悉。以一行排列3个节点总共8个节点为例,最终效果为三行三列。
<ul class="spacing-layout">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
</ul> .spacing-layout {
display: flex;
overflow: auto;
flex-wrap: wrap;
margin-top: 20px; // 对应A
padding: 20px; // 对应B和C
// padding-top: 0; // 对应G
// padding-bottom: 0; // 对应G
// border-top: 20px solid #f66; // 对应G
// border-bottom: 20px solid #f66; // 对应G
width: 700px; // 稍微留空用于显示滚动条
height: 400px;
background-color: #f66;
li {
width: 200px;
height: 200px;
background-color: #66f;
line-height: 200px;
text-align: center;
font-size: 20px;
color: #fff;
&:not(:nth-child(3n)) {
margin-right: 20px; // 对应D和E
}
&:nth-child(n+4) {
margin-top: 20px; // 对应F
}
}
} 空载布局
空载布局指容器内无任何节点时使用其他形式代替的占位布局。还有使用JS判断列表集合为空时显示占位符吗?相信很多使用MVVM框架开发的同学都会使用条件判断的方式渲染虚拟DOM,若列表长度不为0则渲染列表,否则渲染占位符。 <div>
<ul v-if="list.length">...</ul>
<div v-esle>Empty</div>
</div> 然而CSS提供一个空判断的选择器:empty ,这应该很少同学会注意到吧。
:empty 作用于无子节点的节点,该子节点也包括行内匿名盒(单独的文本内容 )。以下三种情况均视为非空状态,若不出现这三种状态则视为空状态,此时:empty 才会触发。
<ul class="empty-layout">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</ul>
<ul class="empty-layout"></ul> $empty: "https://yangzw.vip/img/empty.svg";
.empty-layout {
overflow: auto;
width: 200px;
height: 150px;
outline: 1px solid #3c9;
&:empty {
display: flex;
justify-content: center;
align-items: center;
background: url($empty) no-repeat center/100px auto;
&::after {
margin-top: 90px;
font-weight: bold;
content: "没钱就没数据";
}
}
li {
padding: 0 10px;
height: 30px;
background-color: #09f;
line-height: 30px;
color: #fff;
&:nth-child(even) {
background-color: #f90;
}
}
} 另外还存在一种特殊的空载布局 ,就是不做任何处理。这样最终渲染的DOM只有容器,若已声明margin/padding/border 但未声明width/height 的情况下,就会出现以下占位效果。无任何子节点的容器还声明着margin/padding/border ,看着都尴尬。
没事,:empty 帮你搞掂!对于无任何子节点的容器直接声明display:none 解决所有无效占位,当然也可作用于指定节点。一招制敌,劲! // 作用于所有节点
:empty {
display: none;
}
// 作用于指定节点
.empty-layout:empty {
display: none;
} 多格布局
多格布局指容器内节点以动态数量的格子形式排列的占位布局。微信朋友圈的相册就是最常见的多格布局 了,当单张照片排列、两张照片排列、三张照片排列等等,每种情况下照片的尺寸都可能不一致。笔者制作了一个动态多格相册怀念我家狗狗AB。大家感受下纯CSS实现动态数量的多格布局 吧。
在此留个悬念,不讲解如何实现,看看大家能不能根据笔者列出的提示尝试将该效果复原。主要原理是根据结构选择器限制节点范围 实现,在本文也可找到原理的答案喔!记得实现完再看以下源码哈!
<ul class="multigrid-layout">
<li class="item"><img src="https://static.yangzw.vip/codepen/ab-3.jpg" alt="8 wissenswerte reine CSS-Layouttechniken" ></li>
<li class="item"><img src="https://static.yangzw.vip/codepen/ab-3.jpg" alt="8 wissenswerte reine CSS-Layouttechniken" ></li>
<li class="item"><img src="https://static.yangzw.vip/codepen/ab-3.jpg" alt="8 wissenswerte reine CSS-Layouttechniken" ></li>
<li class="item"><img src="https://static.yangzw.vip/codepen/ab-3.jpg" alt="8 wissenswerte reine CSS-Layouttechniken" ></li>
<li class="item"><img src="https://static.yangzw.vip/codepen/ab-3.jpg" alt="8 wissenswerte reine CSS-Layouttechniken" ></li>
<li class="item"><img src="https://static.yangzw.vip/codepen/ab-3.jpg" alt="8 wissenswerte reine CSS-Layouttechniken" ></li>
<li class="item"><img src="https://static.yangzw.vip/codepen/ab-3.jpg" alt="8 wissenswerte reine CSS-Layouttechniken" ></li>
<li class="item"><img src="https://static.yangzw.vip/codepen/ab-3.jpg" alt="8 wissenswerte reine CSS-Layouttechniken" ></li>
<li class="item"><img src="https://static.yangzw.vip/codepen/ab-3.jpg" alt="8 wissenswerte reine CSS-Layouttechniken" ></li>
</ul> @mixin square($count: 2) {
$length: calc((100% - #{$count} * 10px) / #{$count});
width: $length;
height: $length;
}
.multigrid-layout {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
align-content: flex-start;
padding: 5px;
border: 1px solid #ccc;
border-radius: 5px;
width: 400px;
height: 400px;
li {
display: flex;
overflow: hidden;
justify-content: center;
margin: 5px;
background-color: #f0f0f0;
@include square(3);
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
// 一个元素
.item:only-child {
border-radius: 10px;
width: auto;
max-width: 80%;
height: auto;
max-height: 80%;
}
// 两个元素
.item:first-child:nth-last-child(2),
.item:first-child:nth-last-child(2) ~ .item:nth-child(2) {
@include square(2);
}
.item:first-child:nth-last-child(2) {
border-radius: 10px 0 0 10px;
}
.item:first-child:nth-last-child(2) ~ .item:nth-child(2) {
border-radius: 0 10px 10px 0;
}
// 三个元素
.item:first-child:nth-last-child(3),
.item:first-child:nth-last-child(3) ~ .item:nth-child(2),
.item:first-child:nth-last-child(3) ~ .item:nth-child(3) {
@include square(2);
}
.item:first-child:nth-last-child(3) {
border-top-left-radius: 10px;
}
.item:first-child:nth-last-child(3) ~ .item:nth-child(2) {
border-top-right-radius: 10px;
}
.item:first-child:nth-last-child(3) ~ .item:nth-child(3) {
border-bottom-left-radius: 10px;
}
// 四个元素
.item:first-child:nth-last-child(4),
.item:first-child:nth-last-child(4) ~ .item:nth-child(2),
.item:first-child:nth-last-child(4) ~ .item:nth-child(3),
.item:first-child:nth-last-child(4) ~ .item:nth-child(4) {
@include square(2);
}
.item:first-child:nth-last-child(4) {
border-top-left-radius: 10px;
}
.item:first-child:nth-last-child(4) ~ .item:nth-child(2) {
border-top-right-radius: 10px;
}
.item:first-child:nth-last-child(4) ~ .item:nth-child(3) {
border-bottom-left-radius: 10px;
}
.item:first-child:nth-last-child(4) ~ .item:nth-child(4) {
border-bottom-right-radius: 10px;
}
// 五个元素
.item:first-child:nth-last-child(5) {
border-top-left-radius: 10px;
}
.item:first-child:nth-last-child(5) ~ .item:nth-child(3) {
border-top-right-radius: 10px;
}
.item:first-child:nth-last-child(5) ~ .item:nth-child(4) {
border-bottom-left-radius: 10px;
}
// 六个元素
.item:first-child:nth-last-child(6) {
border-top-left-radius: 10px;
}
.item:first-child:nth-last-child(6) ~ .item:nth-child(3) {
border-top-right-radius: 10px;
}
.item:first-child:nth-last-child(6) ~ .item:nth-child(4) {
border-bottom-left-radius: 10px;
}
.item:first-child:nth-last-child(6) ~ .item:nth-child(6) {
border-bottom-right-radius: 10px;
}
// 七个元素
.item:first-child:nth-last-child(7) {
border-top-left-radius: 10px;
}
.item:first-child:nth-last-child(7) ~ .item:nth-child(3) {
border-top-right-radius: 10px;
}
.item:first-child:nth-last-child(7) ~ .item:nth-child(7) {
border-bottom-left-radius: 10px;
}
// 八个元素
.item:first-child:nth-last-child(8) {
border-top-left-radius: 10px;
}
.item:first-child:nth-last-child(8) ~ .item:nth-child(3) {
border-top-right-radius: 10px;
}
.item:first-child:nth-last-child(8) ~ .item:nth-child(7) {
border-bottom-left-radius: 10px;
}
// 九个元素
.item:first-child:nth-last-child(9) {
border-top-left-radius: 10px;
}
.item:first-child:nth-last-child(9) ~ .item:nth-child(3) {
border-top-right-radius: 10px;
}
.item:first-child:nth-last-child(9) ~ .item:nth-child(7) {
border-bottom-left-radius: 10px;
}
.item:first-child:nth-last-child(9) ~ .item:nth-child(9) {
border-bottom-right-radius: 10px;
} 总结
很多同学可能觉得CSS很简单,但真正玩起来也能与JS有得一比。笔者从事前端领域多年,一直致力于CSS技术的研究与应用,当然真的不是为了玩,而是在玩的过程里将实践到的知识充分应用于工作上。
JS重要但CSS同样重要,希望喜欢CSS的同学多多关注笔者,相信你一定会有更多CSS方面的收获。
原文地址:https://juejin.cn/post/6986873449721364510
作者:JowayYoung
更多编程相关知识,请访问:编程入门!!
|