响应式布局:固定宽度的居中div的中间内容必须成为右列而不会溢出

时间:2016-03-26 22:49:56

标签: css responsive-design tablelayout

我有一个宽度为700像素的居中div,其中中间部分在视口为>时必须成为右列。一些宽度。我为此目的使用了绝对定位,但是这个列必须是响应式的,我不知道它的宽度。

首先,我想知道如何处理绝对定位元素的宽度的规则是什么,这些元素超出了它们的相对父元素。绝对定位应使用其相对父级的宽度,但当元素超出该父级时,该元素将被缩小。如果有一个没有空格的单词,它会相应地扩展元素,然后一切都跟随。我不明白它是如何工作的以及如何预测这种行为。当没有宽度的元素应该从其父元素溢出时,它是相同的。

然后,有没有办法让这个列填满右边,直到它达到窗口的极限而没有溢出(有一点边距右)?如果我在该列上固定一个大的宽度,假设它将是该列在最大视口中实现的最大宽度,并使用overflow属性隐藏窗口外的内容,当然,绝对定位的元素只是被剪切。 我真的不知道如何做出响应,因为它似乎绝对定位从流程中删除元素,它不是为了我的目的。当然,请不要JS。自IE8以来它必须支持Internet Explorer 我想到的唯一解决方案是复制内容并使用display:none / block来切换具有媒体查询的块,但这意味着冗余代码。我尝试了一个复杂的显示:表格布局,直到我发现colspan不存在 (只是你知道,我还有一个左列也要考虑,我之所以使用三列显示:表格布局。如果那是相关的。)

这是一个简化的代码:
我没有放置媒体查询,但小屏幕显然在小屏幕上应该是什么样子,取而代之的是旁边的选择器。

main{
  overflow:hidden;
}
.colMain{
  background-color:green;
  margin-left:auto;
  margin-right:auto;
  position:relative;
  width:300px;
}
.aside{
  background-color:red;
  position:absolute;
  top:0px;
  left:320px;
}
.aside-on-small-screen{
  background-color:red;
}
<main>
  <div class="colMain">
    <div>stuff</div>
    <div class="aside">aside that must extend all the way to the right until it reaches the window limit</div>
    <div>stuff</div>
  </div>
</main>

谢谢。

2 个答案:

答案 0 :(得分:0)

