CSS流体柱,固定利润;圣杯圣杯 [英] CSS fluid columns, fixed margins; the holy grail of holy grails

查看:250
本文介绍了CSS流体柱,固定利润;圣杯圣杯的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新&总结



我觉得有必要让这个问题更清楚,因为有附加的赏金。



em>此外,我确信这将是孩子的游戏,当 calc() CSS3单位值支持,做类似 width:calc (25%-5px);虽然我们可能会在这一点上在我们的脑海中浏览互联网)



为一些共享设计要求的项目开发一个CSS框架;即流体12柱布局。使用百分比宽度为(100%/ 12)x col_size 的浮动 .column 元素,这是相当容易的。但是,问题是在列之间添加了固定的边距(或任何形式的间距)。



如所描述的,每个 .panel 子嵌套。下面是HTML / CSS代码段(为简洁起见缩小):

 。 column {
float:left;
display:inline-block;
}

.width-01 {width:8.3333%; }
.width-02 {width:16.6666%; }
.width-03 {width:25%; }
/ * etc * /

.panel {
width:100%;
padding:5px;
box-sizing:border-box; / *,所以padding不会增加宽度* /
}



 < div class =column width-02> 
< div class =panel> Width-02< / div>
< / div>
< div class =column width-03>
< div class =panel> Width-03< / div>
< / div>
< div class =column width-02>
< div class =panel> Width-02< / div>
< / div>
< div class =column width-05>
< div class =panel> Width-05< / div>
< / div>

此片段将产生与下图类似的布局,但 .panel 元素在所有侧面都有 5px 填充。 我试图使外部列的内容边缘与视口( 的父容器)的边缘齐平。另一种方法是删除 .panel 类,并且只需要加上列:

  .column {
float:left;
display:inline-block;
padding-left:10px;
box-sizing:border-box;
}

.column:first-child {padding-left:0px; }

.width-01 {width:8.3333%; }
.width-02 {width:16.6666%; }
.width-03 {width:25%; }
/ * etc * /



 < div class =column width-02> Width-02< / div> 
< div class =column width-03> Width-03< / div>
< div class =column width-02> Width-02< / div>
< div class =column width-05> Width-05< / div>

同样,这种方法很好,产生的结果更接近下面的图像,然而现在(实际)的问题是,填充正在吃宽度的列宽拧紧宽度分布。 :first-child 列有10个像素(或任何边距大小)比它的兄弟姐妹更大的内容区域宽度。 / p>

这可能看起来无害,甚至不明显;但是有一些情况下,在元素之间使用确切尽可能精确)宽度分布是必要的,否则会使事情变得更容易。



因此,是否使用填充,边距或其某种组合;有没有任何解决方案的流体柱,固定利润,均匀分布的沟槽空间,不会抢夺相邻列的边缘(***哈哈* )内容区域? **






原始问题



的结果在我的搜索和尝试,我总结这是不可能的。



有什么办法,使用纯CSS,实现一个流体宽度的列布局具有固定宽度边距?:此图仅是一​​个示例,而不是具体的布局I 希望实现。给定的溶液应该允许相邻柱的任何组合,总宽度分布总共为12或更小。请考虑常见的

 < div class =cols4> 
< div class =⅙>这是我的magnum opus< / div>
< div class =¼>我最后打败了css< / div>
< div class =⅙>⚉☺☻♾☢< / div>
< div class =blarg-five-twelfs> I BEAT IT FOREVER< / div>
< / div>

绝对最小实现,使用4个等宽(25%)宽和10px是这样的:

  .fourEqualCols {word-spacing:40px; padding:0 40px 0 10px; 
text-align:justify; font-size:0;
-ms-text-justify:distribute-all-lines; }

.fourEqualCols> * {margin-right:-30px;宽度:25%;
display:inline-block;字间距:正常;
text-align:left; font-size:13px; }


< div class =fourEqualCols>
< div> GLORIOUSLY CLEAN MARKUP< / div>
< div>我讨厌额外的标记和过多的类道具< / div>
< div>裸体代码< / div>
< div> get intimate< / div>
< / div>

Soooo这个代码实质上替代了现有的网格框架吗?如果你可以任意设置gutters,然后只是使列的命中100%的宽度,这是严格优于大多数/所有网格框架其实不是吗?如果你不是为IE7开发更多像我们很多,那么结合box-sizing:border-box呈现填充和边框也是一个非问题。



