>  기사  >  웹 프론트엔드  >  알아야 할 8가지 순수 CSS 레이아웃 기술

알아야 할 8가지 순수 CSS 레이아웃 기술

青灯夜游
青灯夜游앞으로
2021-07-21 19:47:074434검색

이 글에서는 공통 또는 특수 레이아웃을 달성하기 위해 모든 사람에게 알려지지는 않았지만 매우 실용적인 몇 가지 순수한 CSS 레이아웃 및 조판 기술을 공유할 것입니다.

알아야 할 8가지 순수 CSS 레이아웃 기술常见或特殊的布局排版

알아야 할 8가지 순수 CSS 레이아웃 기술

开发每一张网页都离不开布局排版,基于良好布局排版打下基础,才能使后续的开发更顺利。当然不能停留在IExplorer时代那种局限思维上,没办法解决的布局排版都用JS实现。今时不同往日,现代CSS属性能更好地快速实现各种布局排版,节约更多时间去摸鱼。

不过按照笔者目前了解的情况来看,大部分同学即使在无需兼容IExplorer的情况下还是遵循CSS+JS的方式完成一些常见或特殊的布局排版。从HTML/CSS/JS前端三剑客的定位来看,HTML映射网页的结构CSS映射网页的表现JS映射网页的行为

布局排版指将图形、文本、图像、媒体等可视化信息元素在页面布局上调整位置尺寸等属性使页面布局变得条理化的过程。大部分同学认为布局排版就是几个合理的CSS属性随便拼凑在一起,但多数情况即使实现也会存在瑕疵,此时就可能使用JS介入。

布局排版的特征可知它属于表现范畴,因此笔者认为大部分布局排版都能使用纯CSS完成,无需JS介入。

本文秉承能使用CSS实现的效果都优先使用CSS的原则,为大家讲解笔者如何巧妙运用各种纯CSS开发技巧完成一些常见或特殊的布局排版

属性

在进入主题前,笔者总结出布局排版一些必备属性,这些属性能快速搭建整体效果,再通过一些常用选择器加以修饰达到完美效果。看似简单,但使用起来不一定完全驾驭。

必备属性都是一些几何属性,主要用于声明位置尺寸

  • 浮动布局float
  • 定位布局position/left/right/top/bottom/z-index
  • 弹性布局display:flex/inline-flexflex系列属性
  • 盒子模型box-sizing/margin/padding/border/width/height

选择器因CSS模块众多而派生出的数量也众多,若无特别方式记熟这些选择器对应的功能,也很难将其发挥到最大作用。

笔者根据选择器的功能划分出八大类,每个类别的选择器都能在一个应用场景里互相组合,记熟这些类别的选择器,相信就能将选择器发挥到最大作用,也能游刃有余将其应用到一些常见或特殊的布局排版里。

布局排版可能只应用到某些选择器,但也不妨碍大家通过以下归类方式记忆。选择器作为CSS的重要组成部分,比起属性组合会有更多的玩法。

基础选择器

그러나 저자의 현재 이해에 따르면 대부분의 학생들은 여전히 ​​CSS+JS 방법을 따라 일부 공통 또는 특수 레이아웃을 완성합니다. HTML/CSS/JS 프론트엔드 삼총사의 포지셔닝 관점에서 HTML은 웹페이지의 를 매핑하고 CSS는 웹페이지의 <td align="center">성능</td>을 매핑하고, <code>JS는 웹페이지의 동작을 매핑합니다.
选择器 别名 说明 版本 常用
tag 标签选择器 指定类型的标签 1
#id ID选择器 指定身份的标签 1
.class 类选择器 指定类名的标签 1
* 通配选择器 所有类型的标签모든 웹페이지를 개발하는 것은 분리될 수 없습니다. >레이아웃과 조판, 좋은 레이아웃과 조판을 바탕으로 기초를 다지면 후속 개발이 더 원활해집니다. 물론, IExplorer 시대의 제한된 생각에 머물 수는 없습니다. 풀 수 없는 레이아웃과 조판은 모두 JS로 구현됩니다. 오늘날은 과거와는 다릅니다. 최신 CSS 속성은 다양한 레이아웃 및 조판을 더 빠르고 효과적으로 구현할 수 있어 더 많은 시간을 절약할 수 있습니다. 구조
🎜레이아웃 및 조판🎜은 그래픽, 텍스트, 이미지, 미디어와 같은 시각적 정보 요소의 위치, 크기 및 기타 속성을 조정하는 것을 의미합니다. 페이지 레이아웃을 변경하여 페이지 레이아웃을 구성하는 과정입니다. 대부분의 학생들은 레이아웃을 무심코 조합한 몇 가지 합리적인 CSS 속성일 뿐이라고 생각하지만, 대부분의 경우 구현하더라도 결함이 있기 때문에 JS를 사용하여 개입할 수도 있습니다. 🎜레이아웃 및 조판의 특성으로 보면 표현의 범주에 속함을 알 수 있으므로 저자는 대부분의 레이아웃이 조판 순수 CSS를 완전하게 사용할 수 있으며 JS 개입이 필요하지 않습니다. 🎜이 글은 CSS를 사용하여 얻을 수 있는 효과에 대해 CSS🎜 사용을 우선한다는 원칙을 고수하며, 저자가 다양한 순수 CSS 개발 기법을 능숙하게 사용하여 일부 공통 또는 특수 레이아웃 . <h2>🎜속성🎜</h2>🎜 주제에 들어가기 전에 저자는 <code>레이아웃 및 조판의 몇 가지 필수 속성을 요약하여 전체적인 효과를 빠르게 구축한 다음 이를 통해 완벽한 결과를 얻기 위해 몇 가지 일반적인 선택을 수정했습니다. 간단한 것 같지만 사용법이 완전히 숙달되지는 않을 수도 있습니다. 🎜필수 속성은 주로 위치크기를 선언하는 데 사용되는 일부 기하학적 속성입니다.
  • 🎜플로팅 레이아웃🎜: float
  • 🎜위치 레이아웃🎜: 위치 /left/right/top/bottom/z-index
  • 🎜 유연한 레이아웃🎜: display:flex/inline-flex, flex 시리즈 속성
  • 🎜Box 모델🎜: box-sizing/margin/padding/border/width/height
