调整大小时保持容器和子容器的比例

Maintain ratio of container and children while resize

我有基于 flexbox 的带图像和不带图像的模块化卡片网格。 通常没有图片的卡片占宽度的50%,有图片的卡片占宽度的100%,没有图片的卡片也为100%。

----------------
[[ txt ][ img ]] – card with an image
----------------
[  txt ][ txt  ] – 2 cards without image
----------------
[      txt     ] – card without image
----------------
[[ txt ][ img ]] – card with an image
----------------

是否可以在调整大小时保持卡片及其内容的比例,并保持 css 的模块化?

代码如下 这让我保持比例,但是当我尝试将这种技术应用于卡片儿童时,一切都崩溃了

<div class="wrapper">
  <div class="card">
    <div class="card-text">
    </div>
    <div class="card-image">  
    </div>
  </div>
</div>

.wrapper
  display: flex
  flex-wrap: wrap
  justify-content: space-between
  width: 620px

.card
  height: 0
  padding-bottom: 50%
  display: flex
  flex-direction: row
  justify-content: space-between
  flex: 1 1 300px

.has-card-image .card-text,
.has-card-image .card-image
  height: 300px
  width: 300px

我可以看到一种方法 w/o 脚本。

在这种情况下,使用 px 值,或者例如使用 vw,原因是 card-textcard-image 需要知道 wrapper 的宽度才能根据预期输出调整大小(这意味着百分比无法使用)。

Fiddle demo

堆栈片段

.wrapper {
  display: flex;
  flex-wrap: wrap;
  width: 600px;
}

.card {
  display: flex;
  flex: 1 300px;
}

.card .card-text,
.card .card-image {
  height: 100px;
  width: 300px;
}

.card .card-text:only-child {
  flex: 1 300px;
}

/*  demo styles  */
.card .card-text, .card .card-image {
  border: 1px solid;
  box-sizing: border-box;
}
.card .card-text::before {
  content: 'text';
}
.card .card-image::before {
  content: 'image';
}
<div class="wrapper">
  <div class="card">
    <div class="card-text">
    </div>
    <div class="card-image">
    </div>
  </div>

  <div class="card">
    <div class="card-text">
    </div>
  </div>

  <div class="card">
    <div class="card-text">
    </div>
  </div>

  <div class="card">
    <div class="card-text">
    </div>
  </div>

  <div class="card">
    <div class="card-text">
    </div>
    <div class="card-image">
    </div>
  </div>  
</div>


如果您需要边距,则需要额外的包装纸

Fiddle demo

堆栈片段

.wrapper {
  width: 620px;
  overflow: hidden;
}

.inner {
  display: flex;
  flex-wrap: wrap;
  margin-left: -20px;
}

.card {
  display: flex;
  flex: 1 300px;
}

.card .card-text,
.card .card-image {
  height: 100px;
  width: 300px;
  margin-left: 20px;
}

.card .card-text:only-child {
  flex: 1 300px;
}


/*  demo styles  */
.card .card-text,
.card .card-image {
  border: 1px solid;
  box-sizing: border-box;
}

.card .card-text::before {
  content: 'text';
}

.card .card-image::before {
  content: 'image';
}
<div class="wrapper">
  <div class="inner">
    <div class="card">
      <div class="card-text">
      </div>
      <div class="card-image">
      </div>
    </div>

    <div class="card">
      <div class="card-text">
      </div>
    </div>

    <div class="card">
      <div class="card-text">
      </div>
    </div>

    <div class="card">
      <div class="card-text">
      </div>
    </div>

    <div class="card">
      <div class="card-text">
      </div>
      <div class="card-image">
      </div>
    </div>
  </div>
</div>


已更新

这是一个使用 vw 和边距的版本,并且是响应式的。

注意,在wrapper上设置的make up for margin也可以在每个item上设置,虽然我觉得这样更简单。

Fiddle demo

堆栈片段

.wrapper {
  width: calc(80vw + 20px);  /*  20px extra for margin  */
  margin: 0 auto;
  overflow: hidden;
}

.inner {
  display: flex;
  flex-wrap: wrap;
  margin-left: -20px;
}

.card {
  display: flex;
  flex: 1 40vw;
}

.card .card-text,
.card .card-image {
  height: 100px;
  width: 40vw;
  margin-left: 20px;
}

.card .card-text:only-child {
  flex: 1 40vw;
}


/*  demo styles  */
.card .card-text,
.card .card-image {
  border: 1px solid;
  box-sizing: border-box;
}

.card .card-text::before {
  content: 'text';
}

.card .card-image::before {
  content: 'image';
}
<div class="wrapper">
  <div class="inner">
    <div class="card">
      <div class="card-text">
      </div>
      <div class="card-image">
      </div>
    </div>

    <div class="card">
      <div class="card-text">
      </div>
    </div>

    <div class="card">
      <div class="card-text">
      </div>
    </div>

    <div class="card">
      <div class="card-text">
      </div>
    </div>

    <div class="card">
      <div class="card-text">
      </div>
      <div class="card-image">
      </div>
    </div>
  </div>
</div>