稀土掘金 稀土掘金

从display理解布局原理

布局是基于文档流、盒模型的概念,当我们关注实际渲染效果时候,需要注意 盒子模型(客体)、以及盒子模型内部的环境也就是格式化上下文

在普通流中,所有的盒子(内联盒子、块级盒子都各自属于一个自己的格式化上下文,格式化上下文即控制元素如何进行布局)。

格式化上下文:元素的边距、边框和填充如何与同一上下文中的其他块交互
块格式化上下文 block formatting contexts
内联格式化上下文 inline formatting contexts
灵活格式化上下文 flex formatting contexts(flex、grid)

盒模型

在这里插入图片描述

CSS3 box-sizing 属性定义了应该如何计算一个元素的总宽度和总高度。
取值:content-box | padding-box | border-box

默认值content-box 标准盒子模型:width 与 height 只包括内容的宽和高,不包括border、padding、margin

.box {width: 350px; border: 10px solid black;} 

在浏览器中的渲染的实际宽度(包括边框)将是 370px
所以此时如果两个子元素分父元素的宽度,30%+70%最终大于父元素
怎么解决:calc(30%-超出的宽度)、用负值margin去补足容器缺口 IE盒模型border-box更为稳健,现在最著名的CSS框架几乎都采用了border-box
width = content + padding + border

display

display 属性可以设置元素的内部和外部显示类型

  • 元素的外部显示类型 outer display types 决定元素自己在流式布局中的表现(块级、内联元素、行内块元素、即inline、block、inline-block)
  • 元素的内部显示类型 inner display types 控制子元素的布局(例如:flow layout、grid、flex)
.container {
  display:  [ <display-outside> | <display-inside> ] | <display-listitem> | <display-internal> | <display-box> | <display-legacy> ;
  writing-mode: vertical-rl   |   horizontal-tb;
}

补充display:none
vue 的 if-show 的底层代码就是通过display:none实现

  • display :none 元素不会占据它本来应该显示的空间
  • visibility : hidden会占据空间 display :none + fixed实现弹窗
<!doctype html>
<head>
  <style>
    body {
      min-height: 200vh;
      margin: 0;
    }

    button {
      padding: .5em .7em;
      border: 1px solid #8d8d8d;
      background-color: white;
      font-size: 1em;
    }

    .top-banner {
      padding: 1em 0;
      background-color:  rgba(0, 0, 0, 0.5);
    }

    .top-banner-inner {
      width: 80%;
      max-width: 1000px;
      margin: 0 auto;
    }
/*弹窗*/
    .modal {
      display: none;
    }
/*弹窗de 用来遮住剩余页面,将用户注意力集中*/
    .modal-backdrop {
      position: fixed;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      background-color: rgba(0, 0, 0, 0.5);
    }

    .modal-body {
      position: fixed;
      top: 3em;
      bottom: 3em;
      right: 20%;
      left: 20%;
      padding: 2em 3em;
      background-color: white;
      overflow: auto;
    }

    .modal-close {
      cursor: pointer;
    }
  </style>
</head>

<body>
  <header class="top-banner">
    <div class="top-banner-inner">
        <button id="open">open</button>
    </div>
  </header>
  <div class="modal" id="modal">
    <div class="modal-backdrop"></div>
    <div class="modal-body">
      <button class="modal-close" id="close">close</button>
      <h2>弹窗标题</h2>
      <p>message</p>
      <form>
        <p>
          <label for="email">Email address:</label>
          <input type="text" name="email"/>
        </p>
      </form>
    </div>
  </div>

  <script type="text/javascript">
    const openBtn = document.getElementById('open');
    const closeBtn = document.getElementById('close');
    const modal = document.getElementById('modal');

    openBtn.addEventListener('click', function(event) {
        event.preventDefault();//阻止元素发生默认的行为
        modal.style.display = 'block';//显示弹窗
    });

    closeBtn.addEventListener('click', function(event) {
        event.preventDefault();
        modal.style.display = 'none';
    });

  </script>
</body>

outer display types