🎜Selector 인해CSS 모듈이 많고 파생물도 많습니다. 이러한 선택기의 해당 기능을 기억하는 특별한 방법이 없으면 최대 효과를 활용하기 어려울 것입니다. 🎜저자는 기능에 따라 선택자를 8가지 카테고리로 구분하고 있는데, 각 카테고리의 선택자를 응용 시나리오에서 서로 결합할 수 있다면 활용도를 극대화할 수 있다고 생각합니다. 선택기 중 하나이며 일부 일반 또는 특수 레이아웃에 쉽게 적용할 수 있습니다. 🎜레이아웃은 특정 선택자에만 적용될 수 있지만, 다음과 같은 분류 방법을 통해 모두가 기억하는 것을 막지는 않습니다. CSS의 중요한 부분인 선택기는 속성 조합보다 더 많은 플레이 방법을 제공합니다.
🎜기본 선택기
🎜🎜tag🎜🎜Tag selector🎜🎜# id🎜🎜ID 선택기🎜<td> <code>ID의 태그 지정🎜🎜1🎜🎜√🎜🎜🎜.class🎜🎜클래스 선택 🎜 🎜*🎜🎜Wildcard selector🎜3√
선택기 별명 설명 버전 자주 사용되는
지정된 태그 유형🎜🎜1🎜🎜√🎜🎜
클래스 이름을 지정하는 태그🎜🎜1🎜🎜√🎜🎜
모든 유형 tag 🎜🎜2🎜🎜√🎜🎜🎜🎜

레벨 선택기

Selector alias Description Version 일반적으로 사용되는
elemP elemCelemP elemC 后代选择器 元素的后代元素 1
elemP>elemC 子代选择器 元素的子代元素 2
elem1+elem2 相邻同胞选择器 元素相邻的同胞元素 2
elem1~elem2 通用同胞选择器 元素后面的同胞元素 3

集合选择器

选择器 别名 说明 版本 常用
elem1,elem2 并集选择器 多个指定的元素 1
elem.class 交集选择器 指定类名的元素 1

条件选择器

선택기 code><td align="center"> </td> <td><code>요소의 하위 요소
选择器 说明 版本 常用
:lang 指定标记语言的元素 2 ×
:dir() 指定编写方向的元素 4 ×
:has 包含指定元素的元素 4 ×
:is 指定条件的元素 4 ×
:not 非指定条件的元素 4
:where 指定条件的元素 4 ×
:scope 指定元素作为参考点 4 ×
:any-link 所有包含href链接元素 4 ×
:local-link 所有包含href且属于绝对地址的链接元素 1
🎜🎜elemP>elemC🎜🎜하위 선택기 🎜
요소의 하위 요소🎜🎜2🎜🎜√🎜🎜🎜🎜elem1+elem2🎜🎜인접 형제 선택기 🎜 인접한 형제 요소🎜🎜2🎜🎜√🎜🎜🎜🎜elem1~elem2🎜🎜범용 형제 선택기 🎜 형제 🎜🎜 요소 뒤의 요소 일반적으로 사용되는 🎜🎜🎜🎜🎜🎜elem1,elem2🎜🎜Union 선택기🎜 여러 지정 요소🎜🎜1🎜 🎜√🎜🎜🎜🎜<code>elem.class🎜🎜교차 선택기🎜 클래스 이름을 지정하는 요소🎜🎜1🎜🎜√ 🎜🎜🎜🎜🎜🎜조건부 선택기🎜🎜🎜🎜🎜🎜Selector🎜🎜Description🎜🎜Version🎜🎜일반적으로 사용되는🎜🎜🎜 🎜🎜🎜:lang🎜 마크업 언어 지정 요소🎜🎜2🎜🎜×🎜🎜🎜🎜:dir()🎜 쓰기 방향을 지정하는 요소 🎜🎜4🎜🎜× 🎜🎜🎜🎜:has🎜 지정된 요소🎜🎜4🎜🎜×🎜🎜🎜🎜를 포함하는 <code>요소: is🎜조건을 지정하는 요소🎜🎜4🎜🎜×🎜🎜🎜🎜:not🎜 조건을 지정하지 않는 요소 조건 지정🎜🎜 4🎜🎜√🎜🎜🎜🎜:where🎜 요소 조건을 지정 🎜🎜4🎜🎜×🎜🎜🎜🎜 :scope🎜 element를 참조 지점으로 지정 🎜🎜4🎜🎜×🎜🎜🎜🎜:any-link🎜 hreflink 요소🎜🎜4🎜🎜×🎜🎜🎜🎜:local-link🎜 를 포함하는 모든 항목에는 href이며 주소 🎜🎜4🎜🎜×🎜🎜🎜🎜의 절대 링크 요소입니다.