编辑:哦,你想要与容器的两侧齐平。没有问题,我不得不专门添加边槽,所以我们可以只是改变一些值10,并摆脱填充和中提琴。 http://jsfiddle.net/bTty3/

  [class ^ = cols] {text-align:justify; font-size:0; 
-ms-text-justify:distribute-all-lines; }

[class ^ = cols]> * {display:inline-block; text-align:left; font-size:13px;
word-spacing:normal; vertical-align:top;
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
box-sizing:border-box; }

.cols2 {word-spacing:20px; padding-right:10px; }
.cols3 {word-spacing:30px; padding-right:20px; }
.cols4 {word-spacing:40px; padding-right:30px; }
.cols5 {word-spacing:50px; padding-right:40px; }
.cols6 {word-spacing:60px; padding-right:50px; }
.cols2> * {margin-right:0}
.cols2> * {margin-right:-10px; }
.cols3> * {margin-right:-20px; }
.cols4> * {margin-right:-30px; }
.cols5> * {margin-right:-40px; }
.cols6> * {margin-right:-50px; }

相同的html

 < div class =cols4> 
< div class =⅙>这是我的magnum opus< / div>
< div class =¼>我最后打败了css< / div>
< div class =⅙>⚉☺☻♾☢< / div>
< div class =blarg-five-twelfs> I BEAT IT FOREVER< / div>
< / div>


Update & Summary

I feel obligated to make this question clearer, now that there is a bounty attached.

