shaozj / blog

blog
87 stars 4 forks source link

利用 flex 实现宽度自适应布局 #14

Open shaozj opened 7 years ago

shaozj commented 7 years ago

利用 flex 实现宽度自适应布局

flex-direction 为 row 时的宽度自适应布局

容器宽度一定,内容宽度超出容器宽度后出现滚动条

代码:

<ul class="wrap">
  <ol class="item">one</ol>
  <ol class="item">two</ol>
  <ol class="item">three</ol>
  <ol class="item">four</ol>
  <ol class="item">five</ol>
  <ol class="item">six</ol>
  <ol class="item">seven</ol>
  <ol class="item">eight</ol>
  <ol class="item">nine</ol>
</ul>
.wrap {
  display: flex;
  border: 2px red solid;
  width: 400px;
  height: 50px;
  align-items: center;
  overflow: auto;
}

.item {
  width: 100px;
  flex-shrink: 0;
  background: green;
  margin-right: 4px;
}

效果:

image

flex-shrink: 0; 表示 flex 元素超出容器时,宽度不压缩,这样就能撑开元素的宽度,使得出现滚动条。

容器的宽度由内容宽度撑开

代码:

<ul class="wrap">
  <ol class="item">one</ol>
  <ol class="item">two</ol>
  <ol class="item">three</ol>
  <ol class="item">four</ol>
  <ol class="item">five</ol>
  <ol class="item">six</ol>
  <ol class="item">seven</ol>
  <ol class="item">eight</ol>
  <ol class="item">nine</ol>
</ul>
.wrap {
  display: inline-flex;
  border: 2px red solid;
  width: auto;
  height: 50px;
  align-items: center;
  overflow: auto;
}

.item {
  width: 100px;
  flex-shrink: 0;
  background: green;
  margin-right: 4px;
}

效果:

image

这里在容器上需要用 display: inline-flex;,这样才能撑开容器;

flex-direction 为 column 时的宽度自适应布局

一种复杂的情况是,我们希望 item 是纵向布局的,但是支持布满一列后换行,同时,在横向能够撑开容器的宽度。我们自然会想到用如下的代码实现:

<div class="container">
  <div class="photo"></div>
  <div class="photo"></div>
  <div class="photo"></div>
  <div class="photo"></div>
  <div class="photo"></div>
</div>
.container {
  display: inline-flex;
  flex-flow: column wrap;
  align-content: flex-start;
  height: 350px;
  background: blue;
}

.photo {
  width: 150px;
  height: 100px;
  background: red;
  margin: 2px;
}

然而在 chrome 浏览器下,效果如下: image

容器的宽度未被撑开。

有两种方式解决这个问题。

用 js(jquery) 来处理

在之前代码的基础上,我们添加如下 js 代码:

$(document).ready(function() {
  $('.container').each(function( index ) {
    var lastChild = $(this).children().last();
    var newWidth = lastChild.position().left - $(this).position().left + lastChild.outerWidth(true);
    $(this).width(newWidth);
  })
});

结果如下:

image

用 css writing-mode 处理

代码:

<div class="container">
  <div class="photo"></div>
  <div class="photo"></div>
  <div class="photo"></div>
  <div class="photo"></div>
  <div class="photo"></div>
</div>
.container {
  display: inline-flex;
  writing-mode: vertical-lr;
  flex-wrap: wrap;
  align-content: flex-start;
  height: 250px;
  background: blue;
}
.photo {
  writing-mode: horizontal-tb;
  width: 150px;
  height: 100px;
  background: red;
  margin: 2px;
}

效果如下:

image

参考文章

nelling commented 7 years ago

不错

BoneTM commented 4 years ago

收藏了

SZP1206 commented 3 years ago

感谢分享!

zhoufanglu commented 2 years ago

感谢 有用