Status Selector

Selector Description Version 일반적으로 사용되는
:active: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 暂停播放的媒体元素 마우스 활성화 요소 code> 1 ×
:hover🎜
마우스를 올린 요소🎜🎜1🎜🎜√🎜🎜🎜🎜: 링크🎜<td>방문하지 않은 <code>링크 요소🎜🎜1🎜🎜×🎜🎜🎜🎜:visited🎜 방문한 링크 요소 🎜🎜1🎜🎜×🎜🎜🎜🎜:target🎜 현재 앵커의 요소🎜🎜3🎜🎜×🎜🎜🎜 🎜: focus🎜 입력 중심 양식 요소🎜🎜2🎜🎜√🎜🎜🎜🎜:required🎜 입력 필수 양식 요소 🎜🎜3🎜🎜√🎜🎜🎜🎜:유효🎜 적법한 양식 요소 입력 >:잘못됨🎜 잘못된 양식 요소 입력🎜🎜3🎜🎜√🎜🎜🎜🎜:범위 내🎜<td> <code> 입력 범위 내의 양식 요소🎜🎜3🎜🎜×🎜🎜🎜🎜:out-of-range🎜 입력 범위 밖의 양식 요소🎜🎜3🎜🎜×🎜🎜🎜🎜:선택됨🎜 옵션이 선택됨 양식 요소🎜🎜3🎜🎜 √🎜🎜🎜🎜:선택 사항 🎜 선택적 양식 요소🎜🎜3🎜🎜×🎜🎜🎜🎜:enabled 🎜 이벤트 활성화 양식 요소🎜🎜3🎜🎜×🎜🎜🎜🎜<code>:disabled🎜이벤트 비활성화 양식 요소🎜🎜3🎜🎜√🎜🎜🎜🎜:읽기 전용🎜 읽기 전용 양식 요소🎜🎜3🎜🎜×🎜🎜🎜🎜:읽기-쓰기🎜 읽고 쓸 수 있는 form 요소🎜🎜3🎜🎜×🎜🎜🎜🎜:target-within🎜내부 앵커 요소가 활성화되는 요소 🎜🎜4🎜🎜×🎜🎜🎜🎜:focus-within🎜 내부 양식 요소에 포커스가 있습니다 요소🎜🎜4🎜🎜√ 🎜🎜🎜🎜:focus-visible🎜 초점을 맞춘 양식 요소🎜🎜4🎜🎜 ×🎜🎜🎜🎜:blank 입력 🎜 입력이 비어 있습니다 양식 요소🎜🎜4🎜🎜×🎜🎜🎜🎜:user-invalid code>🎜<td>적법한 <code>양식 요소를 입력하세요🎜🎜4🎜🎜×🎜🎜🎜🎜<code>:indeterminate🎜옵션이 결정되지 않음 양식 요소🎜🎜4🎜🎜×🎜🎜🎜🎜 :placeholder-shown🎜 placeholder로 표시된 양식 요소🎜🎜4🎜🎜√🎜🎜🎜 🎜:current()🎜 요소 탐색 중🎜🎜4🎜🎜×🎜🎜🎜🎜:past()🎜탐색된 요소🎜🎜4🎜🎜×🎜 🎜🎜🎜:future()🎜 탐색되지 않은 요소🎜 🎜4🎜🎜×🎜🎜🎜🎜:재생 중🎜 미디어 요소🎜🎜4🎜🎜×🎜🎜🎜🎜:일시 중지됨🎜<td>재생 일시 중지 <code>미디어 요소🎜🎜4🎜🎜 ×🎜🎜🎜🎜structure selectorselectorselector

description

version : root
문서의 루트 요소 code><table> <thead>3<tr class="firstRow"> <th align="center">×</th> <th></th> <th align="center"><code>:empty 하위 요소가 없는 요소
: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 ×

伪元素

