0

我的数学令人震惊,我做不到,因为我一生都在做这个计算。我正在创建一个 CSS 网格系统,它允许用户指定任意数量的网格列(默认情况下有 12 个)、这些列之间的装订线、列周围的最大宽度以及该总宽度内的边距。有希望的结果是每列宽度的百分比宽度和所有列的左边距的百分比。

如果我使用下面的默认值,最大宽度将为 1200 像素,左右的内边距将为 20,为网格的最大允许空间提供 1160 的内部宽度。那有意义吗?

顺便说一句,我使用的是 SASS。查看代码中的注释以查看当前有效和无效的内容。

这是 jsFiddle 上的代码:http: //jsfiddle.net/mrmartineau/fMeBk/

$gridColumnCount      : 12;   // Total column count
$gridGutterWidth      : 40;   // [in pixels]
$gridColumnPadding    : 30;   // [in pixels]
$gridMaxWidth         : 1200; // [in pixels]
$gridMargin           : 20;   // [in pixels] Space outside the grid

@function gridColumnWidth() {
    @return $gridMaxWidth / $gridColumnCount;
}
// Grid calculations
@function gridColumnWidthCalc($colNumber) {
    // Is correct
    @if $gridGutterWidth == 0 {
        @return percentage($colNumber / $gridColumnCount);
    }
    // Is incorrect
    @else $gridMargin > 0 {
        @return percentage( (($colNumber / $gridColumnCount) - gutterCalc(false) ) );
    }
}

@mixin columns($columnSpan: 1) {
    width: gridColumnWidthCalc($columnSpan);
}
@function gutterCalc($showUnit: true) {
    @if $showUnit == true {
        @return percentage( $gridGutterWidth / ( $gridMaxWidth - ($gridMargin * 2) ) );
    } @else {
        @return $gridGutterWidth / ( $gridMaxWidth - ($gridMargin * 2) ) * 100;
    }
}

@mixin gridColumn() {
    @if $gridGutterWidth > 0 {
        margin-left: gutterCalc();
    }
    @if $gridColumnPadding > 0 {
        padding: $gridColumnPadding + px;
    }
    float: left;
    min-height: 30px;
    position: relative;
    clear: none;
    &:first-child {
        margin-left: 0;
    }
    background-color: pink;
    border: 1px solid red;
}
@for $i from 1 to $gridColumnCount + 1 {
    .span#{$i}  { @include columns($i); }
}

.container {
    padding-left: $gridMargin + px;
    padding-right: $gridMargin + px;
    max-width: $gridMaxWidth + px;
}

.col {
    @include gridColumn();
}


​
4

3 回答 3

8

好的,我花了一个小时来理解你的无注释代码。

首先,作为网格单元的“列”和作为实际元素的“列”之间存在歧义。下面我称后者为“块”。

您正确地覆盖了连续第一个块的排水沟。因此,排水沟的总数比一行中的块数少一。

但是当你计算块的宽度时,你会从每一列中减去排水沟,而没有考虑到排水沟比块少。

所以你应该按比例减小块的宽度。

工作解决方案:

// Accepts a number of columns that a block should span.
// Returns a percentage width for that block.
@mixin columns($columnSpan: 1) {
    $number-of-blocks-in-container: $gridColumnCount / $columnSpan;
    $total-width-of-all-gutters:    gutterCalc(false) * ($number-of-blocks-in-container - 1);
    $total-width-of-all-blocks:     1 - $total-width-of-all-gutters;
    $width-of-a-single-block:       $total-width-of-all-blocks / $number-of-blocks-in-container;

    width:                          percentage( $width-of-a-single-block );
}

现在你的轮子正在滚动!看看它的实际效果:http: //jsfiddle.net/fMeBk/46/请记住,浏览器会将百分比值四舍五入,但会出现轻微错误,因此网格定位可能不是像素完美的。顺便说一句,右对齐一行中的最后一个块对于最小化此舍入误差的视觉影响是必要的。

