CSS流体柱,固定边距; 圣杯的圣杯

Dan*_*ugg 48 html css fluid-layout

更新和摘要

我觉得有义务让这个问题更清楚,因为现在有一个赏金.

(另外,我很确定当calc()支持CSS3单元值时,这将是孩子的游戏,做类似的事情width: calc(25% - 5px);虽然我们可能会在那时在我们的脑海中浏览互联网)

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

我最初的尝试使用了所描述的流体柱.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; /* so padding doesn't increase width */
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

这个片段会产生类似于下图的布局,但是所有.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 */
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

再次,这很好用,产生的结果更接近下图的结果,但是现在(实际)问题是填充物正在进入柱的宽度,从而拧紧宽度分布.该:first-child列有10个像素(或任何边距大小)更大的内容区域宽度比它的兄弟姐妹.

这可能看起来无害,甚至不明显; 然而,在某些情况下,元素之间具有精确(尽可能精确)的宽度分布是必要的,或者会使事情变得更加容易.

所以,无论是使用填充,边距还是其中某种组合; 是否有流体柱,固定边距的任何解决方案,均匀分布的沟槽空间不会从相邻列中抢夺"边缘"(***哈哈*)内容区域?**


原始问题

由于我的搜索和尝试简单地缺乏结果,我得出结论这是不可能的.如果任何地方都能得到答案,我肯定它就在这里.

有没有办法,使用纯CSS,以实现具有固定宽度边距的流体宽度圆柱布局?

重要提示:这个图只是一个例子,而不是我想要实现的具体布局.给定的解决方案应允许相邻列的任何组合,总宽度分布总计为12或更小.考虑流行的960网格作为参考.)

super_awesome_layout.css
注意:在12列布局中,图像中列的宽度分布分别为2,3,2和5.

到目前为止,我已经使用了一个网格,使用百分比几乎完成了这一点.问题是,为了获得边距,每列需要一个额外的孩子(我称之为.panel):

width: 100%;
box-sizing: border-box;
padding: 10px;
Run Code Online (Sandbox Code Playgroud)

几乎是好的; 问题在于这种方法是第一列和最后一列具有外部"边距"(10px)并且每列之间的"边距"加倍(2 x 10px)

当然,通过包含新的CSS3 calc()值类型,可以更容易地解决这个问题.朝向的方向:

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

我有一些Javascript修复,我已经破解了一些"有效"的东西,但我正在寻求.希望最神圣的圣杯存在.

不幸的是,下面的解决方案和@avall提供的(虽然肯定是简化的一个很好的选择)并不是我想要的.主要问题是,边距不是在列之间平均分配.

我能看到这个工作的唯一方法是减少.panel填充到以下内容5px:

.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;
}
Run Code Online (Sandbox Code Playgroud)

这个解决方案是不可接受的,只是因为IE8无法识别:last-child(并且就此而言:only-child)伪选择器.

小智 64

我终于想通了.在过去的十年中浪费了数百小时的浪费(虽然我依赖于一些年前无法工作的css).我解决了它没有任何陷阱.在IE8 +中.

请准备2001:太空漫游音乐,因为我正在登陆这艘船.

这种方法的天才和技巧在于使用内联块元素,然后使用字间距来使用负右边距来抵消.它自身的负右边距会将元素拉到一起,允许你设置100%的宽度并且仍然适合它们之间的东西,但是让元素重叠.设置父母的负边距只是撤消子边距关于与总宽度交互的影响(我们试图击中的魔术"100%宽度"标记").填充仅用于增加元素的大小对于反作用边际而言,它是无用的.它通常用于陪审团操纵解决方案中的盒子大小,但代价是失去了使用填充的能力,否则可能需要更多包装元素.

字间距提供了神奇的"第三种方式"来添加或删除两个元素之间的水平距离,前提是它们是内联块,因为在这种情况下它们将被计为单个"单词",并且它们之间的任何空格都将合并为一个可控的"字间距"属性.除了这个技巧,我不知道另一种获得100%结果的方法.

我谦卑地提出了固定水槽柔性柱问题的最终答案.我在此命名我的解决方案"欧米茄机动".它具有处理任意混合宽度列的能力(精确加起来总宽度的100%或略小于圆角),任何装订线尺寸,宽度上任何预定义的列数,使用自动换行处理任意数量的行,以及使用嵌入式块元件,以便因此提供来与内联块的垂直取向的选择,并且它不需要任何额外的标记,只需要在容器上的单个类声明(不计算定义列宽).我认为代码说明了一切.这是使用10px排水沟和奖金助手类百分比的2-6列的代码实现.

编辑:有趣的难题.我设法得到两个略有不同的版本; 一个用于mozilla和ie8 +,另一个用于webkit.似乎单词间距技巧在webkit中不起作用,我不知道为什么其他版本在webkit中工作但不是ie8 +/mozilla.结合两者可以让你覆盖所有内容,我愿意打赌有一种方法可以统一这种策略或类似于解决问题的方法.

编辑2:大部分都得到了!Magical text-align: justify几乎在那里使用单词间距获取WebKit.间距似乎有点偏离,就像右边的像素,也可能是排水沟中的一个.但是它可以使用,并且保持列比我之前使用的任何东西都更可靠.它永远不会减少到更少的列,它会压缩直到浏览器获得一个水平滚动条.

编辑3:有点接近完美.将font-size设置为0会将大部分剩余问题规范化为间隔关闭.只需要修复IE9,如果它的字体大小为0,则会崩溃它.

编辑4:从其他一些流畅的帖子得到IE的答案:-ms-text-justify: distribute-all-lines.在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; }
Run Code Online (Sandbox Code Playgroud)