3√
选择器 说明 版本 常用
::before 在元素前插入的内容 2
::after 在元素后插入的内容 2
::first-letter 元素的首字母 1 ×
::first-line 元素的首行 1 ×
::selection 鼠标选中的元素 3 ×
::backdrop 全屏模式的元素 4 ×
::placeholder 表单元素的占位 : nth-child(n) 지정된 순차 인덱스가 있는 요소
🎜: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🎜 마지막 태그의 태그Tag🎜🎜3🎜🎜√🎜🎜🎜🎜:only-of-type🎜 상위 요소에는 태그 이 태그🎜🎜 3🎜🎜√🎜🎜🎜🎜🎜🎜속성 선택기🎜🎜🎜🎜🎜🎜Selector🎜🎜Description🎜🎜Version🎜🎜일반적으로 사용되는🎜🎜🎜 🎜🎜🎜[속성] 🎜<td> 지정된 속성이 🎜🎜2🎜🎜√🎜🎜🎜🎜<code>[attr=val]🎜 Element요소 /code> 지정된 값과 동일한 속성 🎜🎜2🎜🎜√🎜🎜🎜🎜[attr*=val]🎜 속성이 지정된 값을 포함하는 요소🎜🎜3🎜🎜√🎜🎜🎜🎜 <code>[attr^=val]🎜 속성이 지정된 값으로 시작하는 요소🎜🎜3🎜🎜 √🎜🎜🎜🎜[attr$=val] 🎜 속성이 지정된 값으로 끝나는 요소🎜🎜3🎜🎜√🎜🎜🎜🎜 [attr~=val]🎜 지정된 값(완전한 단어)을 포함하는 요소 속성(사용되지 않음) 🎜🎜2🎜🎜×🎜🎜🎜🎜[attr| =val]🎜 지정된 값으로 시작하는 요소가 있는 속성(완전한 단어)(사용되지 않음) 🎜🎜2🎜🎜×🎜🎜🎜🎜🎜🎜의사 요소 🎜🎜🎜 🎜🎜🎜selector 🎜🎜 설명 🎜🎜 버전 🎜 🎜일반적으로 사용됨🎜🎜🎜🎜🎜🎜::before🎜 요소 앞에 삽입된 콘텐츠🎜🎜2🎜 🎜√🎜🎜🎜🎜:: after🎜 요소 뒤에 삽입된 콘텐츠🎜🎜2🎜🎜√🎜🎜🎜🎜::first-letter 🎜 요소 첫 글자🎜🎜1🎜🎜×🎜🎜🎜🎜::first-line🎜 첫 번째 줄 🎜🎜1🎜 요소 🎜×🎜🎜🎜🎜::selection🎜 마우스로 선택한 요소 🎜🎜3🎜🎜× 🎜🎜🎜🎜::backdrop🎜 전체 화면 모드 요소🎜🎜4🎜🎜×🎜🎜🎜🎜::placeholder🎜 양식 요소 placeholder code>🎜🎜4🎜🎜√🎜🎜🎜🎜

Techniques

위의 전제 지식을 바탕으로 저자를 따라 다양한 순수 CSS 개발 기술을 능숙하게 사용하여 일부 공통 또는 특수 레이아웃을 완성하는 방법을 경험해 보겠습니다. 브라우저가 특정 스타일을 자동으로 계산하도록 하려면 box-sizing:border-box를 전역적으로 설정해야 합니다. 코딩하기 전에 reset.css. 常见或特殊的布局排版吧。为了方便浏览器自动计算某些样式,需全局设置box-sizing:border-box,编码前请引入笔者整理的reset.css

主体布局

主体布局指在大部分情况下通用且具备统一特征的占位布局。掌握主体布局是一个前端必不可少的技能,养成看设计图就能大概规划出整体布局的前提是必须熟悉这些主体布局的特点与构造。

全屏布局

经典的全屏布局顶部底部主体三部分组成,其特点为三部分左右满屏拉伸顶部底部高度固定主体高度自适应。该布局很常见,也是大部分Web应用主体的主流布局。通常使用<header></header><footer></footer><main></main>三个标签语义化排版,<main></main>内还可插入<aside></aside>侧栏或其他语义化标签。

알아야 할 8가지 순수 CSS 레이아웃 기술

<div class="fullscreen-layout">
    <header></header>
    <main></main>
    <footer></footer>
</div>

position + left/right/top/bottom

三部分统一声明left:0right:0将其左右满屏拉伸;顶部和底部分别声明top:0bottom:0将其吸顶和吸底,并声明俩高度为固定值;将主体的topbottom分别声明为顶部高度和底部高度。通过绝对定位的方式将三部分固定在特定位置,使其互不影响。

.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>左右两列组成,其特点为一列宽度固定另一列宽度自适应两列高度固定且相等。以下以左列宽度固定和右列宽度自适应为例,反之同理。

알아야 할 8가지 순수 CSS 레이아웃 기술

<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;
    }
}
三列布局

经典的三列布局左中右三列组成,其特点为连续两列宽度固定剩余一列宽度自适应三列高度固定且相等。以下以左中列宽度固定和右列宽度自适应为例,反之同理。整体的实现原理与上述两列布局一致。

