我有一个带有几个英文句子的HTML表单,每行可视化显示一个句子。在每个句子的中间有一个<select>
下拉列表,其左右边缘需要在多行之间对齐,以使其看起来更干净:
<div class="row">
<div class="column col1"> <p> Choose something: </p> </div>
<div class="column col2"> <select name="dropdown"> ... options ... </select> </div>
<div class="column col3"> <p> and finish the sentence.</p> </div>
</div>
<div class="row">
<div class="column col1"> <p> Choose something else: </p> </div>
<div class="column col2"> <select name="dropdown2"> ... options ... </select> </div>
<div class="column col3"> <p> and finish another sentence.</p> </div>
</div>
<div class="row">
<div class="column col1"> <p> Choose last thing: </p> </div>
<div class="column col2"> <select name="dropdown3"> ... options ... </select> </div>
<div class="column col3">
<p>
and all dropdowns should be left- and right-aligned if
there is space. This longer third column should get broken
onto a second line below the second dropdown if it can't fit
immediately to the right of the other two.
</p>
</div>
</div>
然而,这是一个响应式布局,我只想修复中间列的宽度,并根据以下设计标准自动扩展/收缩第1列和第3列:
column
中尽可能多的row
个元素应该左右放置,具体取决于视口宽度。col2
元素应左对齐。在上面,第一个优先考虑第二个;换句话说,如果我们从足够宽的浏览器视口开始,以适应两个标准:
col2
对齐并保持所有三个column
元素并排。col3
块应移动到col1
和col2
块之下。现在col3
不再与col1
和col2
并排,但这种牺牲意味着我们可以恢复col2
对齐。 (此时col1
的{{1}}将防止句子开头与下拉列表之间出现意外差距。)根据前两条规则,显然任何使用百分比的东西都不会起作用。并且可能是由于第3条规则,使用max-width
的任何内容都不起作用。
可以假设任何边距/填充都是固定的。 <table>
会破坏英文句子,因此overflow: hidden
元素不会有高度限制。
我已经浏览了无数的HTML / CSS文章和SO问题,但到目前为止还没有找到解释如何实现这一目标的任何内容。以下是您玩游戏的起点:
在CSS中涉及HTML5或更新功能的解决方案比基于JavaScript的黑客更受欢迎。改变HTML的解决方案是可以的,虽然我很想知道它是否只能通过CSS实现。谢谢!
答案 0 :(得分:1)
采用JavaScript / JQuery方法,我会提供一个想法,但不是代码本身。 我的代码部分不是真正的代码,而是说明需要做什么。 (CSS部分除外)
首先,我们将页面中所有元素的框大小设置为边框,因为它更容易以这种方式计算元素的大小。
*
{
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box; /* Opera/IE 8+ */
}
这意味着.col2的宽度必须增长10px才能支持10px填充并保持不变。
.col2
{
width: 120px;
}
如果第二列始终位于第一列的旁边,那将是最好的, 所以我们将设置.col1的最大宽度以支持该行为。
.col1
{
max-width: calc(100% - 136px); /*136 = 120 + 2*5 + 2*3*/
}
在整个过程中,我们不会将任何内容设置为.row&amp; .col3宽度。 行可以缩小或增长,而.col3将始终占用所需的确切空间量 (无论他是否与.col1&amp; .col2或在不同的行中对齐),实际上我们只改变.col1宽度。
当页面首次加载时,每次主体调整大小时,我们都会调用一个找到最佳布局的javaScript函数。
function adjustToBestLayout()
{
1.
2.
3.
4.
}
在这个过程中,我们需要知道.col1&amp;的实际大小是多少。当前视口大小中的.col3元素(.col2是固定的,所以它有帮助) 如果我们不应用脚本,因为它们的宽度取决于它们的内容,并且可能会在不同的视口大小中发生变化。
所以,如果我们第一次进入该功能,我们将“保存”我们的干净布局,而不是脚本干预。 然后,每次我们进入该功能时,我们将用干净的布局替换旧的调整后的布局,并从头开始重新调整。
所以它是这样的:
1 带回“干净”的布局。 现在我们在每行中都有以下内容: .col1&amp; .col2是对齐的,每个都取其内容的大小, 和.col3(也完全取其内容的大小)可以处于两种可能的状态之一, 他可以与两个第一列对齐,也可以换成新行。
2 每个列元素都会将其实际宽度保存在名为ActualWidth的属性中供以后使用
每行3 ,我们将计算AvailableWidth并将其保存为属性供以后使用,计算结果如下:
if(row.width >= row.col1.ActualWidth + row.col2.ActualWidth + row.col3.ActualWidth)
{
//in this case, all columns are in the same line, and we possibly have space left
row.AvailableWidth = row.width - (row.col1.ActualWidth + row.col2.ActualWidth + row.col3.ActualWidth);
}
else
{
//in this case, the third column is in a different line,
row.AvailableWidth = row.width - (row.col1.ActualWidth + row.col2.ActualWidth);
}
当我们将.col1元素拉伸到相同宽度时,将找到最佳布局, 所以我们将尝试将.col1拉伸到布局中更大的.col1元素的大小。 但是没有导致任何.col3元素到达新行, 所以我们只能通过他的row.AvailableWidth或更少来拉伸每个.col1元素。
4 通过此计算找到给予.col1元素的最佳宽度: 对于每个.col1,如果我们将另一个.col1拉伸到他的大小,我们将计算将对齐多少行。 并且我们将采用得分最大的那个。 所以,对于每个.col1.ActualWidth(= CurrentWidth):有多少行对此语句返回true
0 <= CurrentWidth - row.col1.CurrentWidth <= row.AvailableWidth
之后,我们将.col1元素的宽度固定为获胜宽度 (仅在返回true的行中返回前一个语句)
Etvoilà!
Finnaly:如果我是你,我会选择“像桌子一样”的“固定”布局。
答案 1 :(得分:0)
我终于想出了以下CoffeeScript解决方案:
fixSizes = ->
col1_min = parseInt $(".col1").css("min-width")
col1_max = parseInt $(".col1").css("max-width")
console.log "min #{col1_min}, max #{col1_max}"
$(".row").each (i, row) =>
debug = false
r = $(row)
row_width = r.width()
col1_width = r.find(".col1").width()
col1_outer = r.find(".col1").outerWidth(true)
col2_outer = r.find(".col2").outerWidth(true)
col3_outer = r.find(".col3").outerWidth(true)
col1_spacing = col1_outer - col1_width
space_for_col1 = row_width - col1_spacing - col2_outer - col3_outer
if i == 1
debug = true
if debug
console.log "row#{i} #{row_width}, col1 #{space_for_col1}, col1s #{col1_spacing}, col2 #{col2_outer}, col3 #{col3_outer}"
col1 = r.find(".col1")
col3 = r.find(".col3")
if space_for_col1 < col1_min
# Can't shrink col1 enough to fit all onto one line; break
# col3 onto new line.
col1.css("width", "#{col1_max}px")
col3.css("clear", "left")
if debug
console.log " break into two lines"
else if space_for_col1 < col1_max
# Shrink col1 to fix all onto one line. Annoyingly we
# need to shrink by an extra pixel in order to ensure that
# col3 has enough room to go on the top line and doesn't
# float directly underneath col2. This is presumably due
# to rounding errors, since the row width is a float (in
# Chrome at least).
col1.css("width", "#{Math.floor(space_for_col1)-1}px")
col3.css("clear", "")
if debug
console.log " shrink col1"
else
# No shrinking required, ensure col2 is aligned.
col1.css("width", "#{col1_max}px")
col3.css("clear", "")
if debug
console.log " fix col1 to align col2"
jQuery ->
fixSizes()
$(window).resize ->
fixSizes()
当缩小Chrome中的窗口宽度时,除了令人讨厌的闪烁之外它是有效的 - 在Javascript缩小col3
之前,col2
会立即浮动col1
。向后漂移到col2
的右侧。
但这感觉很难看。我不能不觉得必须有更优雅的东西。