一些助手:

.?, .?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%; }
Run Code Online (Sandbox Code Playgroud)

你可以在这里的荣耀之中见证我的巨着: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>
Run Code Online (Sandbox Code Playgroud)

绝对最小的实现,使用4个相等宽度(25%)宽度cols和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; 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>
Run Code Online (Sandbox Code Playgroud)

Soooo这个代码基本上取代了几乎任何现有的网格框架吗?如果你可以任意设置排水沟,然后只是制作100%宽度的列,那实际上不是大多数/所有网格框架都不是吗?如果你不再像我们很多人一样为IE7开发那么结合盒子大小: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; }
Run Code Online (Sandbox Code Playgroud)

相同的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>
Run Code Online (Sandbox Code Playgroud)

我在这里击败了CSS,这是你的证明

  • 你可能已经解决了这个问题,但在这个过程中你似乎已经疯了.干得好! (51认同)
  • 伙计,我认为这可能会引起比它更多的兴趣.我将采取我的Keep of the Columns标题并自己参加派对. (6认同)
  • 你应该获得额外的"9.999999999999847e + 2447"声望.我将在此后正式将此视为"*Benvie Omega Layout*".认真.请注意,我没有回应这么久,因为我从纯粹的聪明才智处于昏迷状态. (3认同)

NGL*_*GLN 8

试试这个纯CSS2解决方案:演示小提琴

基础CSS (没有化​​妆品的小提琴):

html, body {
    padding: 0;
    margin: 0;
}
#wrap {
    padding-right: 30px;
    overflow: hidden;
}
.col {
    float: left;
    margin-left: 40px;
    margin-right: -30px;
}
.col:first-child {
    margin-left: 0;
}
.small {
    width: 16.66%;
}
.medium {
    width: 25%;
}
.large {
    width: 41.66%;
}
Run Code Online (Sandbox Code Playgroud)

HTML:

<div id="wrap">
    <div class="col small"></div>
    <div class="col medium"></div>
    <div class="col small"></div>
    <div class="col large"></div>
</div>
Run Code Online (Sandbox Code Playgroud)

在IE7,IE8,IE9,Opera 11.50,Safari 5.0.5,FF 6.0,Chrome 13.0的Win7上测试.


更新:

现在,如果您希望使用任意数量的列,则必须在容器中添加一个额外的类,指定列数:

<div class="cols-12 count-04">
    <div class="col width-02"></div>
    <div class="col width-03"></div>
    <div class="col width-02"></div>
    <div class="col width-05"></div>
</div>
Run Code Online (Sandbox Code Playgroud)

查看此更新的小提示,演示了许多不同的列数.

可能的错误:

从理论上讲,imho这个解决方案应该适用于任何浏览器窗口宽度中每个可能的最小列宽的任意数量的列.但似乎所有浏览器都证明无法处理:1.大量1列宽列,或2.浏览器窗口宽度小.

请注意,所有浏览器的最小宽度为1440像素,等于12倍120像素(所有10px边距占用的空间),处理解决方案就好了.当您使用2个或更多列宽列时,对最小浏览器宽度的要求确实下降到720像素(6*120px).最后一种情况听起来更加真实,但仍然无法解释这种浏览器行为.

我尝试通过引入一个额外的最后一个列类来解决这个问题,正如这个小提琴演示的那样,但它并没有解决小浏览器宽度的问题.尽管如此,由于宽度百分比的破坏,它可以解决一个微小的舍入错误,但我认为这个问题可以忽略不计.

我想听听其他css专家的意见,所以我加了一笔赏金.


ava*_*all 7

你为什么不用

.column > .panel {
    padding: 10px 0 10px 10px;
}

.column:first-child > .panel {
    padding-left: 0px;
}
Run Code Online (Sandbox Code Playgroud)

它只会在盒子之间产生10px空间而不使用last-child.