使用CSS的子元素的均匀分布高度 [英] Evenly distributed height of child elements with CSS

查看:560
本文介绍了使用CSS的子元素的均匀分布高度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您需要向用户呈现颜色列表。颜色必须以固定高度显示在列表中,每种颜色占据该高度的一小部分。



这里是四种颜色,列表高度为90像素,周围有一个粗边框:





上述图片是在Firefox 3.6.13中从以下来源呈现的:

 < ul style =height:90px; border:5px solid black; padding:0;> 
< li style =height:25%; background:red;>
< li style =height:25%; background:blue;>
< li style =height:25%; background:yellow;>
< li style =height:25%; background:green;>
< / ul>

这没关系。该列表确实是90像素高 - 在边框内 - 每个颜色获得这个空间(看似)相等的份额。现在,让我们在Safari或Chrome中呈现相同的HTML / CSS:





请注意绿色行和边框之间的窄白色行。这里有一个很简单的解释: 0.25×90 = 22.5



Safari中的WebKit Chrome真的不喜欢非整数像素高度,并丢弃小数。用四行高度22,我们在列表底部得到2个像素的空白: 90 - 4×22 = 2



在静态HTML文件的上下文中,我们可以轻松地将元素的高度设置为23,22,23,23像素,并且列表在任何浏览器中都会显示。另一方面,如果从数据库加载颜色,并且计数随着每个请求而变化,则需要更灵活的解决方案。



我知道如何解决这个问题通过使用Javascript计算和设置每行 onload 上的整数值高度,如果没有其他显示,我将发布此解决方案。然而,我会更喜欢纯粹基于CSS的解决方案。你能想到一个吗?

解决方案

如所承诺的,这里有一个Javascript解决方案。我仍然对一个简单的基于CSS的解决方案很感兴趣,但在此期间,这个答案可能有助于其他人完成他们的工作。



脚本需要声明两个变量在输入点: list 应该指向容器的DOM元素(例如< ul> ),和项目添加到此列表中的项目集合(例如< li> )。
$ b

这个想法是动态设置每个项目上的显示高度(以像素为单位),以确保高度的总和等于容器的高度,同时允许高度之间的最小偏差项目。我们通过循环遍历项目,计算每个项目的积分高度,只需将剩余的可用空间除以剩余的项目数,以便设置明确的高度。

  var spaceRemaining = list.clientHeight; 
var itemsRemaining = items.length;

while(itemsRemaining> 0){
var itemHeight = Math.round(spaceRemaining / itemsRemaining);
items [itemsRemaining - 1] .style.height = itemHeight;
spaceRemaining - = itemHeight;
itemsRemaining - = 1;
}

对于那些喜欢简洁的可读性,这里是一个较短的版本的非常相同的脚本:

  for(var space = list.clientHeight,i = items.length; i; i--){
space - = items [i-1] .style.height = Math.round(space / i);
}


Assume you need to present a list of colors to the user. The colors must be displayed in a list with a fixed height, with each color occupying an equal fraction of that height.

Here is what it should look like with four colors, a list height of 90 pixels and a thick border around:

The image above is rendered in Firefox 3.6.13 from the follow source:

<ul style="height: 90px; border: 5px solid black; padding: 0;">
    <li style="height: 25%; background: red;">
    <li style="height: 25%; background: blue;">
    <li style="height: 25%; background: yellow;">
    <li style="height: 25%; background: green;">
</ul>

This is all fine. The list is indeed 90 pixels heigh – within the borders – and each color gets an (seemingly) equal share of this space. Now, let's render the same HTML/CSS in Safari or Chrome:

Notice the narrow white row between the green row and the border. There is a pretty simply explanation for what we are seeing here: 0.25 × 90 = 22.5

WebKit in Safari and Chrome does not really like non-integer pixel heights and drops the decimal. With four rows of height 22 we get 2 pixels of nothing in the bottom of the list: 90 - 4 × 22 = 2

In the context of a static HTML file, we could easily set the height of the elements to 23, 22, 23, 23 pixels respectively, and the list would show up fine in any browser. If, on the other hand, the colors are loaded from a database and the count varies with each request, a more flexible solution is needed.

I know how to solve this by computing and setting an integer value height on each row onload using Javascript, and I will post this solution if nothing else shows up. I would, however, prefer a purely CSS-based solution to the problem. Can you think of one?

解决方案

As promised, here's a Javascript solution to the problem. I am still very interested in a simple CSS based solution, but in the meantime, this answer might help others getting their job done.

The script expects two variables to be declared at the point of entry: list should point to the DOM element of the container (eg <ul>), and items to the collection of items (eg <li>) in this list.

The idea is to dynamically set an explicit height in pixels on each item, in a way that ensures that the sum of the heights equals the height of the container, while allowing only minimal deviation of height between items. We do this by looping over the items, computing an integral height for each, by simply dividing the remaining available space with the number of items left to have an explicit height set.

var spaceRemaining = list.clientHeight;
var itemsRemaining = items.length;

while (itemsRemaining > 0) {
    var itemHeight = Math.round(spaceRemaining / itemsRemaining);
    items[itemsRemaining - 1].style.height = itemHeight;
    spaceRemaining -= itemHeight;
    itemsRemaining -= 1;
}

For those favoring conciseness over readability, here's a shorter version of the very same script:

for (var space = list.clientHeight, i = items.length; i; i--) {
    space -= items[i-1].style.height = Math.round(space / i);
}

这篇关于使用CSS的子元素的均匀分布高度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