알아야 할 8가지 순수 CSS 레이아웃 기술

<div class="three-column-layout">
    <div class="left"></div>
    <div class="center"></div>
    <div class="right"></div>
</div>

为了让右列宽度自适应计算,就不使用float + margin-left的方式了,若使用margin-left

메인 레이아웃

메인 레이아웃은 대부분의 상황에서 일반적이고 통일된 특성을 갖는 자리 표시자 레이아웃을 의미합니다. 메인레이아웃을 마스터하는 것은 프론트엔드의 필수 스킬입니다. 디자인 도면을 보고 전체적인 레이아웃을 대략적으로 기획하는 능력을 기르기 위해서는 이러한 의 특성과 구조를 잘 숙지해야 합니다. 메인 레이아웃 .

전체 화면 레이아웃

🎜Classic 🎜전체 화면 레이아웃🎜은 상단, 하단 및 본체는 세 부분으로 구성되어 있으며, 세 부분이 전체 화면으로 늘어납니다, 상하 높이가 고정되는 것이 특징입니다. code> 및 본체 높이가 조절됩니다 . 이 레이아웃은 매우 일반적이며 대부분의 웹 애플리케이션 본문의 주류 레이아웃이기도 합니다. 일반적으로 <header></header>, <footer></footer><main></main> 세 개의 태그가 <aside></aside> 사이드바나 기타 의미 태그를 삽입할 수도 있습니다. 🎜🎜알아야 할 8가지 순수 CSS 레이아웃 기술🎜
.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;
    }
}
🎜 🎜위치 + 왼쪽/오른쪽/상단/하단🎜🎜🎜세 부분은 left:0right:0을 선언하여 화면의 왼쪽과 오른쪽으로 늘립니다. 상단과 하단 각각 top:0bottom:0을 선언하여 상단과 하단을 흡수하고 두 높이를 고정 값으로 선언하여 본체의 top 및 bottom은 각각 상단 높이와 하단 높이로 선언됩니다. 세 부분은 서로 영향을 주지 않도록 절대 위치 지정을 통해 특정 위치에 고정됩니다. 🎜
.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🎜🎜🎜 flex를 사용하면 더 간결해집니다. display:flex는 기본적으로 자식 노드를 가로로 정렬합니다. 자식 노드의 정렬 방향을 세로 정렬로 변경하려면 flex-direction:column을 선언해야 합니다. 하단 높이가 고정되어 있으므로 flex:1높이를 가변적으로 선언해야 합니다. 🎜
<div class="grail-layout-x">
    <div class="left"></div>
    <div class="right"></div>
    <div class="center"></div>
</div>
🎜<main></main>를 스크롤 가능한 상태로 표시해야 하는 경우 컨테이너가 적응적으로 스크롤할 수 있도록 overflow:auto를 선언하지 마세요. 형식 지정 문제 컨텍스트의 영향으로 인해 적응형 스크롤이 실패하거나 다른 알 수 없는 효과가 발생할 수 있습니다. <main></main> 내에 <div>를 삽입하고 다음과 같이 선언해야 합니다. 🎜<pre class="brush:css;toolbar:false;">.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; } }</pre><h6 data-id="heading-5">🎜2열 레이아웃🎜</h6>🎜클래식 🎜2열 레이아웃🎜은 <code>왼쪽 열과 오른쪽 열로 구성되며 다음과 같은 특징이 있습니다. 한 열에는 고정 너비가 있고, 다른 열에는 적응형 너비가 있고 두 열에는 고정된 높이가 있습니다. 다음은 왼쪽 열의 고정 너비와 오른쪽 열의 적응형 너비를 예로 사용하며 그 반대의 경우도 마찬가지입니다. 🎜🎜알아야 할 8가지 순수 CSS 레이아웃 기술🎜
<div class="grail-layout-y">
    <div class="left"></div>
    <div class="right"></div>
    <div class="center">
        <div></div>
    </div>
</div>
🎜 🎜float + margin-left/right🎜🎜🎜왼쪽 열은 float:left 및 고정 너비를 선언합니다. float는 노드를 디플로우로 만들기 때문에 오른쪽 열은 margin -left는 두 열이 겹치지 않도록 왼쪽 열의 너비입니다. 🎜
.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🎜🎜🎜왼쪽 열은 위와 동일하게 선언하고, 오른쪽 열은 overflow:hidden을 선언하여 BFC 영역을 형성하고 이를 분리합니다. 외부 세계. 🎜
<div class="grail-layout">
    <div class="left"></div>
    <div class="center"></div>
    <div class="right"></div>