ps另一个思路理解浮动,既能设置宽高,又能跟其他元素处于同一行

块级元素

  1. 总是从新行开始
  2. width、height、margin、padding都可以控制
  3. 可以容纳内联元素和其他块元素
  4. 相邻两个块级盒子之间的垂直间距会遵循外边距折叠原则被折叠,由max-margin决定
  5. 每个盒子的左外边缘会与包含块左边缘重合。如果是从右到左的排版顺序,则盒子的右外边缘与包含块右边缘重合
  6. 宽度默认是父元素内容的100%
html
body
iframe
title
hr
dl、dt、dd
<h1></h1>
...
<h6></h6>
<div></div>
<p></p>
<ul></ul>
<ol></ol>
<li></li>

IE会将main元素渲染成行内元素,而不是块级元素。所以在CSS中我们需要修正

行内元素

  1. 宽度默认是自己内容的宽度
  2. 行内元素只能容纳文本或其他行内元素。
  3. 和相邻行内元素在一行上(父不够子先继续填满,一个元素会被拆成两行)
  4. width、height无效,单水平方向的padding和margin有边距效果
<span></span>
<u></u>
<ins></ins>
<s></s>
<del></del>
<i></i>
<em></em>
<b></b>
<strong></strong>
<a></a>

行内块元素

  1. 即不独占一行的块级元素
  2. 相比行内元素中有几个特殊的标签,可以设置宽高width、height、margin、padding、对齐属性
  3. 默认宽度就是他本身内容的宽度
  4. 相邻行内块在一行上,但是之间会有空白间隙(父不够子到下一行)
<img/>
<textarea>...</textarea>
<button>..</button>
<input>
<br>
<label>...</label>
<select>...</select>
<canvas>...</canvas>
<progress>...</progress>
<cite>...</cite>
<code>...</code>
<audio>...</audio>
<video>...</video>

BFC block formatting context

前端中原本定义了box模型,但是元素会影响其他元素的布局。这时候就出现了BFC,元素会脱离常规流 ,创建一个新的BFC形成独立空间,里面的元素和外面的元素不会彼此影响

触发BFC的条件: 意味着使用块布局,修改display值的计算值

  • 根元素或包含根元素的元素:display: flow-root list-item
  • 浮动元素 :元素的 float 不是 none
left | right | none | inline-start | inline-end
  • 绝对定位元素:元素的 position 为 absolute 、sticky、 fixed
  • 行内块元素
  • 表格单元格 display:table-* 属性的所有表格单元格

表格单元格table-cell
表格标题table-caption
匿名表格单元格元素
table、table-row、table-row-group、table-header-group、table-footer-group(分别是HTML中table、row、tbody、thead、tfoot的默认属性)

  • 元素属性 contain(部分浏览器支持): layout、content、strict
  • overflow 值不为 visible 的块元素
  • 弹性元素:display为 flex 或 inline-flex元素的直接子元素
  • 网格元素:display为 grid 或 inline-grid 元素的直接子元素
  • 多列容器:column-count 或 column-width 不为 auto,包括 column-count 为 1
.container {
    column-width: 200px;
    column-count: 3;
}

元素属性 column-span 设置为 all:使元素横跨所有列

多列布局 - 学习 Web 开发 | MDN (mozilla.org)

使用场景

父元素的高度塌陷

父元素大小受子元素影响,当子元素都设置为浮动,浮动的子元素脱离了文档流,被提起来形成了新的队列,下方普通队列(父元素)无法触及它,检测不到它的存在无法被他撑开,父元素的高度可能会塌陷
方法:

  1. 对父元素触发BFC 触发了BFC的容器就是页面上一个完全隔离开的容器,容器中的元素绝对不会影响到外面的元素
    为了保证上述规则,在计算父元素的高度时必须让浮动的子元素参与进来。
  • 浮动布局的核心就是让元素脱离普通流,然后使用width/height,margin/padding将元素定位。
  • absolute定位的基准是最近的非static定位父对象,而fixed是相对html根节点的定位。两种定位都会脱离普通流
  • 所以父元素为relative,子元素为absolute,也会出现跟浮动一样的问题:父对象高度坍塌,子元素不能撑起父对象。
  1. 对浮动元素后面的元素 clearfix,使用伪类:before 父元素class属性值含 clearfix
    .clearfix:before,.clearfix:after { 
      content:".";
      display:table;
    }
    .clearfix:after {
     clear:both;
    }
    .clearfix {
      *zoom:1;
    }

