LoginSignup
6
7

More than 5 years have passed since last update.

【Sass】固定と可変どちらもいける簡単グリッドシステム【Mixin】

Last updated at Posted at 2014-12-17

Sassで簡単グリッドシステム

PSDからそのままの幅を入力するだけでグリッドレイアウトが出来る、簡単グリッドシステムを作ってみました。
スペックはこんな感じです。

  • box-sizing: border-box;を除けば、IE7以上から対応。
  • 固定幅レスポンシブどちらでも対応できます。個別に指定が可能なため、要素やデバイスごとに固定にしたり可変にしたり簡単に切り替え出来ます。
  • グリッド結合用のクラスも自動生成。
  • 縦列結合のグリッドには対応してません。が、グリッドをネストすることで同等のことが可能。
  • 高さを揃えるjQueryプラグインfixHeight.js,jquery.heightLine.jsなどと組み合わせることで、実力を発揮。
  • スマホ、タブレット対応も基本的に@includeを上書きするだけで対応可能。
  • Sass 3.2.5で動作確認済み。

サンプルソースコードでは、こちらのゼロパディングfunctionを使用していますが、該当部分を修正すれば無しでも動きます。そのまま使う場合は、mixinより前にこちらのfunctionを入れてください。
http://jsdo.it/kosei27/sass-zeropadding

追記:nounitという単位を削るfunctionも使っていますので、mixinより前にこちらのfunctionも入れてください。
http://jsdo.it/kosei27/hqio

サポートブラウザの分岐はCompassで行っています。$legacy-support-for-ie6: ture;とか。これ自体が古い記述みたいで、Sass ver3.4からは動かないようなので注意。さっき知ったがな( ゚ρ゚ )
http://atendesigngroup.com/blog/new-browser-support-features-compass-1x
というわけで、Sass3.4以降で使用したい方は、該当箇所を変更してください。

Mixin

_mixin.scss
// * Responsive Grid System float & box-sizing (IE7 and above. Without box-sizing)
// * If set $parentWidth Responsive Mode
@mixin grid-type-float($mat, $mal, $width, $col, $firstLineCol, $parentWidth:0) {
    $mat: 20px !default;
    $mal: 20px !default;
    $width: 200px !default;
    $col: 4 !default;
    $firstLineCol: #{$col} !default;
    @include clearfix;
    @if $parentWidth == 0 {
        width: $mal * $col + $width * $col;
        margin-left: 0 - $mal;
    }
    @else {
        $mal: nounit($mal);
        $width: nounit($width);
        $parentWidth:nounit($parentWidth) + $mal;
        width: 100% + percentage($mal / $parentWidth);
        margin-left: 0 - percentage($mal / $parentWidth);
    }
    & > * {
        @if $legacy-support-for-ie6 or $legacy-support-for-ie7 {
        } @else {
            @include box-sizing(border-box);
        }
        float: left;
        @if $parentWidth == 0 {
            width: $width;
            margin-left: $mal;
        } @else {
            width: percentage($width / $parentWidth);
            margin-left: percentage($mal / $parentWidth);
        }
        @for $i from 2 through $col {
            &.gridCol#{zeropadding($i,2)} {
                @if $parentWidth == 0 {
                    width: ($mal * $i - 1) + $width * $i;
                }
                @else {
                    width: percentage($mal / $parentWidth) * ($i - 1) + percentage($width / $parentWidth) * $i;
                }
            }
        }
        @if $col - ($col - $firstLineCol) == 1 {
            &:first-child ~ * {
                margin-top: $mat;
            }
        }
        @if $col - ($col - $firstLineCol) == 2 {
            &:first-child + * ~ * {
                margin-top: $mat;
            }
        }
        @if $col - ($col - $firstLineCol) == 3 {
            &:first-child + * + * ~ * {
                margin-top: $mat;
            }
        }
        @if $col - ($col - $firstLineCol) == 4 {
            &:first-child + * + * + * ~ * {
                margin-top: $mat;
            }
        }
        @if $col - ($col - $firstLineCol) == 5 {
            &:first-child + * + * + * + * ~ * {
                margin-top: $mat;
            }
        }
        @if $col - ($col - $firstLineCol) == 6 {
            &:first-child + * + * + * + * + * ~ * {
                margin-top: $mat;
            }
        }
        @if $col - ($col - $firstLineCol) == 7 {
            &:first-child + * + * + * + * + * + * ~ * {
                margin-top: $mat;
            }
        }
        @if $col - ($col - $firstLineCol) == 8 {
            &:first-child + * + * + * + * + * + * + * ~ * {
                margin-top: $mat;
            }
        }
    }
}