使用flexbox并指定一个百分比宽度。详细信息在Snippet的CSS部分中。

  • "multi"
    • order
    • flex-shrink
    • flex-growflex-basisvw
  • Flexbox
    • 视口宽度/高度vhem
    • 百分比
    • /* Optional Defaults and Resets */ * { -ms-box-sizing: border-box; box-sizing: border-box; } html { font: 400 10px/1 Arial; width: 100%; height: 100%; } /*, *:before, *:after { box-sizing: inherit; margin: 0; padding: 0; border: none; }*/ body { font: inherit; font-size: 160%; /* background: rgba(0, 0, 0, .2);*/ line-height: 1; overflow: visible; width: 100%; height: 100%; } /* Demo Styles */ /* All outlines and backgrounds are for presentational purposes */ /* vw/vh viewport width/height 1vw/vh = 1% of viewport width/height */ main { overflow: hidden; /* width: 100vw; height: 100vh; background: rgba(0, 0, 255, .2);*/ width: 100%; height: 100%; min-height: 35em; display: table; } /* Flexbox layout will automatically keep .aside to the right with the */ /* property justify-content: space-between; which keeps the max amount */ /* of even space between flex-items (which is .stuff and .aside) */ .colMain { /* display: flex; flex-direction: row; flex-wrap: nowrap; justify-content: space-between; */ background-color: green; margin-left: auto; margin-right: auto; position: relative; min-width: 99%; min-height: 99%; padding: 1em; display: table-row; width: 700px; } /* Removed absolute positioning in favor of flexbox and a percentage */ /* width. .aside will start dis-proportionally expanding while the viewport */ /* expands. The two columns on the right while begin to shrink in response */ /* to.aside's expansion. All this stretching and shrinking happens when the */ /* elements are at 210px or more (210 is 30% of 700px). This behavior is */ /* accomplished by using flex-shrink, flex-grow, and flex-basis */ .aside { display: table-cell; background-color: red; position: absolute; top: 1em; right: 0; left: 70%; /* order: 3; */ min-width: 30%; max-width: 500px; min-height: 100%; /* flex-grow: 1; flex-basis: 210px;*/ outline: 2px solid #7c1b38; padding: 5px; } .aside-on-small-screen { background-color: red; } .stuff { outline: 2px dotted white; width: 30%; max-width: 210px; min-height: 100%; position: absolute; /* flex-shrink: 1; flex-basis: 210px; */ display: table-cell; } #col1 { left: 1em; top: 1em; } #col2 { left: 36%; top: 1em; } /*.stuff:first-of-type { order: 1; } .stuff:last-of-type { order: 2; */ } /* The HTML shows that the second column (the second .stuff) would be */ /* in-between .aside and the edge of .colMain. Instead of moving it out of */ /* the way in markup (HTML), I used the flexbox property, order. */

&#13;
&#13;
<main>
  <div class="colMain">
    <div id="col1" class="stuff">stuff</div>

    <div class="aside">aside that must extend all the way to the right until it reaches the window limit</div>

    <div id="col2" class="stuff">stuff</div>
  </div>
</main>
&#13;
    let catGroup:UInt32 = 0x1 << 0
let groundGroup:UInt32 = 0x2 << 1
    cat.physicsBody?.categoryBitMask = catGroup
    cat.physicsBody?.contactTestBitMask = groundGroup
    ground.physicsBody?.categoryBitMask = groundGroup
    ground.physicsBody?.contactTestBitMask = catGroup
&#13;
&#13;
&#13;

答案 1 :(得分:0)

一个问题有三个:

第一个问题。

如何转换中间内容

<div class="wrapper">
    <div>stuff</div>
    <div class="aside">Middle content</div>
    <div>stuff</div>
</div>

在右列中向右消耗而不会溢出窗口,当过去列的“包装”的其余部分必须是固定宽度的居中列时。

<div class="colLeft"></div>
<div class="wrapper" style="text-align:center; width:700px;">
    <div>stuff</div>
    <div>stuff</div>
</div>
<div class="aside">Middle content now to the right</div>

绝对定位没有帮助,因为没有固定大小(%或px),它不在流量范围内,可变宽度的内容将不适应情况(和溢出)。

这可以通过显示表轻松解决。

第二个问题。

显示表/表格单元导致第二个问题 要使用display:table-cell制作三个“列”,顺序非常重要。这意味着“aside”div必须是其列的最后一个元素(我的第一个片段中的包装列),以使其成为右侧行的独立单元格。如果您不必担心这个中间内容的故事而且您只需要在div的末尾向右切换内容或从左侧开始切换内容,那么它已经结束了。 你只需要使用display:table-cell设置colLeft,wrapper和我的第二个代码段的样式,并使用另一个带有display:table的全局包装器和一些其他样式,如table-layout:fixed和width:100%来完成这个技巧。使用小屏幕的媒体查询,您只需要使用display:none隐藏colLeft。

但是如果你需要中间内容作为中间内容,但仍然在小屏幕上和大屏幕上的右栏中,这是一个不同的情况。

这可以通过anonymous table objects和table-header / footer / row-group来解决。

使用表格页眉/页脚/行组,您可以重新组织行,这样您就可以将“旁边”放在最后,将其转换为大屏幕上的独立单元格,并将其放在中间的表格行中-group on small screens:

.header{
  background-color:green;
  display:table-header-group;
}
.footer{
  background-color:green;
  display:table-footer-group;
}
.aside{
  background-color:red;
  display:table-row-group;
}
<div class="header">stuff</div>
<div class="footer">stuff</div>
<div class="aside">Middle content</div>

第三个问题。

最难的问题是固定宽度的居中“列”。使用table-xxx-group,禁止在table-header-group和table-footer-group周围放置一个包装器来设置700px的宽度,因为table-group是行元素,包装器将自动成为一个表对象,排除“旁边”,它不能在小屏幕上以表格 - 行 - 组样式插入中间。 如果不在“东西”周围放置包装器,您将无法在大屏幕上控制创建的匿名单元格的宽度,因为您无法设置匿名的样式。因此每个单元格的宽度需要1/3。

main{
  display:table;
  table-layout: fixed;
  width:100%;
}
.colLeft{
  background-color:yellow;
  display:table-cell;
}
.header,.footer{
  background-color:green;
  /*no display style > it will create an anonymous cell
  object around the header/footer elements*/
}
.aside{
  background-color:red;
  display:table-cell;
}
<main>
  <div class="colLeft"></div>
  <div class="header">stuff</div>
  <div class="footer">stuff</div>
  <div class="aside">Middle content now to the right</div>
</main>

解决方案是使用table-column-group / table-column。您可以设置列的样式并将宽度设置为中间列,即使它是匿名确定的。

解决方案

小屏幕

.rowTabled{
  display:table;
  table-layout: fixed;
  width:100%;
}
.header{
  background-color:green;
  display:table-header-group;
}
.footer{
  background-color:green;
  display:table-footer-group;
}
.aside{
  background-color:red;
  display:table-row-group;
}
.colLeft, .colgroup{
  display:none;
}
<main>
  <div class="colgroup">
    <div class="colCol left"></div>
    <div class="colCol middle"></div>
    <div class="colCol right"></div>
  </div>
  <div class="rowTabled">
    <div class="colLeft"></div>
    <div class="header">stuff</div>
    <div class="footer">stuff</div>
    <div class="aside">asideeeeeeeeeeeex eeeeee eeeeeeeee eeeeeeeeeeeeee</div>
  </div>
</main>

大屏幕

main{
  display:table;
  table-layout: fixed;
  width:100%;
}
.colgroup{
  display:table-column-group;
}
.colCol{
  display:table-column;
}
.middle{
  background-color:green;
  width:100px;
}
.left,.right{
  background-color:yellow;
}
.rowTabled{
  display:table-row;
}
.colLeft{
  display:table-cell;
}
.aside{
  background-color:red;
  display:table-cell;
}
<main>
  <div class="colgroup">
    <div class="colCol left"></div>
    <div class="colCol middle"></div>
    <div class="colCol right"></div>
  </div>
  <div class="rowTabled">
    <div class="colLeft"></div>
    <div class="header">stuff</div>
    <div class="footer">stuff</div>
    <div class="aside">asideeeeeeeeeeeex eeeeee eeeeeeeee eeeeeeeeeeeeee</div>
  </div>
</main>