需要帮助创建基于百分比的SASS网格系统

时间:2012-11-24 21:21:36

标签: css sass

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

如果我使用下面的默认值,最大宽度将为1200px,左边的内边距为&对于网格允许的最大空间,右边为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();
}


​

3 个答案:

答案 0 :(得分: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/请记住,浏览器将百分比值向上舍入时会出现轻微错误,因此网格定位可能不是像素完美的。顺便说一句,右对齐连续的最后一个块是必要的,以尽量减少这种舍入错误的视觉效果。

老兄,你的代码架构是错误的,你的方法有很多缺点。如果你愿意,我可以给它们命名。

你真的应该给Susy另一次尝试。它是SASS的精彩片段,也是学习SASS技术的重要资源。它的源代码有很好的评论,可以在GitHub上找到。

据您了解,Susy缺少哪些网格框架功能?

我向你保证,Susy 可以做你想做的事。只需解释一项任务,我将尝试利用Susy提出一个优雅的解决方案。

PS我不是想阻止你进行实验。实践变得完美!尝试 是必要的,而且你做得很好。我想告诉你的是,你应该遵循一个很好的榜样并采用良好的做法,这样你就不会在错误的地方结束。

PPS请给我回复我的评价。我花了很多时间来帮助你,而你却把我的答案弄得一团糟。 :(

答案 1 :(得分:0)

您没有说明任何具体问题,这是针对StackOverflow规则的。

如果没有你对框架结构的解释,很难理解你在每个函数和mixin中想要实现的目标。

我们该如何帮助?

无论如何,你的方法有问题有两个原因:

  1. 你正试图重新发明轮子。已有数十个网格框架。
  2. 您使用的是非语义方法。您通过在HTML中应用特定于样式的类来进行样式设计。相反,你的类应该是语义的(即说明块的功能,而不是它们的外观),并且样式应该应用于CSS中的那些类。有了SASS,这很容易。
  3. 解决方案:使用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>
    

    SASS:

    //////////
    // 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:查看此旁边的问题特定答案!

答案 2 :(得分:0)

我把一个简单的基于SASS百分比的网格生成器放在一起。你正在寻找的数学是:

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

其中的某些css仅用于显示目的,以便在使用项目中也包含的标记时您将看到您的网格。如果您有任何疑问,请告诉我,欢呼!