(Also, I'm pretty sure this will be child's play when the calc() CSS3 unit value is supported, doing something like width: calc(25% - 5px); though we'll probably be browsing the internet in our minds by that point)

I'm working on a CSS framework for a few projects that share design requirements; namely a fluid 12 column layout. Using floated .column elements with percentage widths of (100% / 12) x col_size, this is reasonably easy. However, the issue comes with the addition of fixed margins (or any form of spacing) between columns.

My initial attempt used the fluid columns as described, with a .panel child nested in each. HTML/CSS snippet follows (reduced for brevity):

.column{
    float: left;
    display: inline-block;
}

.width-01{ width:  8.3333%; }
.width-02{ width: 16.6666%; }
.width-03{ width:      25%; }
/* etc */

.panel{
    width: 100%;
    padding: 5px;
    box-sizing: border-box; /* so padding doesn't increase width */
}

<div class="column width-02">
    <div class="panel">Width-02</div>
</div>
<div class="column width-03">
    <div class="panel">Width-03</div>
</div>
<div class="column width-02">
    <div class="panel">Width-02</div>
</div>
<div class="column width-05">
    <div class="panel">Width-05</div>
</div>

This snippet would produce a layout similar to that of the image below, however all .panel elements have 5px padding on all sides. I'm trying to make the content edge of the outside columns flush with the edge of the view-port (or parent container for that matter). Another approach would be to eliminate the .panel class altogether, and just go with columns:

.column{
    float: left;
    display: inline-block;
    padding-left: 10px;
    box-sizing: border-box;
}

.column:first-child{ padding-left: 0px; }

.width-01{ width:  8.3333%; }
.width-02{ width: 16.6666%; }
.width-03{ width:      25%; }
/* etc */

<div class="column width-02">Width-02</div>
<div class="column width-03">Width-03</div>
<div class="column width-02">Width-02</div>
<div class="column width-05">Width-05</div>

Again, this works well, producing results even closer to that of the image below, however now the (actual) problem is that the padding is eating into the width of the columns screwing up the width distribution. The :first-child column has 10 pixels (or whatever the margin size is) greater content area width than it's siblings.

This may seem innocuous, even unnoticeable; however there are a few instances where having exact (as exact as possible) width distribution between elements is either necessary, or would make things altogether easier.

And so, whether using padding, margin, or some combination thereof; is there any solution for fluid columns, fixed margins, with even distribution of gutter space that won't rob "marginal" (***haha*) content area from the adjacent columns?**


Original Question

Due to the simple lack of results in my searches and attempts, I've concluded this is impossible. If anywhere can yield an answer though, I'm certain it is here.

Is there any way, using pure CSS, to achieve a fluid width columned layout with fixed width margins?

Important note: This figure is only an example, and not the specific layout I'm looking to achieve. A given solution should permit any combination of adjacent columns, the total width distribution totaling 12 or less. Consider the popular 960 grid for reference.)


Note: In a 12 column layout, the width distribution of the columns in the image are 2, 3, 2, and 5 respectively.

So far, I've resorted to a grid that, using percentages, nearly accomplishes this. The problem is, in order to achieve the margins, each column requires an additional child (I call them .panel) with:

width: 100%;
box-sizing: border-box;
padding: 10px;

This is, again nearly, fine; the issue is with this approach is that the first and last column have outer "margins" (10px) and the "margins" between each column are doubled (2 x 10px)

Certainly, with the inclusion of the new CSS3 calc() value type, this could be solved much more easily. Something in the direction of:

.width-12 > .panel{ width: 100%; }
.width-09 > .panel{
    width: calc(75% - 10px);
    margin: ...;
}

I've got some Javascript fixes, I've hacked out some stuff that "works", but I'm on a quest. Hopefully the holiest of grails exists.

The following solution, and the one @avall provided (although certainly a good choice on simplifying) unfortunately aren't what I'm looking for. The main issue being, the margins are not distributed evenly among columns.

The only way I can see this working is reducing the .panel padding to 5px and something like:

.column:first-child > .panel {
    padding-left: 0px;
}

.column:last-child > .panel {
    padding-right: 0px;
}

/* not necessary? in any case, haven't tested */
.column:only-child > .panel {
    padding-right: 0px;
    padding-left: 0px;
}

This solution is not acceptable, only because IE8 fails to recognize the :last-child (and for that matter :only-child) pseudo selectors.

解决方案

I finally figured out. After into the hundreds of hours wasted on and off over the last decade (though I'm relying on some css that wouldn't have worked year ago anyway). I solved it without any gotchas. and in IE8+.

Please prepare the 2001: A Space Odyssey Music because I'm landing this boat.

The genius and trick to this method is in using inline-block elements and then using word-spacing to counterbalance using a negative right margin. A negative right margin on it's own will pull elements together, allowing you to have 100% width set and still fit things in between, but leave the elements overlapping. Setting negative margin on the parent just undoes the child margin in regards to the effect on interacting with total width (the magic "100% width" mark we're trying to hit"). Padding only serves to increase the size of the element its on and is useless with regards to counter-acting margin. It is often used with box-sizing in the jury rigged solutions to this problem, at the expense of losing the ability to use padding at all otherwise (and margin) and likely requiring more wrapper elements.

word-spacing provides the magical "third way" to add or remove horizontal distance between two elements, provided they are inline-block, since they will be counted as a single "word" in that case, and any whitespace between will collpapse down to the one single controllable "word-spacing" property. Aside from this trick I'm not aware of another way to get this 100% result.

I humbly present the ultimate answer to the fixed-gutters flex-columns problem. I hereby name my solution "the omega maneuver". It comes with the ability to handle arbitrary mixed width columns (adding up to 100% total width exactly or slightly less for rounding), any gutter size, any predefined amount of columns in width, handles arbitrary amounts of rows with auto-wrapping, and uses inline-block elements so therefore provides the vertical-alignment options that come with inline-block, AND it doesn't require any extra markup and only requires a single class declaration on the container (not counting defining column widths). I think the code speaks for itself. Here's the code implementation for 2-6 columns using 10px gutters and bonus helper classes for percentages.

EDIT: interesting conundrum. I've managed to get two slightly different versions; one for mozilla and ie8+, the other for webkit. It seems the word-spacing trick doesn't work in webkit, and I don't know why the other version works in webkit but not ie8+/mozilla. Combining both gets you coverage over everything and I'm willing to bet there's a way to unify this tactic or something very similar to work around the issue.

EDIT2: Mostly got it! Magical text-align: justify gets WebKit almost there with the word-spacing one. The spacing just seems a tiny bit off, like a matter of pixels on the right and maybe one extra in the gutters. But it's usable and it seems more reliable about keeping the columns than anything I've used before. It never chops down to fewer columns, it'll compress until the browser gets a horizontal scrollbar.

Edit3: Got it a little close to perfect. Setting the font-size to 0 normalizes most of the remaining issues with spacing that's off. Just gotta fix IE9 now which collapses it if it font is size 0.

EDIT4: Got the answer to IE from some other fluid width posts: -ms-text-justify: distribute-all-lines. Tested in IE8-10.

/* The Omega Maneuver */
[class*=cols] { text-align: justify; padding-left: 10px; font-size: 0;
             -ms-text-justify: distribute-all-lines; } 

 [class*=cols]>* { display: inline-block; text-align: left; font-size: 13px;
                word-spacing: normal; vertical-align: top;
                -webkit-box-sizing: border-box;
                   -moz-box-sizing: border-box;
                        box-sizing: border-box; }

.cols2 { word-spacing: 20px; padding-right: 20px; }
.cols3 { word-spacing: 30px; padding-right: 30px; }
.cols4 { word-spacing: 40px; padding-right: 40px; }
.cols5 { word-spacing: 50px; padding-right: 50px; }
.cols6 { word-spacing: 60px; padding-right: 60px; }

  .cols2 > * { margin-right: -10px; }
  .cols3 > * { margin-right: -20px; }
  .cols4 > * { margin-right: -30px; }
  .cols5 > * { margin-right: -40px; }
  .cols6 > * { margin-right: -50px; }

Some helpers:

.⅛, .⅛s >* { width: 12.50%; }
.⅙, .⅙s >* { width: 16.66%; }
.⅕, .⅕s >* { width: 20.00%; }
.¼, .¼s >* { width: 25.00%; }
.⅓, .⅓s >* { width: 33.00%; }
.⅜, .⅜s >* { width: 37.50%; }
.⅖, .⅖s >* { width: 40.00%; }
.½, .½s >* { width: 50.00%; }
.⅗, .⅗s >* { width: 60.00%; }
.⅝, .⅝s >* { width: 62.50%; }
.⅔, .⅔s >* { width: 66.00%; }
.¾, .¾s >* { width: 75.00%; }
.⅘, .⅘s >* { width: 80.00%; }
.⅚, .⅚s >* { width: 83.33%; }
.⅞, .⅞s >* { width: 87.50%; }
.blarg-five-twelfs { width: 41.66%; }

You can witness my magnum opus in action amongst a field of glory here: http://jsfiddle.net/xg7nB/15/

<div class="cols4">
    <div class="⅙">This is my magnum opus</div>
    <div class="¼">I finally beat css</div>
    <div class="⅙">⚉ ☺ ☻ ♾ ☢</div>
    <div class="blarg-five-twelfs">I BEAT IT FOREVER</div>
</div>

The absolute minimal implementation, using as an example 4 equal width (25%) width cols and 10px gutters is like so:

.fourEqualCols { word-spacing: 40px; padding: 0 40px 0 10px;
                 text-align: justify; font-size: 0;
                 -ms-text-justify: distribute-all-lines; }

.fourEqualCols>* { margin-right: -30px; width: 25%;
                   display: inline-block; word-spacing: normal;
                   text-align: left; font-size: 13px; }


<div class="fourEqualCols ">
  <div>GLORIOUSLY CLEAN MARKUP</div>
  <div>I hate extra markup and excessive class props</div>
  <div>Naked code</div>
  <div>get intimate</div>
</div>

Soooo this code essentially replaces pretty much any existing grid framework right? If you can arbitrarily set gutters and then just make sets of columns that hit 100% width, that's strictly superior to most/all grid frameworks in fact isn't it? If you're not developing for IE7 anymore like a lot of us then that combined with box-sizing: border-box renders padding and border also a non-issue.

Edit: oh right you wanted to be flush with the sides of the container. No problem with this, I had to specifically add side gutters so we can just change some values by 10 and get rid of the padding and viola. http://jsfiddle.net/bTty3/

[class^=cols] { text-align: justify; font-size: 0;
             -ms-text-justify: distribute-all-lines; } 

 [class^=cols] >* { display: inline-block; text-align: left; font-size: 13px;
                word-spacing: normal; vertical-align: top;
                -webkit-box-sizing: border-box;
                   -moz-box-sizing: border-box;
                        box-sizing: border-box; }

.cols2 { word-spacing: 20px; padding-right: 10px; }
.cols3 { word-spacing: 30px; padding-right: 20px; }
.cols4 { word-spacing: 40px; padding-right: 30px; }
.cols5 { word-spacing: 50px; padding-right: 40px; }
.cols6 { word-spacing: 60px; padding-right: 50px; }
 .cols2 >* { margin-right: 0 }
 .cols2 >* { margin-right: -10px; }
 .cols3 >* { margin-right: -20px; }
 .cols4 >* { margin-right: -30px; }
 .cols5 >* { margin-right: -40px; }
 .cols6 >* { margin-right: -50px; }

Same html

<div class="cols4">
    <div class="⅙">This is my magnum opus</div>
    <div class="¼">I finally beat css</div>
    <div class="⅙">⚉ ☺ ☻ ♾ ☢</div>
    <div class="blarg-five-twelfs">I BEAT IT FOREVER</div>
</div>

这篇关于CSS流体柱,固定利润;圣杯圣杯的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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