清除浮动的理解:拉回文档流。取消“浮动元素的浮动效果”对其他元素造成的影响。IE⑥⑦不兼容

margin包含塌陷、重叠塌陷

margin在垂直方向取最大值

  • 包含塌陷:给容器触发BFC
  • 重叠塌陷:用容器包裹元素,给容器触发BFC

CSS3的多列属性

image.png

display:grid

display:grid 该元素成为一个网格容器,它的子元素成为网格元素。

所有网格元素必须是网格容器的直接子节点

定义网格轨道

新属性定义网格轨道: fr每一列的权重 支持函数repeat

grid-template-rows: 1fr 1fr;
//等同于
grid-template-rows:repeat(2,1fr );
grid-template-columns: 2fr 1fr 1fr 3fr;
//等同于
grid-template-columns: 2fr repeat(2,1fr ) 3fr;
<!doctype html>
<head>
  <style>
  :root {
    box-sizing: border-box;
  }

  *,
  ::before,
  ::after {
    box-sizing: inherit;
  }

  .grid {
    display: grid;
    grid-template-columns: 1fr 2fr 1fr;
    grid-template-rows: 1fr 1fr;
    grid-gap: 0.5em;
  }

  .grid > * {
    background-color: darkgray;
    color: white;
    padding: 2em;
    border-radius: 0.5em;
  }
  </style>
</head>
<body>
  <div class="grid">
    <div class="a">a</div>
    <div class="b">b</div>
    <div class="c">c</div>
    <div class="d">d</div>
    <div class="e">e</div>
    <div class="f">f</div>
  </div>
</body>

隐式网格

上面显式定义了一个网格,在实际DOM中如果元素多于网格数会自动扩充网格,这就是隐式网格
设置隐式网格的默认大小值:

grid-auto-rows: 1fr;
grid-auto-colums: 1fr;

指定元素所占位置

grid-column: 1 / 3;

在前面代码的基础上加入

 .a{
        grid-column: 1 / 3;
  }

页面变化为 在这里插入图片描述

补充语法

命名网格线

.container {
    display: grid;
    grid-template-columns: [left-start] 2fr
                           [left-end right-start] 1fr
                           [right-end];
    grid-template-rows: repeat(4, [row] auto);
    grid-gap: 1.5em;
    max-width: 1080px;
    margin: 0 auto;
  }

  header,
  nav {
    grid-column: left-start / right-end;
    grid-row: span 1;
  }

  .main {
    grid-column: left;
    grid-row: row 3 / span 2;
  }

  .sidebar-top {
    grid-column: right;
    grid-row: 3 / 4;
  }

命名网格区域

网格区域必须组成一个矩形 .作为名称 代表空出一个网格

.container {
    display: grid;
    grid-template-areas: "title title"
                         "nav   ."
                         "main  aside1"
                         "main  aside2";
    grid-template-columns: 2fr 1fr;
    grid-template-rows: repeat(4, auto);
    grid-gap: 1.5em;
    max-width: 1080px;
    margin: 0 auto;
  }

特性查询

CSS查看浏览器支持特性与否 回退样式在特性查询之外

 @supports (display: grid) {
      .portfolio {
        display: grid;
        grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
        grid-auto-rows: 1fr;
        grid-gap: 1em;
        grid-auto-flow: dense;
      }
    }
    //抑或是
     @supports not(display: grid){}
     @supports (display: grid) or (display: table){} 
     @supports (display: grid) and (display: table){} 

设置不同的网格大小

给部分元素占多个网格区域

.portfolio .featured {
      grid-row: span 3;
      grid-column: span 3;
    }

