美文网首页
CSS Flex垂直排列时的容器宽度问题

CSS Flex垂直排列时的容器宽度问题

作者: 切糕糕 | 来源:发表于2017-11-03 11:48 被阅读44次

最近在学习Flex布局,想模仿小米首页的商品Tab页效果:

小米官网Tab页效果

仔细推敲可以发现,图中商品的陈列方式并不是一行一行的,而是一列一列的。当第一列排满后,剩下的一项“彩虹7号电池”会被排到第二列。

DOM的文档流通常是从左到右、自上而下横向排列元素的。像这种列式排列的,可以用JavaScript实现。但如果想用纯CSS实现,就会有些难度。

你可能首先会想到使用Flex布局,把主轴方向设置为垂直方向。虽然这样商品竖着排列了,但是你会发现,随着商品列数的增加,外层的容器并不会自动变宽

Flex外层容器不会自动变宽

这是Flex布局设计上的一个问题,可以参考这个StackOverflow提问。这里还有个DEMO更直观地阐述了这个问题:jsFiddle链接

解决这个问题的办法有不少,对比下来最巧妙的办法就是:完全不考虑用Flex布局,利用writing-mode属性就能搞定。writing-mode是个平时用得很少的属性,原本是用来方排版竖向的文字,如中国古诗词。对writing-mode的历史感兴趣的话可以阅读 张鑫旭大神的文章

writing-mode既然能让文字竖着排,也就能让容器内的元素竖着排。给商品列表的外层容器加上writing-mode属性,就能解决容器宽度的问题:

.tab-pane {
    // lr可理解为left to right,即垂直方向上从左到右
    writing-mode: vertical-lr; 
}
image.png

似乎不太对,容器内的所有元素都继承了竖向排版,没关系,把容器内的元素writing-mode重置成通常文档流的方向:

.tab-pane-items {
    // tb可理解为top to bottom,即水平方向自上而下
    writing-mode: horizontal-tb;
}
最终效果图

这样就完美了。:-)

附完整例子代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
  <script src="https://cdn.bootcss.com/vue/2.4.4/vue.min.js"></script>
  <style>
  .list-group-item {
    cursor: pointer;
    border-radius: 0;
    border: none;
    background: rgba(0,0,0,.8);
    color: white;
    margin: 0;
    position: static;
  }
  .tabs {
    position: relative;
    background: #eee;
  }
  .tabs .list-group {
    width: 20rem;
    margin-bottom: 0;
  }
  .tab-pane {
    box-shadow: 0 5px 20px gray;
    background: white;
    padding: 2rem;
    position: absolute;
    left: 20rem;
    height: 100%;
    top: 0;
    writing-mode: vertical-lr;
  }
  .tab-pane-items {
    display: inline-block;
    margin: 1rem 3rem 1rem 1rem;
    color: black;
    writing-mode: horizontal-tb;
  }
  span.image {
    padding: 10px 20px;
    margin-right: 1rem;
    background: #ccccff;
  }
  </style>
  <title>Document</title>
</head>
<body style="padding-top: 2rem;">
  <div class="container" id="app">
    <div class="tabs">
      <ul class="list-group">
        <li :class="['list-group-item', index==menu.active?'active':'']" 
          v-for="(item,index) in menu.items" @mouseover="menu.active=index" 
          @mouseleave="menu.active=-1" :key="index">{{item}}
          <div v-show="menu.active==index" class="tab-pane">
            <div v-for="n in (((index+1)*31)%19)" class="tab-pane-items">
              <span class="image"></span>
              <a href="#">iPhone手机</a>
            </div>
          </div>
        </li>
      </ul>
    </div>
  </div>
  <script>
  new Vue({
    el: '#app',
    data: {
      menu: {
        active: 1,
        items: [
          '手机 电话卡',
          '笔记本',
          '电视 盒子',
          '路由器 智能硬件',
          '移动电源 电池 插线板',
          '耳机 音箱',
          '保护套 贴膜',
          '线材 支架 储存卡',
          '箱包 服饰 鞋 眼镜',
          '生活周边'
        ]
      }
    }
  });
  </script>
</body>
</html>

相关文章

  • CSS Flex垂直排列时的容器宽度问题

    最近在学习Flex布局,想模仿小米首页的商品Tab页效果: 仔细推敲可以发现,图中商品的陈列方式并不是一行一行的,...

  • flex布局

    css3布局 1. flex容器 该容器有六种属性: flex-direction:决定主轴的方向(即项目的排列方...

  • CSS布局的那些事

    位置 移动 宽度和高度 即大小 css的"图层" BFC position float flex grid 容器的...

  • css flex

    css flex布局 采用 Flex 布局的元素,称为 Flex 容器(flex container),简称“容器...

  • 学习

    一. css相关 1. flex布局 1行排列,多个换行image.png 垂直水平居中image.png 左边固...

  • updating...

    CSS 1、三栏布局问题(左右固定宽度 中间自适应) flex grid float + margin 2、CSS...

  • 【css图片垂直居中】让html img图片垂直居中的三种方法

    一、使用flex实现垂直居中 利用css flex实现垂直居中。flex可能不是实现垂直居中最好的选择,因为IE8...

  • jQuery-轮播

    实现原理 CSS部分 图片容器宽度设置为图片宽度*图片数量,并将所有图片使用浮动进行水平排列,形成一个滑动轨道; ...

  • RN(react native)入坑指南-04,布局容器

    react native 支持采用flex方式布局。默认情况下如果不设置flex容器的宽度,那么flex容器会10...

  • 2021-11-18-🌈 让div填充剩余的屏幕空间的高度

    flex 父元素设置 flex-flow: column; 垂直排列再使用 flex 自适应布局 calc hei...

网友评论

      本文标题:CSS Flex垂直排列时的容器宽度问题

      本文链接:https://www.haomeiwen.com/subject/kweouxtx.html