【每日一题】实现一个圣杯布局(及其引发的Flex布局新认识)

引言

昨日看牛客面经,看到一个面试题:实现一个圣杯布局,也正好是我刚看了阮老师Flex布局教程中有对圣杯布局的描述,我当时并没有实现,但看来还是要老老实实动手去实现一下,写的过程我也对 flex:1 进行了一些探索和得到一些新的认识。

圣杯布局

圣杯布局(Holy Grail Layout)指的是一种最常见的网站布局。页面从上到下,分成三个部分:头部(header),躯干(body),尾部(footer)。其中躯干又水平分成三栏,从左到右为:导航、主栏、副栏。

我实现的圣杯布局

弹性盒模型实现

我是按照阮老师的示例,采用Flex布局实现,大体相同,有些细节部分不一样
HTML代码如下:

 <body class="HolyGrail">
    <header>#header</header>
    <div class="HolyGrail-body">
      <main class="HolyGrail-content">#center</main>
      <nav class="HolyGrail-nav">#left</nav>
      <aside class="HolyGrail-ads">#right</aside>
    </div>
    <footer>#footer</footer>
  </body>

CSS代码如下:

	* {
      margin: 0;
    }

    .HolyGrail {
      display: flex;
      min-height: 100vh; /*撑满整个屏幕*/
      flex-direction: column; /* 头、中部、脚纵向显示 */
    }

    header,
    footer {
      height: 60px; /*设置一个固定的高度*/
      background: rgba(29, 27, 27, 0.726);

      /* 用于字体居中,不是重点 */
      line-height: 60px;
      text-align: center;
      color: white;
    }

    .HolyGrail-body {
      display: flex;
      flex: 1;
    }

    .HolyGrail-content {
      flex: 1;
      background: rgb(206, 201, 201);
    }

    .HolyGrail-nav,
    .HolyGrail-ads {
      /* 两个边栏的宽度设为12em,定宽 */
      flex: 0 0 12em;
    }

    .HolyGrail-nav {
      /* 导航放到最左边 */
      order: -1;
      background: rgba(95, 179, 235, 0.972);
    }

    .HolyGrail-ads {
      background: rgb(231, 105, 2);
    }

    /*如果是小屏幕,躯干的三栏自动变为垂直叠加。*/
    @media (max-width: 768px) {
      .HolyGrail-body {
        flex-direction: column;
        flex: 1;
      }
      .HolyGrail-nav,
      .HolyGrail-ads,
      .HolyGrail-content {
        flex: auto;
      }
    }

布局理解

①首先是HolyGrail ,给整个body设置flex布局方式,同时设置属性flex-direction: column使得头部(header),躯干(body),尾部(footer)从上到下纵向显示
②对于header和footer,给一个固定的高度
③对于HolyGrail-body(躯干部分),整体设置为flex布局方式
④对于主栏,可以伸缩
⑤对于导航栏和副栏,定宽

flex:1的奥秘

想必看了阮老师的教程都发现在圣杯布局的示例中他用了flex:1写法,但是在他的教程中并没有对其阐述,博主当时也是比较纳闷,所以便去查阅了很多资料,但是网上很多博文水平参差不齐,出入很大,最终还是回到了MDN去查官方的文档。

请看下面MDN官方文档:
在这里插入图片描述

由MDN文档可知,设置 flex:1相当于flex:1 1 0,浏览器会按照flex:1 1 0的写法来渲染样式。

flex属性的前两个参数分别是flex-grow属性和flex-shrink属性,均设置为1,即表示该项目可以放大和缩小即可以伸缩。

那么flex属性的第三个参数设置为0又表示什么呢?
flex属性的第三个参数是flex-basis属性

flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。

auto 表示项目本身的大小, 如果设置为 auto, 那么盒子就会按照自己内容的多少来等比例的放大和缩小,

那我们如果设置为0, 那么他就不会按项目本身来计算, 所以它不关心内容, 只是把空间等比收缩和放大
在这里插入图片描述

上图是MDN的官方实例,注意Chrome浏览器会自动在0后面添加一个px像素单位,用其他浏览器打开可能会发现后面添加的是%,这些都是浏览器自动添加的后缀不会产生其他影响。

注:
①两个边栏的宽度设为12em,em是一个相对单位,是当前元素相对于父元素字体的大小而言的,在不设置字体大小的情况下,浏览器默认字体大小为16px,此时1em=16px,所以12em相当于192px
②CSS3新属性之min-height: 100vh;
vh: 相对于视窗的高度, 视窗被均分为100单位的vh;
vw: 相对于视窗的宽度, 视窗被均分为100单位的vw;
所以给body设置min-height: 100vh可以使所有盒子撑满整个屏幕。

写在最后

当网上的文章过于纷杂,乱花渐欲迷人眼的时候,去看一些权威的文档、源码才是正确的选择,这样才能保持一个清醒的头脑和清晰的认知。
MDN Web 文档

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值