在这里插入图片描述在这里插入图片描述

这种变化是默认 grid-auto-flow:row;

display:flex

Flex 布局教程:语法篇 - 阮一峰的网络日志 (ruanyifeng.com) 传统布局基于盒状模型,依赖 display 属性 + position属性 + float属性。09年,W3C提出Flex布局

利用弹性盒子写一个菜单栏

首先一个简单的例子 在这里插入图片描述

在这里插入图片描述

/*外部容器设置为弹性*/
    .site-nav {
      display: flex;
      padding: .5em;
      background-color: #5f4b44;
      list-style-type: none;
      border-radius: .2em;
    }

    .site-nav > li {
      margin-top: 0;
    }

    .site-nav > li > a {
      display: block;
      padding: .5em 1em;
      background-color: #cc6b5a;
      color: white;
      text-decoration: none;
    }
    /*所有块的左部外边距*/
    .site-nav > li + li {
      margin-left: 1.5em;
    }
   /*设置最后一块的左部外边距为auto来让他填满容器,实现靠右的效果*/
    .site-nav > .nav-right {
      margin-left: auto;
    }

基础知识

display:flex 该元素成为弹性容器,他的子元素成为弹性子元素,flex容器存在方向不同的两条轴,主轴和交叉轴。项目主轴大小:子元素占据主轴方向上的长度。 子元素的float、clear、vertical-align失效。

.box{
  display: flex;
}

.box{
  display: inline-flex;
}

.box{
  display: -webkit-flex; /* Webkit内核的浏览器,必须加上-webkit前缀,Safari */
  display: flex;
}

属性

容器属性

flex-flow属性:flex-direction+flex-wrap

默认值:row nowrap

  • flex-direction 主轴的方向即项目的排列方向
flex-direction:row;//默认控制子元素从左到右
column、row-reverse、column-reverse

在垂直的弹性盒子里,flex的收缩属性不会起作用

  • flex-wrap指定弹性元素是否会在容器内折行显示 默认,项目都排列在轴线上,如果超出一行,该属性定义如何换行
nowrap不换行
wrap换行,下一行在下方
wrap-reverse换行,下一行在上方
启用之后,flex-shrink无效,元素不再收缩,直接折行

justify-content、align-content、align-items

对齐方式会影响间距效果

justify-content 当元素没有填满,控制元素沿主轴方向上的等间距 在这里插入图片描述 align-content属性值同justify-content,定义多根交叉轴线的对齐方式,即多行情况下的对齐。 在这里插入图片描述

align-items 包含块中在交叉轴方向上的对齐方式。 在这里插入图片描述子元素提供了align-self属性来覆盖align-item属性

子元素属性

  • 子元素的float、clear、vertical-align失效。
  • 弹性子元素像块级元素一样填充可用宽度,但是弹性子元素不一定填满其弹性容器的宽度
  • 弹性子元素高度相等,高度由他们的内容决定。(换一个主轴方向就是等宽列)
  • 本质上是因为控制副轴上的属性align-items、align-content的初始值是stretch
  • 将弹性子元素的margin设置为auto后,就可以实现子元素相对弹性容器居中。

order属性

定义项目排列顺序: 值越小越前,默认值为0

简写属性flex = (flex-basis, flex-grow, flex-shrink)

  • flex-basis
元素大小的基准值
作用于宽度还是高度取决于flex-direction
px、em、百分比
  • flex-grow
非负整数,子元素的盒模型占据之后的容器宽度可能会有留白
留白会将增长因子视作权重来分给子元素
0代表不增长
  • flex-shrink
子元素的盒模型占据之后的容器宽度可能不足
0代表不缩水

flex实现网页布局

在这里插入图片描述