伙计,您的代码架构非常错误,并且您的方法有许多缺点。如果你愿意,我可以命名它们。

你真的应该再试一次苏西。它是 SASS 的精彩部分,也是学习 SASS 技术的重要来源。它的源代码有很好的注释并且可以在 GitHub 上找到。

根据您的说法,Susy 缺乏您的网格框架的哪些功能?

我向你保证,苏西可以为所欲为。只需解释一个任务,我就会尝试利用 Susy 提出一个优雅的解决方案。

PS我并不是要劝阻你不要尝试。熟能生巧!实验必要的,而且你做得很好。我想告诉你的是,你应该遵循一个好的榜样并采取良好的做法,这样你就不会走错地方。

PPS 请给我我的评价。我花了很多个人时间试图帮助你,而你却忽略了我的回答。:(

于 2012-11-26T22:13:57.327 回答
0

您没有说明任何具体问题,这违反了 StackOverflow 规则。

如果没有您对框架结构的解释,就很难理解您使用每个函数和 mixin 究竟想要实现什么。

我们应该如何提供帮助?

无论如何,您的方法是错误的,原因有两个:

  1. 您正在尝试重新发明轮子。已经有几十个网格框架。
  2. 您正在使用非语义方法。您通过在 HTML 中应用特定于样式的类来设置样式。相反,你的类应该是语义的(即声明块的功能,而不是它们的外观)并且样式应该应用于 CSS 中的这些类。使用 SASS,这很容易。

解决方案:使用Susy。这是一款很棒的软件,它的作者 Eric Meyer 在 StackOverflow 上的反应非常好。

使用 Susy,您的代码可能如下所示:

HTML:

<div id="container">
        <div id="gallery">
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
        </div>
        <div id="promos">
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
        </div>
        <div id="footer">
            <div id="bottom-menu"></div>
            <div id="partners"></div>
            <div id="social-buttons"></div>
        </div>
        <div>
            <div class="col span12"></div>
        </div>
</div>

萨斯:

//////////
// Imports
//////////

@import susy


//////////
// Defining variables
//////////

// Main grid properties
$total-columns  : 12      // Number of columns
$container-style: fluid   // The grid should stretch
$max-width      : 1200px  // But not wider than this

// Proportions between column width and gutter between columns
$column-width   : 85%     
$gutter-width   : 100% - $column-width

// Setting margins around the grid
$grid-padding   : 1em     // This will remain absolute
$container-width: 100%    // If you want relative margins, change this instead


//////////
// Applying containers and columns
//////////

// Setting containers in all immediate children of #container
#container > *
  +container /* ← Actual Susy magic! :D */
  max-width: $max-width

// Setting columns
#gallery > *
  +span-columns(1)
  &:last-child             // The last column should be marked with "omega"
    +span-columns(1 omega) // to compensate browsers' calculation errors

#promos > *
  +span-columns(2)
  &:last-child
    +span-columns(2 omega)

// #footer
#bottom-menu
  +span-columns(6)

#partners
  +span-columns(4)

#social-buttons
  +span-columns(2 omega)

抱歉,我没有测试过这段代码,它可能包含错误,但你仍然可以看到这个想法。

Susy 还可以让您轻松创建响应式网格。他们说 Susy 将成为 Compass 中的默认网格引擎。

UPD:请参阅此问题旁边的特定问题答案!

于 2012-11-26T14:24:46.260 回答
0

不久前,我组装了一个简单的基于 SASS 百分比的网格生成器。您正在寻找的数学在这里:

https://github.com/jordancooperman/simple_grid/blob/master/assets/css/scss/partials/_grid.scss

那里的一些 css 仅用于显示目的,因此如果使用项目中也包含的标记,您将看到您的网格。如果您有任何问题,请告诉我,干杯!

于 2012-12-19T16:02:42.943 回答