使元素占用容器中的可用空间

时间:2015-11-10 12:33:45

标签: html css html5 css3 flexbox

我有一个看起来如此的页面:

The way it's supposed to look

这里的标题是我遇到问题的原因。它包含:

  1. 最左侧的图标,其大小固定

  2. 一个标题,位于图标的右侧,占据了所需的空间,使标题文字适合一行

  3. 有时,标题下方有一个字幕

  4. 有时候,一个包含一些辅助内容的方框会安排在标题的右边,用尽任何遗留空间

  5. 我不想因为各种原因(包括但不限于完美主义)来嵌套这些元素,而且我几乎那里......除了我能&# 39;得到最后一个框,"辅助材料",以填补剩余的空间。

    我已将此作为列构建,图标为100%高度,标题和副标题为<50%高度,辅助框具有100%高度。给aux盒固定宽度的工作正常,但是当我尝试使它width: 100%水平生长时,100%似乎意味着&#34; 100%的周围盒子&#34; (在我的情况下,<heading>)而不是&#34; 100%的剩余空间&#34;,这使它溢出。

    &#13;
    &#13;
    html, body { padding: 0; margin: 0; height: 100%; width: 100%; font: 10px sans-serif }
    
    /* Colors to please the eyes */
    article { border: 5em solid limegreen; }
    header { border: 1px solid tomato; }
    .icon { background-color: cyan; }
    h1 { background-color: magenta; }
    h2 { background-color: yellow; }
    .aux { background-color: lavender; }
    
    /* Arrange them boxes */
    article {
        display: flex;
        flex-flow: column nowrap;
    }
    header {
        display: flex;
        flex-flow: column wrap;
        align-content: flex-start;
        height: 5em;
    }
    .icon { width: 5em; height: 100% }
    h1 { font-size: 200%; margin: 0 }
    h2 { font-size: 150%; margin: 0  }
    .aux { height: 100%; width: 100%; }
    &#13;
    <article>
      <header>
        <div class=icon>ICON</div>
        <h1>Main header</h1>
        <h2>Subheading here</h2>
        <div class=aux>MOAR STUFF</div>
      </header>
      <section>
        Lorem ipsum dolor sit amet...
      </section>
    </article>
    &#13;
    &#13;
    &#13;

    我可以让最后一个框水平增长,不用更改标记吗?

4 个答案:

答案 0 :(得分:2)

更新的解决方案(现在CSS Grid可用)

随着CSS Grid的出现,布局相对简单。没有必要改变标记。

这一个关键规则是:

grid-template-columns: 5em auto 1fr;

它建立一个有三列的网格。指定每列的宽度,并与问题的要求一致。

fr单位在概念上与flex-grow属性相似。它旨在消耗自由空间。

header {
  display: grid;
  grid-template-columns: 5em auto 1fr; /* set 3 columns at specified widths */
  grid-template-rows: 50% 50%;         /* set 2 rows at specified heights */
  height: 5em;  
}

.icon {
  grid-row: span 2;                    /* span two rows (full height) */
}

h1 {}                                 /* placed automatically based on source order */

h2 {
  grid-column: 2;                      /* placed in column 2 */
}

.aux {
  grid-column: 3;
  grid-row: 1 / span 2;
}

/* non-essential decorative styles */
body    { margin: 0; font: 10px sans-serif }
article { border: 5em solid limegreen; }
header  { border: 1px solid tomato;    }
.icon   { background-color: cyan;      }
h1      { background-color: magenta; font-size: 200%; margin: 0; }
h2      { background-color: yellow;; font-size: 150%; margin: 0; }
.aux    { background-color: lavender;  }
<article>
  <header>
    <div class=icon>ICON</div>
    <h1>Main header</h1>
    <h2>Subheading here</h2>
    <div class=aux>MOAR STUFF</div>
  </header>
  <section>
    Lorem ipsum dolor sit amet...
  </section>
</article>

jsFiddle demo

OLD(PRE-GRID)解决方案

如果为包含h1h2的列定义宽度,则获取辅助框(“moar stuff”)以拉伸其父级的剩余宽度不是问题。< / p>

试试这个:

HTML(无变化)

CSS

h1 {
   font-size: 200%;
   margin: 0;
   width: 10em; /* new */
}

.aux {
   height: 100%;
   width: calc(100% - 10em - 5em - 10em); /* width less header column less icon 
                                             less green border */
}

jsFiddle demo

答案 1 :(得分:1)

我的回答

html,
body {
  padding: 0;
  margin: 0;
  height: 100%;
  width: 100%;
  font: 10px sans-serif
}
/* Colors to please the eyes */