Howto

グリッドさせたい要素の親要素にgrid-type-floatを@includeさせます。

HTML

index.html
<ul class="easyGrid">
<li>テキストテキスト</li>
<li>テキストテキスト</li>
<li>テキストテキスト</li>
<li>テキストテキスト</li>
<li>テキストテキスト</li>
<li>テキストテキスト</li>
</ul>

Fixed Grid

_grid.scss
.easyGrid {
    @include grid-type-float(20px,30px,138px,6,6);
}

Responsive Grid

_grid.scss
.easyGrid {
    @include grid-type-float(20px,30px,138px,6,6,980px);
}

grid-type-floatカッコ内の値ですが、それぞれ先頭から、margin-top,margin-left,width,グリッド数,最初の列のグリッド数,カラム幅となっています。
最後のカラム幅を入力しない場合は固定幅、入力すると可変幅になります。(margin-top以外は全て%に変換)
カラム幅はPSDの値(というか、コンテンツ幅)を入力してください。

Output CSS

_grid.css
.easyGrid { *zoom: 1; width: 102.9703%; margin-left: -2.9703%; }
.easyGrid:before, .easyGrid:after { content: ""; display: table; }
.easyGrid:after { clear: both; }
.easyGrid > * { float: left; width: 13.66337%; margin-left: 2.9703%; }
.easyGrid > *.gridCol02 { width: 30.29703%; }
.easyGrid > *.gridCol03 { width: 46.93069%; }
.easyGrid > *.gridCol04 { width: 63.56436%; }
.easyGrid > *.gridCol05 { width: 80.19802%; }
.easyGrid > *.gridCol06 { width: 96.83168%; }
.easyGrid > *:first-child + * + * + * + * + * ~ * { margin-top: 20px; }

コンパイル後のCSSです。理論的にはネガティブマージンを利用した段組です。
:first-childを使用しているので、IE7対応の場合はコメントアウトの位置に注意してください。

Support Multidevice

_grid.scss
.easyGrid {
    @include grid-type-float(20px,30px,138px,6,6,980px);
    @media screen and (min-width: 667px) and (max-width: 960px) {
        @include grid-type-float(10px,10px,130px,2,2,280px);
    }
}

上記のように上書きするだけです。どちらかというと、margin-top指定のソースコードがPCサイト制作からのスマホサイト制作向きですが、CSS次第でモバイルファースト向けにも変更出来ます。

Combine Grids

HTML

index.html
<ul class="easyGrid">
<li>テキストテキスト</li>
<li class="gridCol02">テキストテキスト</li>
<li class="gridCol03">テキストテキスト</li>
<li class="gridCol02">テキストテキスト</li>
<li class="gridCol04">テキストテキスト</li>
</ul>
_grid.scss
.easyGrid {
    @include grid-type-float(20px,30px,138px,6,3,980px);
}

自動生成されるclassを指定することでくっつきます。
ソースコードは6グリッド分で最初の列のグリッドが3つの場合。

Remarks

説明が適当な箇所もありますが、主な使い方はこんな感じです。
結構前に作ったものですが、最近使い勝手を良くするためにmargin-top指定に改良を加えました。
全称セレクタを指定している箇所がいくつかあるので、厳密に要素を指定したい場合や、サイトのパフォーマンスが気になる方はタグ名やclassを指定されたほうが良いと思います。

6
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
7