</div>
🎜🎜flex🎜🎜🎜 flex를 사용하면 더 간결해집니다. 왼쪽 열은 고정 너비를 선언하고 오른쪽 열은 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;
    }
}
🎜3열 레이아웃🎜
🎜클래식 🎜3열 레이아웃🎜은 왼쪽, 가운데, 오른쪽에 세 개의 열)으로 구성됩니다. >의 특징은 다음과 같습니다: code>연속된 두 열의 너비는 고정되어 있습니다, 나머지 열의 너비는 가변적입니다세 열의 높이는 고정되어 동일합니다. . 다음은 왼쪽 중간 열의 고정 너비와 오른쪽 열의 적응형 너비를 예로 들어 설명하며 그 반대의 경우도 마찬가지입니다. 전반적인 구현 원리는 위의 2열 레이아웃과 일치합니다. 🎜🎜알아야 할 8가지 순수 CSS 레이아웃 기술🎜
<div class="average-layout">
    <div class="one"></div>
    <div class="two"></div>
    <div class="three"></div>
    <div class="four"></div>
</div>
🎜 오른쪽 열의 너비를 적응적으로 계산하기 위해서는 float + margin-left 방식을 사용하지 않으며, margin-left를 사용하는 경우 반드시 계산해야 합니다. 왼쪽 중간 열의 너비와 함께. 🎜🎜🎜overflow + 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>被挤出的左右列使用floatmargin负值将其拉回与中间列处在同一水平线上
    <li>不同
      <li>圣杯布局:父节点声明padding为左右列留出空位,将左右列固定在空位上 <li>双飞翼布局:中间列插入子节点并声明margin为左右列让出空位,将左右列固定在空位上

알아야 할 8가지 순수 CSS 레이아웃 기술

圣杯布局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;">&lt;div class=&quot;grail-layout-y&quot;&gt; &lt;div class=&quot;left&quot;&gt;&lt;/div&gt; &lt;div class=&quot;right&quot;&gt;&lt;/div&gt; &lt;div class=&quot;center&quot;&gt; &lt;div&gt;&lt;/div&gt; &lt;/div&gt; &lt;/div&gt;</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;
    }
}
均分布局

经典的均分布局多列组成,其特点为每列宽度相等每列高度固定且相等。总体来说也是最简单的经典布局,由于每列宽度相等,所以很易找到合适的方式处理。

알아야 할 8가지 순수 CSS 레이아웃 기술

<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;
    }
}
居中布局

居中布局父容器若干个子容器组成,子容器在父容器中横向排列或竖向排列且呈水平居中或垂直居中。居中布局是一个很经典的问题,相信大家都会经常遇到。

알아야 할 8가지 순수 CSS 레이아웃 기술

在此直接上一个目前最简单最高效的居中方式。display:flexmargin: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.innerWdithwindow.innerHeight。若不考虑低版本浏览器兼容性,完全可用一行CSS代码秒杀所有移动端的伸缩方案。

/* 基于UI width=750px DPR=2的网页 */
html {
    font-size: calc(100vw / 7.5);
}

上述代码使用calc()实现font-size的动态计算。calc()自适布局里的核心存在,无它就不能愉快地实现自适布局所有动态计算了。

calc()用于动态计算单位,数值长度角度时间百分比都能作为参数。由于执行数学表达式后返回运算后的计算值,所以可减少大量人工计算甚至无需人工计算。

calc()饥不择食,所有计量单位都能作为参数参加整个动态计算。

  • 数值整数浮点数
  • 长度pxemremvwvh
  • 角度degturn
  • 时间sms
  • 百分比%

calc()虽然好用,但新手难免会遇到一些坑,谨记以下特点,相信就能玩转calc()了。

    <li>四则运算:只能使用+-*/作为运算符号 <li>运算顺序:遵循加减乘除运算顺序,可用()提升运算等级 <li>符号连接:每个运算符号必须使用空格间隔起来 <li>混合计算:可混合不同计量单位动态计算

第三点尤为重要,若未能遵守,浏览器直接忽略该属性。

上述font-size:calc(100vw / 7.5)其实就是根据设计图与浏览器视窗的比例动态计算font-size100/750 = x/100vw

在SPA里有遇过因为有滚动条或无滚动条而导致页面路由在跳转过程里发生向左或向右的抖动吗?这让强迫症患者很难受,此时可用calc()巧妙解决该问题。

.elem {
    padding-right: calc(100vw - 100%);
}

不直接声明padding-right为滚动条宽度是因为每个浏览器的默认滚动条宽度都可能不一致。100vw是视窗宽度,100%内容宽度,那么100vw - 100%就是滚动条宽度,声明padding-right用于保留滚动条出现的位置,这样滚动条出不出现都不会让页面抖动了。

有了calc()做保障就可迅速实现一些与视窗尺寸相关的布局了。例如实现一个视窗宽度都为50%的弹窗。

알아야 할 8가지 순수 CSS 레이아웃 기술

<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()也不一定结合视窗比例单位计算。例如自适布局已知部分节点高度,不想手动计算最后节点高度但又想其填充布局剩余空间。

알아야 할 8가지 순수 CSS 레이아웃 기술

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

吸附布局

吸附布局指相对视窗任何滚动都能占据特定位置的占位布局。视窗滚动到特定位置,布局固定在该位置,后续不随视窗滚动而滚动。该布局产生的效果俗称吸附效果,是一种常见网页效果。譬如吸顶效果吸底效果都是该范畴,经常在跟随导航移动广告悬浮提示等应用场景里出现。

