【问题标题】:Responsive design with divs in each page corner响应式设计,每个页面角落都有 div
【发布时间】:2016-12-13 00:36:52
【问题描述】:

我正在进行响应式设计,我在顶部有一个 ID div,在页面的其余部分,我应该在页面的每个角落都有 div 按钮(即,我应该有 2x2 div ,每行并排两个 div,第一行与页面顶部对齐,第二行与页面底部对齐)- 在横向视图中。 (在Placing 4 html elements in every corner of a div 中讨论了类似的内容,但我无法找到如何将该解决方案应用于我的示例)。

在纵向视图中,按钮的宽度应该大约是视口宽度的大小,并且它们应该在彼此下方。我想出了以下示例:

<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <script type="text/javascript">
  </script>
  <style type="text/css">
html, body {
  margin: 0;
  padding: 0;
}
.testbtnholder {
  border: 2px solid gray;
  width: calc(100% - 1em);
  height: calc(100% - 2em);
  position: relative;
  margin-top: 0px;
  margin-left: 1em;
  margin-right: 1em;
  margin-bottom: 1em;
}
.testbtn {
  border: 2px solid #FF9999;
  width: calc(50% - 1em);
  height: 5em;
  /* line-height: 5em; // does vertical align to middle, but only for single-line text; http://phrogz.net/css/vertical-align */
  position: absolute;
  text-align: center;
  /* top: 50%; margin-top: -2.5em; // should do vertical align to middle, but it doesn't */
}
@media all and (orientation:landscape) {
  .testbtn:nth-child(even) {
    right: 0;
  }
  /*nth-last-child(-n+2) - select 2 last items from the parent*/
  .testbtn:nth-last-child(-n+2) {
    bottom: 0;
  }
}
@media all and (orientation:portrait) {
  .testbtn {
    position: relative;
    width: calc(100%);
  }
}
#dreport {
  font-size: 0.76em;
}
  </style>
</head>

<body>
  <div id="dreport">Test text</div>
  <div class="testbtnholder">
    <div class="testbtn">Test <br/> one</div>
    <div class="testbtn">Test two</div>
    <div class="testbtn">Test three</div>
    <div class="testbtn">Test <br/> four</div>
  </div>
</body>
</html>

这个横向示例在 Chromium 48 中有些工作,但在 Firefox 50 中失败(下图,左图是 Chromium,右图是 Firefox):

(事实上,如果我在 HTML 的开头添加 &lt;!DOCTYPE html&gt;,Chromium 也会产生与 FF 相同的错误布局!)

我的问题/疑问是:

  • 即使我将 htmlbody 的边距/填充设置为 0,然后为 margin-leftmargin-right 显式设置 .testbtnholder,在 FF 和 Chromium 中我都会得到某种左边距“推动”布局的其余部分,因此出现滚动条。如何显式设置边距,这样我就不必依赖overflow:hidden; 来隐藏滚动条(因此.testbtnholder 的边框在页面中水平居中显示)?
  • 我希望 div 按钮中的文本水平和垂直居中;我已经使用text-align: center 实现了水平居中,但无法让垂直居中(使用vertical-align: middle)工作
  • 如何让 Firefox 渲染与 Chromium 相同的图像(FF 渲染问题可能在 Positioning problems in Firefox? position:relative for a display:table element 中描述)
  • 有没有比我这里采用的更好的布局方法?例如,根据方向将absolute 的位置切换到relative 对我来说似乎有点骇人听闻,那么使用弹性盒布局会更好吗?我看过https://css-tricks.com/snippets/css/a-guide-to-flexbox/,但现在对我来说有点太多了 - 所以如果 flexbox 在这里更适用,我该如何重写这个例子的 HTML/CSS 来使用 flexbox?李>

否则,在纵向模式下,布局通常可以正常工作(除了边距问题):

【问题讨论】:

  • 首先,从 HTML 中取出 &lt;style&gt; 内容并将其放入 CSS 文件中,然后您可以从 HTML 标头调用。
  • 谢谢@Martin - 但据我所知,如果 CSS 包含在 HTML 中,或者在单独的文件中,渲染应该没有区别?我把它们放在一起,所以这个例子可以只用一个文件来复制......

标签: html css


【解决方案1】:
  • 您应该始终添加&lt;!DOCTYPE html&gt;。这不应该是一个例外

我不太明白您为什么要这样工作,但通过使用您提供的代码并进行以下更改:

.testbtnholder {
    /* position: relative; */
}

(横向)

这完全解决了我的布局问题。

此外,您还有一个次要问题,即宽度与窗口大小略有偏差,我认为您需要调整宽度 calc


问题:

即使我将 html 和 body 的边距/填充重置为 0,然后为 .testbtnholder 显式设置 margin-left 和 margin-right,在 FF 和 Chromium 中,我都会得到某种“推动”的左边距" 布局的其余部分,因此出现滚动条。如何显式设置边距,这样我就不必依赖溢出:隐藏;隐藏滚动条(因此 .testbtnholder 的边框在页面中水平居中显示)?

使用margin:auto 自动居中设置宽度的容器。如:

div {
    display:block;
    width: 80%;
    min-width: 200px;
    max-width: 800px;
    margin:auto; /* will always be horizontally centered */
}

我希望 div 按钮中的文本水平和垂直居中;我已经使用 text-align: center 实现了水平居中,但无法使垂直居中(使用 vertical-align: middle)工作

Flex Box 相当简单。

如何让 Firefox 渲染与 Chromium 相同的图像

