用于在 2 个动态调整大小时对齐 3 个元素的纯 HTML/CSS 解决方案?

Posted

技术标签:

【中文标题】用于在 2 个动态调整大小时对齐 3 个元素的纯 HTML/CSS 解决方案?【英文标题】:Pure HTML/CSS solution for aligning 3 elements when 2 are dynamically sized? 【发布时间】:2015-04-22 20:21:37 【问题描述】:

这个问题需要解释一下。请多多包涵:

几个月前,我为网站上的一个部分设置了一个由三部分组成的标题。在此标题的左侧有一个标题,其内容可以更改。右侧是一个徽标,始终为 150 像素宽 x 60 像素高。它们之间是一组双线。像这样的:

[这就是标题] ========================================= [标志这里]

这个网站是响应式的,所以标题的整体宽度是可变的。 标题必须始终位于一行。 包含双线的 div 需要更改大小以填充 Title 和 Logo 之间的空间。

我最初设置它以便使用媒体查询和 calc();功能。但是,该网站必须一直兼容到 IE 8,所以我最终编写了一些 JS 来让它工作。

这是一个 JS fiddle,它本质上反映了这种行为: http://jsfiddle.net/55u5mpu2/2/

function sizeLines()  
var logoSize = document.getElementById("the-logo").offsetWidth; 
var titleWidth = document.getElementById("the-h2-Title").offsetWidth; 
var totalWidth = document.getElementById("entire-Header").offsetWidth; 
var offsetWidth = (logoSize + titleWidth); 
var linesWidth = (totalWidth - offsetWidth - 20) + "px"; 
document.querySelector("#the-lines").style.width = linesWidth;   

window.onresize = sizeLines; 
#entire-Header
  position: relative;
  width: 100%;
  height:40px;


#the-h2-Title 
  position: relative;
  float: left;
  width: auto;
    padding-right: 10px;


#the-lines 
  border-top: 4px solid #000000 !important;
  border-bottom: 4px solid #000000 !important;
  height: 1px;
  float: left;
  margin-top: 23px;
  min-width: 40px;


#the-logo 
  position: relative;
  max-width: 160px;
  max-height: 50px;
  float: right;
  width: auto;
  height: auto;
  top: 0;
<div id="entire-Header">
   <h2 id="the-h2-Title">
      <div id="headlineTextbox">This is a Test Headline</div>
   </h2>
   <div id="the-lines"> &nbsp;</div>
   <img id="the-logo" src="http://placehold.it/150x60">
</div>

问题是,脚本需要很长时间才能在慢速连接上加载,因此徽标会在一个奇怪的位置出现一段时间。因此,我试图找到一个纯粹的 CSS/html 解决方案来做与我的脚本相同的事情。

这里有相关的问题,但似乎没有一个适用。我不能在标题或线条上加上宽度,因为它们都是动态的。

表格似乎工作正常,但如果我输入 width: auto;在两个 tds 上,事情失败了。

以下是我创建的良好表格布局示例: http://jsfiddle.net/d40a429s/1/

table width: 100%;
#test-title width:20%;
#lines-here width:auto;
#lines-here > div border-top:4px solid #2a2a2a; border-bottom:4px solid #2a2a2a;height: 1px;
#test-logo width: 160px; padding-left: 10px;
<div id="test-Section-Header">
   <table>
      <tbody>
         <tr>
             <td id="test-title"><h2>Test Title</h2></td>
            <td id="lines-here">
               <div></div>
            </td>
            <td id="test-logo">
               <img src="http://placehold.it/150x60" >
            </td>
         </tr>
      </tbody>
   </table>
</div>

我试过把 position: absolute;以及徽标和标题上的顶部/左侧或顶部/右侧,但我无法让中间 div 正确调整大小。

所以:如果有人在这里做到了:关于我如何在没有 JS 的情况下让它工作的任何想法?或者也许是一种整理我的 JS 以使其运行更快的方法?

谢谢!

【问题讨论】:

【参考方案1】:

您的问题可以通过稍微修改 HTML 和 CSS 完全解决,无需 javascript

这是 Danield 的 fiddle 的分支 - 支持 IE8+

说明:

#the-logo 移动为#entire-Header 容器中的第一个元素允许我们将#the-logo 向右浮动,而不会包裹并下降到标题下方,因为它在布局时具有“更高优先级”正在计算中。

将“clearfix”添加到#entire-Header 使我们不必担心标题溢出由任何固定尺寸分配的空间。这让我们可以完全删除height 约束。 #entire-Header 是块级元素 (div),这意味着默认情况下它的宽度为 100%,不需要显式设置(除非它之前已被覆盖)。

