如何在响应式设计中向右拉出一个元素?

How to pull out an element to the right in responsive design?

这是我要实现的布局:

       Mobile:                            Desktop:
+-------------------+        +-----------+---------------------+
|         C         |        |     C     |                     |
+-------------------+        +-----------+                     |
|                   |        |     P     |                     |
|                   |        +-----------+                     |
|         V         |        |           |          V          |
|                   |        |           |                     |
|                   |        |           |                     |
+-------------------+        |           |                     |
|         P         |        |           |                     |
+-------------------+        +-----------+---------------------+
         100%                    300px        100% - 300px

因此,如果屏幕足够宽 (min-width: 960px),元素 V 会从其他两个元素之间拉出,并向右移动。

请注意 none 的元素(包括外部容器)具有固定的已知高度。它们都必须自动调整大小以适合其内容。

移动版也是DOM的合理顺序,所以我们就用这个HTML:

<div class="outer">
  <div class="C"></div>
  <div class="V"></div>
  <div class="P"></div>
</div>

我第一次尝试用flexbox实现桌面布局:

@media screen and (min-width: 960px) {
  .outer {
    display: flex;
    flex-direction: column;
  }
  .C { order: 1; width: 300px; }
  .V { order: 3; }
  .P { order: 2; width: 300px; }
}

这会处理重新排序,但在 PV 之间似乎有 no way to force a wrap 而没有设置固定高度。所以元素仍然堆叠在一起。

我还尝试使用浮点数将 V 拉出:

@media screen and (min-width: 960px) {
  .C { width: 300px; }
  .V { width: calc(100% - 300px); margin-left: 300px; float: right; }
  .P { width: 300px; }
}

但最终低于 C。要解决此问题,我将不得不更改 DOM 顺序,出于可访问性原因我宁愿不这样做。

我也可以用绝对定位把V拉出来:

@media screen and (min-width: 960px) {
  .outer { position: relative; }
  .C { width: 300px; }
  .V { width: calc(100% - 300px); right: 0; top: 0; }
  .P { width: 300px; }
}

问题在于 V 不再影响 outer div 的高度,并开始与 outer.[=27= 下面的内容重叠]

最后考虑CSSgrid,但会降低浏览器兼容性

有没有一种方法可以在不诉诸丑陋的技巧的情况下创建这种布局?

添加更多浮动:

@media screen and (min-width: 960px) {
  .C {
    width: 300px;
    float: left;
  }
  .V {
    width: calc(100% - 300px);
    float: right;
  }
  .P {
    width: 300px;
    clear: left; /* clear only left to go under C */
  }
  .outer {
    overflow: auto; /* create a BFC to avoid the float getting outside the container */
  }
}

.outer {
  margin:10px;
}
<div class="outer">
  <div class="C" style="height:50px;background:red"></div>
  <div class="V" style="height:150px;background:blue"></div>
  <div class="P" style="height:60px;background:green"></div>
</div>


<div class="outer">
  <div class="C" style="height:50px;background:red"></div>
  <div class="V" style="height:100px;background:blue"></div>
  <div class="P" style="height:100px;background:green"></div>
</div>

<div class="outer">
  <div class="C" style="height:100px;background:red"></div>
  <div class="V" style="height:50px;background:blue"></div>
  <div class="P" style="height:50px;background:green"></div>
</div>

或如下 CSS 网格:

@media screen and (min-width: 960px) {
  .V {
    grid-row:span 3;
  }
  .outer {
    display:grid;
    grid-template-columns:300px 1fr;
    align-items:start;
  }
}

.outer {
  margin:10px;
}
<div class="outer">
  <div class="C" style="height:50px;background:red"></div>
  <div class="V" style="height:150px;background:blue"></div>
  <div class="P" style="height:60px;background:green"></div>
</div>


<div class="outer">
  <div class="C" style="height:50px;background:red"></div>
  <div class="V" style="height:100px;background:blue"></div>
  <div class="P" style="height:100px;background:green"></div>
</div>

<div class="outer">
  <div class="C" style="height:100px;background:red"></div>
  <div class="V" style="height:50px;background:blue"></div>
  <div class="P" style="height:50px;background:green"></div>
</div>