使用Flexbox和溢出来居中项目

时间:2015-09-11 16:48:50

标签: css html5 css3 flexbox

问题摘要

我想要的布局是能够在页面上居中(垂直和水平)一个未知大小的图像。如果图像太大而无法适合任何一个方向,我想显示滚动条,以便用户可以滚动查看完整图像。我遇到的问题是,当图像太大而不适合时,图像的顶部和左侧(取决于切断的部分)将永远无法滚动到。

尝试解决方案

我正在尝试使用flexbox来实现所需的布局,但不要求使用flexbox。这是一个重现问题的小例子(请注意,我没有在CSS中添加任何浏览器前缀,因此您需要在Chrome中查看此内容[或者也可以在Firefox中查看?]):



.body {
  height: 600px;
}

.container {
  margin: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid red;
  height: 100%;
  overflow: auto;
}

img {
  border: 5px solid black;
}

<div class="body">
  <div class="container">
    <img src="http://placehold.it/700x700" />
  </div>
</div>
&#13;
&#13;
&#13;

您应该能够完全看到图像周围的边框,但随着窗口缩小,图像的左侧和/或顶部会被切断。随着窗口继续缩小,越来越多的图像将变得不可见。

请注意,如果那里有图像,那似乎并不重要。这是一个片段,只是使用普通的div来显示问题:

&#13;
&#13;
.body {
  height: 600px;
  margin-top: 80px;
}

.container {
  margin: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid red;
  height: 100%;
  overflow: auto;
}

.content {
  border: 5px solid black;
  width: 600px;
  height: 600px;
  background-color: gray;
}
&#13;
<div class="body">
  <div class="container">
    <div class="content"></div>
  </div>
</div>
&#13;
&#13;
&#13;

同样,整个div应该总是可以通过滚动来访问,但事实并非如此。

问题

如何实现上述所需的布局仅使用HTML和CSS(不接受JS答案)?不需要Flexbox来解决问题,但这将是一个不错的选择。

谢谢!

4 个答案:

答案 0 :(得分:4)

只需从.container中移除justify-content,然后为您的图片添加margin: auto

&#13;
&#13;
.body {
  height: 600px;
}

.container {
  margin: auto;
  display: flex;
  /* align-items: center; // no need for this anymore */
  /* justify-content: center; // remove this */
  border: 1px solid red;
  height: 100%;
  overflow: auto;
}

img {
  border: 5px solid black;
  margin: auto;  /* add this */
}
&#13;
<div class="body">
  <div class="container">
    <img src="http://placehold.it/700x700" />
  </div>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

如果你还在寻找,或者是对其他任何对简单解决方案感兴趣的人:

您可以通过将图像包装在Flex容器中的容器中来实现此目的,如下所示:

  • Flex容器
    • display: flex
    • height: 100vh
  • 内部容器
    • margin: auto

这就是你需要在视口中垂直和水平放置一个未知大小的图像,而不会失去滚动到它的任何部分的能力,以防它不适合任何一个方向。

示例1 :(以视口为中心的图像)

body {
  margin: 0;  /* Override user agent styles */
}

.flex {
  display: flex;
  height: 100vh;
}
.container {
  margin: auto;
}
<body class="flex">
  <main class="container">
    <img src="http://placehold.it/100x100">
  </main>
</body>

示例2 :(图片不适合视口,但仍然可以滚动)

body {
  margin: 0;  /* Override user agent styles */
}

.flex {
  display: flex;
  height: 100vh;
}
.container {
  margin: auto;
}
img {
  border: 1px solid red;
}
<body class="flex">
  <main class="container">
    <img src="http://placehold.it/1000x1000">
  </main>
</body>

适用于最新版本的Chrome,Firefox,Opera和Edge。

答案 2 :(得分:0)

所以标准是你总是想要一个垂直和水平居中的图像,并且无论视口有多小或多大,它都可以滚动?看看这个片段,让我知道我是否关闭。如果我完全错了,那么我有B计划。如果我已经成功或几乎在那里,我会解释我的所作所为。