一旦您设置了一致的 CSS 结构,Firefox 和 Chromium 就会非常一致。 Safari 和 IE 可能会给你带来更多的不一致问题。

有没有比我这里采用的更好的布局方法?

是的,尝试使用Flex Box

编辑:我看到你已经参考了关于 Flex Box 的阅读,老实说,指向 CSS 技巧 Flexbox 页面的链接是一个很好的起点,因为它贯穿了各个方面flexbox 逐点。坚持下去,你会变得更聪明、更强大:)

【讨论】:

  • 谢谢@Martin - re:Flex Box 链接,我的问题是理解如何在这种情况下应用它:)。删除position: relative 确实解决了一些问题(角定位),但不尊重底部和右侧边距,.testbtnholder 的高度为 0px。在 Firefox 中进行测试,positioninheritinitialstaticunset 将产生与删除 position: relative 相同的布局;但position:fixed 将具有支架高度,position: absolute 将具有支架高度和底部边距。
  • absolutely 定位元素被定位在文档流之外,所以这就像试图让气球适合鞋盒——绝对定位的元素不知道它周围的东西, 在它之前或之后。它只知道偏移量left/right/top/bottom 值。最好阅读CSS Document Flow@sdbbs
  • Document flow link。不是太深入,但希望能给你一些清晰度。 @sdbbs
【解决方案2】:

我在这里尝试过使用Flexbox,请看下面的sn-p:

html, body {
  margin: 0;
  padding: 0;
}
.testbtnholder {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  border: 2px solid gray;
  height: calc(100vh - 2em);
  position: relative;
  margin-top: 0px;
  margin-left: 1em;
  margin-right: 1em;
  margin-bottom: 1em;
}
.row {
  display: flex;
}
.row .testbtn:last-child {
  margin-left: auto;
}
/* .row:last-child .testbtn {
  align-self: flex-end;
} */
.testbtn {
  border: 2px solid #FF9999;
  padding: 10px;
  width: 40%;
  height: 5em;
  height: auto;
}
@media all and (orientation:landscape) {
  .testbtn:nth-child(even) {
    right: 0;
  }
  /*nth-last-child(-n+2) - select 2 last items from the parent*/
  .testbtn:nth-last-child(-n+2) {
    bottom: 0;
  }
}
@media all and (orientation:portrait) {
  .row {
    flex-direction: column;
  }
  .row .testbtn:last-child {
    margin-left: 0;
  }
  .row:last-child .testbtn {
    align-self: stretch;
  }
  .testbtn {
    position: relative;
    flex: 1;
    align-self: stretch;
    width: auto;
  }
}
#dreport {
  font-size: 0.76em;
}
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
  <script type="text/javascript">
  </script>
</head>

<body>
  <div id="dreport">Test text</div>
  <div class="testbtnholder">
    <div class="row">
      <div class="testbtn">Test <br/> one</div>
      <div class="testbtn">Test two</div>
    </div>
    <div class="row">
      <div class="testbtn">Test three</div>
      <div class="testbtn">Test <br/> four</div>
    </div>
  </div>
</body>
</html>

希望这是您想要实现的目标。

【讨论】:

    【解决方案3】:

    就我个人而言,横向模式使用绝对位置,纵向模式切换到 flexbox 列布局...对我来说似乎更整洁。

    示例:

    * {
          /*
          to avaid srollbars when using borders set box-sizing
          here it is set to every element
          */
          box-sizing: border-box;
        }
    
        html, body {
          margin: 0px;
          padding: 0px;
          height: 100%;
        }
    
        body {
          display: flex;
          flex-direction: column;
        }
        #header-contaier {
    
          height: 2em;
    
    
        }
        #button-container {
          position: relative;
          flex: 1 0 auto;
          margin-top: 0.5em;
    
        }
    
        .div-button {
          /*the width in landscape mode - default here*/
          width: calc(50% - 1em);
          height: 5em;
          text-align: center;
          vertical-align: middle;
          line-height: 5em;
          margin: 0;
          background: rgba(0, 75, 153, 0.8);
        }
        @media all and (orientation:landscape) {
    
          #button-1 {
            position: absolute;
            top: 0px;
            left: 0px;
          }
          #button-2 {
            position: absolute;
            top: 0px;
            right: 0px;
          }
          #button-3 {
            position: absolute;
            bottom: 0px;
            left: 0px;
          }
          #button-4 {
            position: absolute;
            bottom: 0px;
            right: 0px;
          }
        }
        @media all and (orientation:portrait) {
          /*switch to flexbox column layout*/
          #button-container {
            display: flex;
            flex-direction: column;
    
          }
          .div-button {
            /*set width to 100% and give it some margin-bottom*/
            flex: 0 0 5em;
            width: 100%;
            margin-bottom: 0.5em;
          }
        }
    <div id="header-container">Header container</div>
      <div id="button-container">
        <div id="button-1" class="div-button">Button 1</div>
        <div id="button-2" class="div-button">Button 2</div>
        <div id="button-3" class="div-button">Button 3</div>
        <div id="button-4" class="div-button">Button 4</div>
      </div>

    这个布局有更多的可能性 - 这只是一个例子。 (在 SO 上运行 Full Page 中的 sn-p 以查看横向和纵向之间的切换)

    你有滚动条是因为在使用边框时你应该使用box-sizing: border-box; 边框宽度不是在大小中计算的。

    要使垂直对齐工作,您必须设置相应的行高。 (参见本例中的 css)

    其他使文本居中的技术是可能的: 例如this question on SO

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-16
      • 1970-01-01
      相关资源
      最近更新 更多