jQuery 시대에는 흡착 효과 플러그인이 많이 있었습니다. 이제 세 가지 주요 프런트엔드 프레임워크에도 자체 타사 흡착 효과 구성 요소가 있습니다. 모두 공통 구현 원칙을 가지고 있습니다. scroll 이벤트를 수신하고, scrollTop대상 노드의 위치 범위를 결정하고, 를 설정합니다. > 조건이 충족되면 노드위치고정으로 선언하면 창을 기준으로 대상 노드의 위치가 지정됩니다. 사용자가 창의 특정 위치에 고정된 것처럼 보이게 합니다.

jQuery时代就有很多吸附效果插件,现在三大前端框架也有自身第三方的吸附效果组件。它们都有着共通的实现原理:监听scroll事件,判断scrollTop目标节点的位置范围,符合条件则将目标节点position声明为fixed使目标节点相对于视窗定位,让用户看上去就像钉在视窗指定位置上。

JS实现吸附效果的代码在网上一搜一大堆,更何况笔者喜欢耍CSS,在此就不贴相关的JS代码了。在此推荐一个很少见很少用的CSS属性position:sticky。简单的两行核心CSS代码就能完成十多行核心JS代码的功能,何乐而不为呢。

简单回顾position属性值,怎样用就不说了,大家应该都熟悉。

position 속성 값에 대한 간략한 리뷰입니다. 사용법은 따로 다루지 않겠습니다.
取值 功能 版本
inherit 继承 2
static 标准流 2
relative 相对定位 2
absolute 绝对定位 2
fixed 固定定位 2
sticky 粘性定位저자가 CSS를 가지고 노는 것을 좋아한다는 것은 말할 것도 없고 인터넷에 흡착 효과를 얻기 위한 JS용 코드가 많기 때문에 여기에는 관련 JS 코드를 게시하지 않겠습니다. 여기서는 거의 사용되지 않는 CSS 속성 position:sticky를 권장합니다. 간단한 두 줄의 핵심 CSS 코드10줄 이상의 핵심 JS 코드 기능을 완성할 수 있습니다.
상속상속
함수 버전
🎜2🎜🎜 🎜 정적 🎜🎜표준 흐름🎜🎜2🎜🎜 🎜상대🎜🎜상대 위치 지정🎜🎜2🎜🎜🎜절대🎜🎜절대 위치🎜🎜2🎜🎜 🎜고정🎜🎜고정 위치 🎜 🎜2🎜🎜 🎜고정🎜🎜고정 위치🎜🎜3🎜🎜🎜🎜

当值为sticky时将节点变成粘性定位粘性定位相对定位固定定位的结合体,节点在特定阈值跨越前为相对定位,跨越后为固定定位

알아야 할 8가지 순수 CSS 레이아웃 기술

<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:stickytop/bottom:npx。上述5个节点都声明position:sticky,但由于top/bottom赋值有所不同就产生不同吸附效果。

细心的同学可能发现这些节点在某些滚动时刻处于相对定位,在特定滚动时刻处于固定定位

    <li>第1个<li>top0px,滚动到容器顶部就固定 <li>第2个<li>top40px,滚动到距离容器顶部40px就固定 <li>第3个<li>:未声明top/bottom,就一直保持相对定位 <li>第4个<li>bottom40px,滚动到距离容器底部40px就固定 <li>第5个<li>bottom0px,滚动到容器底部就固定

当然,换成leftright也一样能实现横向的吸附效果

值得注意,粘性定位的参照物并不一定是position:fixed。当目标节点的任意祖先节点都未声明position:relative|absolute|fixed|sticky,才与position:fixed表现一致。当离目标节点最近的祖先节点声明position:relative|absolute|fixed|sticky目标节点就相对该祖先节点产生粘性定位。简单来说确认参照物的方式与position:absolute一致。

兼容性勉强还行,近2年发版的浏览器都能支持,SafariFirefox的兼容性还是挺赞的。有吸附效果需求的同学建议一试,要兼容IExplorer就算了。期待该属性有更好的发展,毕竟吸附布局真的是一种常见布局。

알아야 할 8가지 순수 CSS 레이아웃 기술

横向布局

横向布局指容器内节点以水平方向排列且溢出部分被隐藏的占位布局。竖向布局很常见,声明overflow:hidden;width:xpx;height:ypx就能实现,但横向布局却不能使用类似方式实现。

为了方便使用多种方式实现横向布局,以下将通用代码拆分出来。

알아야 할 8가지 순수 CSS 레이아웃 기술

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

凸显布局

凸显布局指容器内节点以同一方向排列且存在一个节点在某个方向上较突出的占位布局。该布局描述起来可能比较拗口,直接看以下效果吧,这是一个横向列表,节点从左往右排列,最右边的节点特别突出。这就是凸显布局的特征,凸显的节点可在凸显布局任意位置,上下左右左上左下右上右下都行。