article {
  border: 5em solid limegreen;
}
header {
  border: 1px solid tomato;
}
.icon {
  background-color: cyan;
}
h1 {
  background-color: magenta;
}
h2 {
  background-color: yellow;
}
.aux {
  background-color: lavender;
}
header {
  height: 5em;
  position: relative;
}
.icon {
  width: 5em;
  height: 100%;
  position: absolute;
}
h1 {
  font-size: 200%;
  margin: 0 0 0 calc(5em / 2); /* adjust for the font size */
  float: left;
  height: 1px;
}
h2 {
  font-size: 150%;
  margin: calc(1em * 200 / 150) 0 0 calc(5em / 1.5); /* adjust for the font size */
  float: left;
  clear: left;
}
.aux {
  overflow: hidden;
  height: 100%;
  text-align: center;
}
<article>
  <header>
    <div class=icon>ICON</div>
    <h1>Main header</h1>
    <h2>Subheader here</h2>
    <div class=aux>
      MOAR STUFF MOAR STUFF
    </div>
  </header>
  <section>
    Lorem ipsum dolor sit amet...
  </section>
</article>

优点是.aux具有正确的大小,因此您可以将其中的内容集中在其中。缺点是你丢失了主标题的背景,所以你必须在另一个元素上伪造它。但那可以做到。

答案 2 :(得分:0)

我不知道在不更改标记的情况下修复此问题的任何简单方法。麻烦的是你同时进行包裹和拉伸。如果您移除了包裹的部分,则可以更改弯曲方向并拉伸最终元素。

下面是一个对标记几乎没有变化的解决方案。我把标题和副标题放在一个容器里。

html, body { padding: 0; margin: 0; height: 100%; width: 100%; font: 10px sans-serif }

/* Colors to please the eyes */
article { border: 5em solid limegreen; }
header { border: 1px solid tomato; }
.icon { background-color: cyan; }
h1 { background-color: magenta; }
h2 { background-color: yellow; }
.aux { background-color: lavender; }

/* Arrange them boxes */
article {
    display: flex;
    flex-flow: column nowrap;
}

header {
    display: flex;
    flex-flow: row wrap;
    align-content: flex-start;
    height: 5em;
}

.icon, h1, h2 {
  flex-shrink: noshrink;
}

.icon { width: 5em; height: 100% }
h1 { font-size: 200%; margin: 0 }
h2 { font-size: 150%; margin: 0  }

.aux { height: 100%; flex-grow: 1; }
<!DOCTYPE html>
<html>
    <head>
        <title>Flexicols</title>
    </head>
    <body>
        <article>
            <header>
                <div class=icon>ICON</div>
                <div class='subtitled-heading'>
                  <h1>Main header</h1>
                  <h2>Subheading here</h2>
                </div>
                <div class=aux>MOAR STUFF</div>
            </header>
            <section>
                Lorem ipsum dolor sit amet...
            </section>
        </article>
    </body>
</html>

答案 3 :(得分:0)

基本上需要更改的内容(根据您的规则保留HTML原样),是:

  • header填充其父
  • 标题背景为薰衣草假冒aux填充100%(aux会 根据需要增长)
  • 最小/最大高度/宽度aux所以它保持在父
  • 之内
  • h1h2的高度设为50%,以便它们换行。
  • h1h2需要填充他们的框,以便flex增长。

小更新

  • 使标题斩掉溢出
  • 添加大小调整规则以使所有内容正确对齐

&#13;
&#13;
html,
body {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
  height: 100%;
  width: 100%;
}
*,
*:before,
*:after {
  box-sizing: inherit
}
/* Colors to please the eyes */

article {
  border: 5em solid limegreen;
}
header {
  border: 1px solid tomato;
}
.icon {
  background-color: cyan;
}
h1 {
  background-color: magenta;
}
h2 {
  background-color: yellow;
}
.aux {
  background-color: lavender;
}
/* Arrange them boxes */

article {
  display: flex;
  flex-flow: column nowrap;
}
header {
  background-color: lavender;
  display: flex;
  overflow: hidden;
  width: 100%;
  flex-flow: column wrap;
  align-content: flex-start;
  height: 5em;
}
.icon {
  width: 5em;
  height: 100%
}
h1 {
  font-size: 200%;
  margin: 0;
  height: 50%;
}
h2 {
  font-size: 150%;
  margin: 0;
  height: 50%;
}
.aux {
  min-height: 100%;
  max-width: 100%
}
&#13;
<article>
  <header>
    <div class=icon>ICON</div>
    <h1>Main header</h1>
    <h2>Subheading here</h2>
    <div class=aux>MOAR STUFF</div>
  </header>
  <section>
    Lorem ipsum dolor sit amet...
  </section>
</article>
&#13;
&#13;
&#13;