<!doctype html>
<head>
  <style>
    :root {
      box-sizing: border-box;
    }

    *,
    ::before,
    ::after {
      box-sizing: inherit;
    }

    body {
      background-color: #709b90;
      font-family: Helvetica, Arial, sans-serif;
    }

    body * + * {
      margin-top: 1.5em;
    }

    .container {
      max-width: 1080px;
      margin: 0 auto;
    }

    .site-nav {
      display: flex;
      padding: .5em;
      background-color: #5f4b44;
      list-style-type: none;
      border-radius: .2em;
    }

    .site-nav > li {
      margin-top: 0;
    }

    .site-nav > li > a {
      display: block;
      padding: .5em 1em;
      background-color: #cc6b5a;
      color: white;
      text-decoration: none;
    }

    .site-nav > li + li {
      margin-left: 1.5em;
    }

    .site-nav > .nav-right {
      margin-left: auto;
    }

    .tile {
      padding: 1.5em;
      background-color: #fff;
    }

    .flex {
      display: flex;
    }

    .flex > * + * {
      margin-top: 0;
      margin-left: 1.5em;
    }

    .column-main {
      flex: 2;
    }

    .column-sidebar {
      flex: 1;
      display: flex;
      flex-direction: column;
    }

    .column-sidebar > .tile {
      flex: 1;
    }

  
    .login-form h3 {
      margin: 0;
      font-size: .9em;
      font-weight: bold;
      text-align: right;
      text-transform: uppercase;
    }

    .login-form input:not([type=checkbox]):not([type=radio]) {
      display: block;
      margin-top: 0;
      width: 100%;
    }

    .login-form button {
      margin-top: 1em;
      border: 1px solid #cc6b5a;
      background-color: white;
      padding: .5em 1em;
      cursor: pointer;
    }

  </style>
</head>

<body>
  <div class="container">
    <header>
      <h1>Ink</h1>
    </header>
    <nav>
      <ul class="site-nav">
        <li><a href="/">Home</a></li>
        <li><a href="/features">Features</a></li>
        <li><a href="/pricing">Pricing</a></li>
        <li><a href="/support">Support</a></li>
        <li class="nav-right">
          <a href="/about">About</a>
        </li>
      </ul>
    </nav>
    <main class="flex">
      <div class="column-main tile">
        <h1>Team collaboration done right</h1>
        <p>Thousands of teams from all over the
          world turn to <b>Ink</b> to communicate
          and get things done.</p>
      </div>
     
      <div class="column-sidebar">
        <div class="tile">
        
        <form class="login-form">
            <h3>Login</h3>
            <p>
              <label for="username">Username</label>
              <input id="username" type="text"
                name="username"/>
            </p>
            <p>
              <label for="password">Password</label>
              <input id="password" type="password"
                name="password"/>
            </p>
            <button type="submit">Login</button>
          </form>

        </div>
        <div class="tile centered">
          <small>Starting at</small>
          <div class="cost">
            <span class="cost-currency">$</span>
            <span class="cost-dollars">20</span>
            <span class="cost-cents">.00</span>
          </div>
          <a class="cta-button" href="/pricing">
            Sign up
          </a>
        </div>
      </div>
    </main>
  </div>
</body>

玻璃钢生产厂家购物商场美陈玻璃钢雕塑的性能广州半马人玻璃钢雕塑五华区玻璃钢雕塑加工厂多少钱2019新年商场美陈河北通道商场美陈订购广西玻璃钢泡沫雕塑厂家南沙玻璃钢人物雕塑在线下单玻璃钢卡通人物雕塑工程温州抽象玻璃钢园林雕塑昭通市玻璃钢雕塑厂家宣威市玻璃钢雕塑设计哪里买人物玻璃钢雕塑哪家强滁州卡通玻璃钢雕塑厂玻璃钢浮雕城市雕塑厂沈丘玻璃钢雕塑费用海伦玻璃钢牌匾雕塑新乡玻璃钢雕塑图片古代玻璃钢名医雕塑厂家浮雕迎丰收玻璃钢雕塑镜面玻璃钢雕塑价格行情商场创意商业美陈服务霍州玻璃钢长颈雕塑校园文化玻璃钢雕塑四川商场美陈供货商营口玻璃钢浮雕人物山水雕塑甘南城市玻璃钢雕塑价格雕塑 玻璃钢 宁波沈阳玻璃钢花盆西藏商场美陈报价香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化