WEBOPIXEL

SASSのMixinでカスタマイズしやすいパーセントベースのグリッドシステム作ってみた

Posted: 2015.05.26 / Category: HTML&CSS / Tag: 

SASS(SCSS)でパーセントベースのシンプルなグリッドMixinを作ってみました。
Mixinにすることでカラム数やマージンの微調整が簡単にできるようになります。

Sponsored Link

分割数だけ指定(マージンなし)

最初はマージン0のタイプです。
12分割を4つのカラムで指定してみます。

HTML

<div class="row">
	<div class="col-3"><p>Grid 3</p></div>
	<div class="col-3"><p>Grid 3</p></div>
	<div class="col-3"><p>Grid 3</p></div>
	<div class="col-3"><p>Grid 3</p></div>
</div>
    

Mixinです。引数は「分割数」「マージン」「クラス名」の順で指定します。

SCSS

@mixin rowSplit($col:12, $class:'row-split') {
    .#{$class}:after {
        content: "";
        display: table;
        clear: both;
    }
    @for $i from 1 through $col
    {
        $width: (100% / ($col/$i));
        .#{$class} .col-#{$i}
        {
            width: $width;
        }
    }
    .#{$class} [class*='col-'] {
        float: left;
    }
}
@include rowSplit();
    

これは決まっているものなのでMixinにする意味はあまりないかもしれません。

分割数・マージンを指定するMixin

次はマージンを設定できるようにしてみましょう。

SCSS

@mixin rows($col:12, $gutter: 3%, $class:'row') {
	$grid: (100% - (($col - 1) * $gutter)) / $col;
	@for $i from 1 through $col
	{
		$num: $col - $i + 1;
		$width: ($grid * $num) + ($gutter * ($num - 1));
		.#{$class} .col-#{$num}
		{
			width: $width;
		}
	}
	.#{$class} [class*='col-'] {
		margin-left: $gutter;
		float: left;
	}
	.#{$class} [class*='col-']:first-child {
		margin-left: 0;
	}
	.#{$class}:after {
		content: "";
		display: table;
		clear: both;
	}
}

@include rows();

Bootstrapとかは間隔を開けるとwidthも狭くなると思いますが、これはピッタリ配置するタイプです。

リストで並べる

リストで並べる例です。3分割してみます。

liで指定したマージンをulで打ち消すタイプです。
なのですが、パーセント指定だとマージン数が大きくなった時左に隙間ができてしまいますね。

HTML

<ul class="blocks-3">
	<li>33%</li>
	<li>33%</li>
	<li>33%</li>
	<li>33%</li>
	<li>33%</li>
	<li>33%</li>
</ul>

SCSS

@mixin blocks($col, $gutter: 3%, $class:'blocks') {
    [class*='#{$class}-'] {
        padding-left: 0;
        list-style: none;
        margin-left: -$gutter;
    }
    [class*='#{$class}-']:after {
        content: "";
        display: table;
        clear: both;
    }
    [class*='#{$class}-'] > li {
        height: auto;
        float: left;
        margin-bottom: 1em;
        margin-left: $gutter;
    }
    [class*='#{$class}-'] > li li {
        float: none;
        margin: 0;
    }

    @for $i from 2 through $col
    {
        $width: (100% / $i )- $gutter;
        .#{$class}-#{$i} > li
        {
            width: $width;
        }
    }
}
@include blocks(6);

CSS3バージョン

ということでCSS3が使用できる条件ならこちら

SCSS

@mixin blocks($col, $gutter: 3%, $class:'blocks') {
	[class*='#{$class}-'] {
		padding-left: 0;
		list-style: none;
	}
	[class*='#{$class}-']:after {
		content: "";
		display: table;
		clear: both;
	}
	[class*='#{$class}-'] > li {
		height: auto;
		float: left;
		margin-bottom: 1em;
		margin-right: $gutter;
	}

	[class*='#{$class}-'] > li li {
		float: none;
		margin: 0;
	}
	@for $i from 1 through $col
	{
		$grid: (100% - (($i - 1) * $gutter)) / $i;
		$num: $col - $i + 1;
		$width: ($grid * $num) + ($gutter * ($num - 1));
		.#{$class}-#{$i} > li
		{
		width: $grid;
		}
	}
}
@include blocks(6, 3%);

[class*='blocks-'] > li:nth-child(3n) {
    margin-right: 0;
}

最後に3番目だけマージンを0にしています。
jQueryとかでやってもいいですね。

割合を決めて分割

12分割じゃなくて割合を決めて分割するタイプです。

SCSS

@mixin rows($gutter: 3%, $class:'row', $col-class:'unit-') {
	$nums: 90, 80, 75, 70, 66, 65, 60, 50, 40, 35, 33, 30, 25, 20, 10;
	@each $num in $nums {
		@if $num == 33 {
			$value: 33.333333333333;
		}
		@else if $num == 66 {
			$value: 66.666666666666;
		}
		@else {
			$value: $num;
		}
		$split: (100/$value)-1;
		$grid: $split * $gutter;
		$width: (100 - $grid) / ($split + 1);

		.#{$class} .#{$col-class}#{$num} {
			width: $width;
		}
	}

	.#{$class} [class*=#{$col-class}] {
		float: left;
		margin-left: $gutter;
	}
	.#{$class} [class*=#{$col-class}]:first-child {
		margin-left: 0;
	}
}

3分割にしたかったので33と66だけ小数点で切り分けてます。