css几种高效方案如何适配首屏可视区域

在我们的业务中,我们遇到比较通用的布局,上中下上左中下以及更为复杂的结构,在一些常用交互设计上,我们究竟选择何种布局方案,最后都会产生不同的效果,在用户体验上来看也会千差万别。本文是一篇通用业务场景的解决方案,希望能带来一些思考和帮助。

正文开始…

上中下

这是我们在C端常见的一种主体结构,什么意思?我们看下下面这种结构

我们从以上结构来看,内容始终是在我们设置的可视区域内部,如果内容很多,则会产生滚动条,headerfooter始终是在整屏的顶部和底部。我们思考下为何会有种需求?按照正常文档流结构,我们的内容区域如果很多,底部就会被自动撑到非可视区域,并且我们的header也会随着内容滚动而被隐藏了。

我们针对不同的场景,我们说下为什么固定header与footer相比较不固定体验会好很多。

  • 固定header与footer,内容滚动

在首屏能看到整个网页的内容Headerfooter,无论内容是否多少,headerfooter始终能被用户看到,且用户在滚动内容区域,非常快捷的切换其他tab

  • 不固定header与footer,内容不滚动,随着内容有多少就撑多少

这种比较简单,基本不用我们特殊处理,也就是内容有少就会展示多少,并且footer会贴着内容展示,并且当内容足够多时,当我们滑动到底部时,header会看不见,这是一种不好的体验。

那如何实现首屏始终固定HeaderFooter,内容始终在满屏滚动呢

  • 方案一:flex实现

我们先看下页面结构

   <div class="app">
      <header>
          <div class="home">Home</div>
          <div class="web">web技术学苑</div>
          <div class="about">about</div>
          <div class="login">登录</div>
      </header>
      <main>
          <div>公众号:Web技术学苑</div>
          <div>https://learn.wmcweb.cn</div>
      </main>
      <footer>
          MIT Licensed | Copyright © 2022-present Maic
      </footer>
    </div>

对应的css如下

 * {

      padding: 0;


      margin: 0;


    }

    html, body {
        height: 100%;
    }

    .app {
        display: flex;

        flex-direction: column;
        height: 100%;
    }
    main {
      flex:1;
      padding: 0 20px;
    }

   header {
        display: flex;
        height: 50px;
        align-items: center;
        padding: 0 20px;
    }
  footer {
        padding: 0 20px;
        height: 30px;
    }

    header >div {
        padding: 0 5px;
    }

    .web {
        color: green;
    }
    .about {
       flex:1;
       display: flex;
       justify-content: flex-end;
    }
  

在以上对应的结构里我们发我们对.app设置了flex,但是flex-direction:column主轴方向众向排列,因为我们的headerfooter是固定高度,我们给了main设置了flex:1,并且我们将html,body以及.app的高度设置成了100%,我们知道子级设置高度百分比会继承父级的高度

不知道你有没有发现在header中我们的结构是下面这样简单单一的结构

 <header>

    <div class="home">Home</div>
    <div class="web">web技术学苑</div>
    <div class="about">about</div>
    <div class="login">登录</div>
  </header>

但是你会发现,我要实现的效果是左右这样的布局结构,我并没有将头部布局变成左右结构,而是利用flex,单独设置了aboutflex为1,并单独设置了它自己的样式,思考下是不是比下面这样的结构要简单,简单的结构,样式会少很多,并且可拓展性会更好点

 <header>

     <div class="left">
        <div class="home">Home</div>

        <div class="web">web技术学苑</div>

      </div>
      <div class="right">
          <div class="about">about</div>
          <div class="login">登录</div>
      </div>
  </header>

我们看下最终的效果

现在我们填充多一些内容

你会发现内容滚动头部会被隐藏,并没有达到我们想要的效果,那有什么办法可以解决这个问题呢?

我们知道产生滚动条的本质原因是,内容溢出了,在可视区域内容超出,就会产生滚动条,这个滚动条此时作用在body上的

所以我们只需要把滚动控制在内容区域即可

  main {
    flex:1;
    padding: 0 20px;
    height: calc(100vh - 80px);
    overflow-y: auto;
 }