#the-h2-Title#entire-Header 中的第二个元素,并且向左浮动。作为一个块元素 (h2),它会在将单词包装在自身内部之前将其作为一个整体包装在 #the-logo 之下。

现在我们的徽标和标题位于两侧,我们可以设置#the-lines 的样式。作为一个块级元素,它将水平扩展到可用空间,在本例中为 100%。为了防止它延伸到标题和徽标下方,我们将overflow: hiddenoverflow: auto 添加到#the-lines。这将创建一个新的block formatting context,使#the-lines 的宽度缩小到剩余的可用空间,该空间是在两个浮动元素之间计算得出的。

警告:这仅在#the-line 的高度小于#the-logo 的情况下有效,否则#the-line 将在#the-logo 下方换行。这是因为它是第三个元素,它的布局受前两个元素的影响。

CSS:

#entire-Header 
    margin: 1em 0 .5em;

/* http://nicolasgallagher.com/micro-clearfix-hack/ */
#entire-Header:before,
#entire-Header:after 
    content: " ";
    display: table;

#entire-Header:after 
    clear: both;
 
#the-h2-Title 
    margin: .5em 0;
    float: left;
    margin-right: 10px;

#the-lines 
    border-top: 4px solid #000000 !important;
    border-bottom: 4px solid #000000 !important;
    height: 1px;
    /* http://www.stubbornella.org/content/2009/07/23/overflow-a-secret-benefit/ */
    overflow: hidden;
    margin-top: 23px;

#the-logo 
    width: 160px;
    height: 50px;
    margin-left: 10px;
    float: right;

标记:

<div id="entire-Header">
    <img id="the-logo" src="http://placehold.it/150x60" />
     <h2 id="the-h2-Title">
      <div id="headlineTextbox">This is a Test Headline</div>
   </h2>

    <div id="the-lines"></div>
</div>

【讨论】:

【参考方案2】:

支持 IE8

如果您想保持对 IE8 的支持,您可以通过在 HTML 中包含 &lt;script&gt; 标记来修复加载缓慢的问题。

      ...
    </div>
  </div>

  <script>
    // JavaScript here
  </script>
</body>

不支持 IE8 (IE10+)

如果您想要纯 CSS 解决方案,请使用 flexbox。将标题设置为 flexbox,将顺序分配给标题、行和徽标,并在必要时允许行缩小和扩大。

<!-- HTML -->
<div class="container">
  <div class="title">
    Title
  </div>
  <div class="line">
    Line
  </div>
  <div class="logo">
    Logo
  </div>
</div>

/* CSS */
.container 
  display: flex;
  width: 100%;

.line 
  order: 1;
  flex-shrink: 10000000;
  flex-grow: 10000000;

.title 
  order: 0;
  flex-shrink: 1;

.logo 
  order: 2;
  flex-shrink: 1;

有关 flexbox 的更多信息,请参阅 this article 和 this useful flexbox playground。

【讨论】:

【参考方案3】:

这当然可以通过 IE8 支持来完成

1) 将定宽+右浮动图片移动到第一个孩子

2) 在标题中保留float:left

3) 在行上设置overflow:hidden(或auto)(以建立新的块格式化上下文)

4) 在容器上设置display:inline-block(以包含浮动)

Updated FIDDLE(调整浏览器大小看效果)

#entire-Header 
  display: inline-block;
  width: 100%;
  height: 40px;

#the-h2-Title 
  float: left;
  padding-right: 10px;

#the-lines 
  border-top: 4px solid #000000 !important;
  border-bottom: 4px solid #000000 !important;
  height: 1px;
  overflow: hidden;
  margin-top: 23px;

#the-logo 
  width: 160px;
  height: 50px;
  padding-left: 10px;
  float: right;
<div id="entire-Header">
  <img id="the-logo" src="http://placehold.it/150x60" />
  <h2 id="the-h2-Title">
      <div id="headlineTextbox">This is a Test Headline</div>
   </h2>
  <div id="the-lines"></div>

</div>

【讨论】:

以上是关于用于在 2 个动态调整大小时对齐 3 个元素的纯 HTML/CSS 解决方案?的主要内容,如果未能解决你的问题,请参考以下文章

使用自动布局将 3 个按钮与目标 C 中的动态内容对齐

矢量调整大小 - 检测的便携方式

即使调整窗口大小,如何确保元素正确对齐?

flex 布局换行后最后一行左对齐

怎么确定Java对象的大小

如何防止Ajax元素包装?