<强>概要

  1. 定义<body>,因为如果您不这样做,则无法确定滚动条的移动距离。

    position: relativetop, bottom, right,left在0处展开<body>以覆盖视口。

    身体的widthheight 100vw以及100vh强制限制<body>

    ♦由于<body>是一个容器,所有flexbox属性都会影响.x水平居中。

    由于您强调使用滚动条,overflow: scroll滚动条即使不需要也会保留。在涉及动态内容的情况下这是好的,因为不会有任何跳跃。

  2. 外部容器.x具有flexbox属性,以使内部容器.y居中。 此外,您会注意到一个鲜为人知的财产。

  3. .y flex-flow: column nowrap使图片居中。

  4. body已将min-content应用于heightwidth,这将迫使其内容的边界形成紧张的封装。这就是您在没有通常截止的情况下能够看到图像边框的方式。

  5. <强>更新

    这个演示有一些简单的JS来演示任何大小的图像:

    1. 水平居中
    2. 垂直居中
    3. 可以查看任何尺寸的所有面。
    4. 注意: DEMO 下的任何内容都可以完全安全地删除或注释掉。

      &#13;
      &#13;
      // DEMO 
      var s = document.getElementById('s');
      s.addEventListener('click', function(event) {
        event.preventDefault();
        var w = document.getElementById('w'),
          h = document.getElementById('h'),
          pic = document.getElementById('pic'),
          wv = w.value,
          hv = h.value;
        pic.src = "http://placehold.it/" + wv + "x" + hv + "/";
      }, false);
      &#13;
      /* RESET */
      
      html {
        box-sizing: border-box;
        font: small-caps 400 16px/1.45'Source Code Pro';
      }
      *,
      *:before,
      *:after {
        box-sizing: inherit;
        margin: 0;
        padding: 0;
        border: 0 solid transparent;
      }
      /* REQUIRED */
      
      body {
        position: relative;
        top: 0;
        left: 0;
        bottom: 0;
        right: 0;
        width: 100vw;
        height: 100vh;
        overflow: auto;
        margin: auto;
        width: -moz-min-content;
        width: -webkit-min-content;
        width: min-content;
        height: -moz-min-content;
        height: -webkit-min-content;
        height: min-content;
      }
      .x {
        height: 600px;
        flex-flow: row nowrap;
        display: flex;
        align-items: center;
        justify-content: center;
        align-content: center;
      }
      .y {
        margin: auto;
        display: flex;
        flex-flow: column nowrap;
        align-items: center;
        justify-content: center;
        align-content: center;
        border: 2px dashed red;
      }
      /* DEMO */
      
      .ui {
        position: fixed;
        top: 1em;
        left: 1em;
        width: 500px;
        line-height: 1.3;
        z-index: 1;
      }
      fieldset {
        border: 1px solid lightgrey;
        border-radius: 6px;
      }
      input {
        width: 48px;
        line-height: 1.2;
        border: 1px solid grey;
        border-radius: 6px;
        padding: 2px;
        margin: 2px 1px;
      }
      label {
        margin: 2px 0 2px 2px;
      }
      &#13;
      <!doctype html>
      <html>
      
      <head>
        <meta charset="utf-8">
        <title>C.R.A.P.D. -=- Changing Rectangle Alignment, Position, and Dimensions</title>
      </head>
      
      <body>
        <!-- DEMO -->
        <header class="ui">
          <fieldset>
            <legend>Changing Rectangle Alignment Position and Dimensions</legend>
            <label for="w">Width
              <input id="w" type="text" value="300" />
            </label>
            <label for="h">Height
              <input id="h" type="text" value="300" />
            </label>
            <input id="s" type="submit" value="Submit" />
          </fieldset>
        </header>
        <!-- REQUIRED -->
        <main class="x">
          <section class="y">
            <img id="pic" src="http://placehold.it/300x300/" />
          </section>
        </main>
      </body>
      
      </html>
      &#13;
      &#13;
      &#13;

答案 3 :(得分:0)

找到了一个使用double flex容器的解决方案:

.body {
  height: 600px;
  overflow: auto;
  display: flex;
  flex-direction: column;
}
.container {
  display: flex;
  align-items: center;
  flex-grow: 1;
}
.content {
  flex-grow: 1;
  text-align: center;
}
img {
  border: 1px solid red;
}
<div class="body">
 <div class="container">
    <div class="content">
      <img src="http://placehold.it/700x700" />
    </div>
  </div>
</div>