在main上我们设置了固定高度,此时我们利用了一个calc的css计算,设置中间内容的固定高度就是calc(100vh - 80px),80px是header与footer的高度,所以最后的效果就是下面这样的

注意我们给about设置了flex:1所以它承载了剩余的空间,并且我们单独将她设置成flex,并且居右排列

  • 方案2: grid实现

我们在以上使用flex实现了我们需要的效果,但实际上grid实现更灵活

  <div class="app">
    <header>
        <div class="home">Home</div>

        <div class="web">web技术学苑</div>

        <div class="about">about</div>
        <div class="login">登录</div>
    </header>
    <main>
        <div>公众号:Web技术学苑</div>
        <div>https://learn.wmcweb.cn</div>
        <div id="content"></div>
    </main>
    <footer>
        MIT Licensed | Copyright © 2022-present Maic
    </footer>
  </div>

对应的css

  * {

        padding: 0;
        margin: 0;
    }

    .app {
        display: grid;
        grid-template-rows: 50px 1fr 30px;
    }
    main {
        padding: 0 20px;
        height: calc(100vh - 80px);
        overflow-y: auto;
    }
   header {
       display: grid;
       grid-template-columns: repeat(16,minmax(50px, 1fr));
       align-items: center;
       padding: 0 20px;;
    }
    footer {
        padding: 10px 20px;

    }
    header >div {
        padding: 0 5px;
    }

    .web {
        color: green;
    }

    .about {
        grid-column: 15;
        display: flex;
        justify-content: flex-end;
    }
    .login {
        grid-column: 16;
        display: flex;
        justify-content: flex-end;
    }

注意我们并没给html,body设置高度,我们在app上设置了grid,并且设置了grid-template-rows: 50px 1fr 30px,同样的,我们将滚动条放在了main上,并设置了overflow-y:auto

效果与flex是一样的

  • 方案3: 定位
    定位的元素是脱离文档流的,但是我们可以将内容定位控制,footer可以是absolute或者fixed
 * {

    padding: 0;
    margin: 0;
}
.app {
    position: relative;
}
main {
    padding: 0 20px;
    height: calc(100vh - 80px);
    overflow-y: auto;
    position: absolute;
    top: 50px;
    bottom: 30px;
    left:0;
    right: 0;
}
header {
   display: flex;
   align-items: center;
   padding: 0 20px;;
   height: 50px;
}
footer {
    padding: 10px 20px;
    position: fixed;
    bottom: 0;
}
header >div {
    padding: 0 5px;
}
.web {
    color: green;
}
.about {
    flex:1;
    display: flex;
    justify-content: flex-end;
}
.login {
    display: flex;
    justify-content: flex-end;
}

上左中下

在我们了解上中下结构后,我们在中台项目,这种结构是非常统一的

面对这种通用的结构,布局的方式有很多,但是我们通常来说一般顶部粘性,然后内容滚动,底部会随着内容并不固定在首屏

  • 方案1:grid实现
 <div class="app">
  <header>


      <div class="home">Home</div>


      <div class="web">web技术学苑</div>


      <div class="about">about</div>


      <div class="login">登录</div>


  </header>


  <slide>
      <div>菜单1</div>
      <div>菜单2</div>
  </slide>
  <main>
      <div>公众号:Web技术学苑</div>
      <div>https://learn.wmcweb.cn</div>
      <div id="content"></div>
  </main>
  <footer>
      MIT Licensed | Copyright © 2022-present Maic
  </footer>
</div>

对应的css

  * {

      padding: 0;


      margin: 0;


  }

  .app {
      display: grid;
      grid-template-columns: 100px 1fr 1fr 1fr;
      grid-template-rows: 50px 1fr 30px;
  }

 header {
      grid-column: 1/5;
     display: flex;
     align-items: center;
     padding: 0 20px;;
     height: 50px;
     background-color: yellow;
  }
  slide {
      padding: 0 20px;
      background-color: green;
  }


  main {
      grid-column: 2/5;
      padding: 0 20px;
      height: calc(100vh - 80px);
      overflow-y: auto;
      padding: 0 20px;
      background-color: pink;
  }


  footer {
      padding: 10px 20px;
      grid-column: 1/5;
  }
  header >div {
      padding: 0 5px;
  }
  .web {
      color: green;
  }
  .about {
      flex:1;
      display: flex;
      justify-content: flex-end;
  }
  .login {
      display: flex;
      justify-content: flex-end;
  }

