用于在 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"> </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: hidden
或overflow: 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 中包含 <script>
标记来修复加载缓慢的问题。
...
</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 解决方案?的主要内容,如果未能解决你的问题,请参考以下文章