1알아야 할 8가지 순수 CSS 레이아웃 기술

这里巧妙运用margin-*:auto实现了凸显布局。相信大家实现水平居中固定宽度的块元素都会使用margin:0 auto

在此同样原理,当节点声明margin-*:auto时,浏览器会自动计算剩余空间并将该值赋值给该节点。在使用该技巧时必须基于flex布局

1알아야 할 8가지 순수 CSS 레이아웃 기술

1알아야 할 8가지 순수 CSS 레이아웃 기술

1알아야 할 8가지 순수 CSS 레이아웃 기술

1알아야 할 8가지 순수 CSS 레이아웃 기술

<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的巧妙运用。这样组合让特殊位置的节点直接减少属性覆盖的问题,不仅易读还能装逼。

  • :not(:first-child):排除首节点,其他节点都使用某些样式
  • :not(: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

  • :nth-child(n):选择第n个元素
  • :nth-child(odd):选择奇数位置元素,相当于:nth-child(2n-1)
  • :nth-child(even):选择偶数位置元素,相当于:nth-child(2n)
  • :nth-child(xn):选择第x*n个元素
  • :nth-child(x-n):选择前x个元素
  • :nth-child(y-n):nth-child(n+x):选择第x~y个元素

分析间距布局的一切特点,捕获特征很有利于将特征转换成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个节点为例,最终效果为三行三列。

1알아야 할 8가지 순수 CSS 레이아웃 기술

알아야 할 8가지 순수 CSS 레이아웃 기술

<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才会触发。

  • 仅存在节点:<div><p>CSS</p></div>
  • 仅存在文本:<div>CSS</div>
  • 同时存在节点和文本:<div>Hello <p>CSS</p> </div>

알아야 할 8가지 순수 CSS 레이아웃 기술

<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,看着都尴尬。

알아야 할 8가지 순수 CSS 레이아웃 기술

没事,:empty帮你搞掂!对于无任何子节点的容器直接声明display:none解决所有无效占位,当然也可作用于指定节点。一招制敌,劲!

// 作用于所有节点
:empty {
    display: none;
}
// 作用于指定节点
.empty-layout:empty {
    display: none;
}

多格布局

多格布局指容器内节点以动态数量的格子形式排列的占位布局。微信朋友圈的相册就是最常见的多格布局了,当单张照片排列、两张照片排列、三张照片排列等等,每种情况下照片的尺寸都可能不一致。笔者制作了一个动态多格相册怀念我家狗狗AB。大家感受下纯CSS实现动态数量的多格布局吧。

在此留个悬念,不讲解如何实现,看看大家能不能根据笔者列出的提示尝试将该效果复原。主要原理是根据结构选择器限制节点范围实现,在本文也可找到原理的答案喔!记得实现完再看以下源码哈!

2알아야 할 8가지 순수 CSS 레이아웃 기술

<ul class="multigrid-layout">
    <li class="item"><img  src="https://static.yangzw.vip/codepen/ab-3.jpg" alt="알아야 할 8가지 순수 CSS 레이아웃 기술" ></li>
    <li class="item"><img  src="https://static.yangzw.vip/codepen/ab-3.jpg" alt="알아야 할 8가지 순수 CSS 레이아웃 기술" ></li>
    <li class="item"><img  src="https://static.yangzw.vip/codepen/ab-3.jpg" alt="알아야 할 8가지 순수 CSS 레이아웃 기술" ></li>
    <li class="item"><img  src="https://static.yangzw.vip/codepen/ab-3.jpg" alt="알아야 할 8가지 순수 CSS 레이아웃 기술" ></li>
    <li class="item"><img  src="https://static.yangzw.vip/codepen/ab-3.jpg" alt="알아야 할 8가지 순수 CSS 레이아웃 기술" ></li>
    <li class="item"><img  src="https://static.yangzw.vip/codepen/ab-3.jpg" alt="알아야 할 8가지 순수 CSS 레이아웃 기술" ></li>
    <li class="item"><img  src="https://static.yangzw.vip/codepen/ab-3.jpg" alt="알아야 할 8가지 순수 CSS 레이아웃 기술" ></li>
    <li class="item"><img  src="https://static.yangzw.vip/codepen/ab-3.jpg" alt="알아야 할 8가지 순수 CSS 레이아웃 기술" ></li>
    <li class="item"><img  src="https://static.yangzw.vip/codepen/ab-3.jpg" alt="알아야 할 8가지 순수 CSS 레이아웃 기술" ></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

更多编程相关知识,请访问:编程入门!!

위 내용은 알아야 할 8가지 순수 CSS 레이아웃 기술의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

firefox jquery css safari css3 html 前端框架 Float 运算符 auto 继承 class JS 事件 dom href 选择器 盒子模型 display position overflow margin padding border 伪元素 viewport background column flex li github https
성명:
이 기사는 juejin.cn에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제
이전 기사:CSS 계층 관계를 설정하는 방법다음 기사:CSS 계층 관계를 설정하는 방법

관련 기사

더보기