最后的结果

  • 方案2:flex

我们看下结构

<div class="app">

  <header>


      <div class="home">Home</div>


      <div class="web">web技术学苑</div>


      <div class="about">about</div>


      <div class="login">登录</div>


  </header>


  <main>

      <div class="slide">

          <div>菜单1</div>

          <div>菜单2</div>

      </div>

      <div class="content-box">

          <div>公众号:Web技术学苑</div>

          <div>https://learn.wmcweb.cn</div>

          <div id="content"></div>

      </div>

  </main>

  <footer>

      MIT Licensed | Copyright © 2022-present Maic

  </footer>

  </div>

对应的css

header {
       display: flex;
       align-items: center;
       padding: 0 20px;;
       height: 50px;
       background-color: yellow;
    }

    main {
        display: flex;

    }
    .slide {
        width: 100px;
        height: calc(100vh - 80px);
        background-color: green;
        padding-left: 20px;
    }

   .content-box {
    flex:1;
    height: calc(100vh - 80px);
    overflow-y: auto;
    background-color: pink;
   }
    footer {
        padding: 10px 20px;
    }
...
  • 方案3:普通的布局结构

我们尝试用普通的布局结构去实现我们的需求,相比较grid,flex布局,你会发现传统的布局代码量会产生很多

<div class="app">

  <header>


      <div class="home">Home</div>


      <div class="web">web技术学苑</div>


      <div class="about">about</div>


      <div class="login">登录</div>


  </header>


  <main>

      <div class="slide">

          <div>菜单1</div>

          <div>菜单2</div>

      </div>

      <div class="content-box">

          <div>公众号:Web技术学苑</div>

          <div>https://learn.wmcweb.cn</div>

          <div id="content"></div>

      </div>

  </main>

  <footer>

      MIT Licensed | Copyright © 2022-present Maic

  </footer>

  </div>

你会发现首先我们内容区域的结构就变得相对复杂了些,但也没有那么特别复杂,我们再来看看css

* {
      padding: 0;


      margin: 0;


  }

header {
   display: flex;
   align-items: center;
   padding: 0 20px;;
   height: 50px;
   background-color: yellow;
}
main {
    position: relative;
}
.slide {
      position: absolute;
      left:0px;
      width: 100px;
      height: calc(100vh - 80px);
      background-color: green;
      padding-left: 20px;
  }

 .content-box {
  padding-left:120px;
  width: calc(100vw - 120px);
  height: calc(100vh - 80px);
  overflow-y: auto;
  background-color: pink;

 }
  footer {
      padding: 10px 20px;
  }
 ...
     

我们在调整结构后,最大的调整就是,左侧与内容的调整,左侧绝对定位,右侧内容就是给一个左侧的内边距,然后设置了固定宽度和高度,并且给了滚动显示

效果也是一样的

最后你会发现实现布局的方法有很多,不同的结构组织,对应的css会有所差别,每一种情况对于后期的可拓展性更是不一样,个人推崇首选grid方式,然后是flex,最后是定位grid对于后期的修改兼容性更好,但对于使用者grid特性有更高的要求

总结

  • 了解上中下结构,我们如何让headerfooter在可视区域显示,对应的内容在可视区域内滚动

  • 用不同方式实现上中下结构的布局,比如flex或者grid都可以实现

  • 实现上左中下结构,我们通过三种不同的方式去实现,grid布局更加灵活,页面结构比较简单,css也相对较少,个人推崇grid最佳

  • 每一种方案都有其自己的特点,也并都不都是完美的,比如使用grid,那么对使用者有更高的要求,相对flex定位它更灵活,面对复杂的机构,如果你掌握了grid,那么会使用简单的结构,最少的css实现其他两种方案一样的效果。

  • 本文code example

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYNIGuFn' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片