#卒業する前に。
便利故に何でもかんでもBootstrapを使えばいいみたいな風潮になってきている(私の中で)のでBootstrapを使わずにスタイルを組み立ててみようと思い、記録用に記事にします。
▪投稿者のスペック
デザイナーとして、画像制作・編集を担当する傍ら、メインコーダーのサブとしてコーディングをサポートしています。
JavaScript(jQuery)とSASSは現在勉強中。5割程度しか使えていないと思います。
実務経験は2年。今回の記事に間違いが混じっていることがあるかと思います。
その時はご指摘頂きますと、とても嬉しく思います。
##グリッドシステムの仕組みを理解する
Bootstrapのグリッドシステムはwidth100%を12分したもの
width:50%を取りたい場合、12の半分で6 '.col-md-6
'というクラス名でしたね。
これを噛み砕くとこんな計算式になります。
100% ÷ (12 ÷ 6) = 50%
→ 100% × 6 ÷ 12 = 50%
CSSに表すと以下のようになります。
.col-6{
width: calc(100% * 6 / 12);
}
SASS(SCSS)でイクルード出来るように、ミックスインを作りましょう。
@mixin col($nam) {
width: (100% * $nam / 12);
}
これを1〜12の各クラスのPC用とスマホ用に量産します。
指定数の量産は'@for
'文を使います。
'@for
'文ではクラス名の指定に変数から引用できます。
その際、呼び出す変数は、'#{$}'
で囲ってあげます。
@mixin col($nam) {
width: (100% * $nam / 12);
}
@for $nam from 1 through 12{
.col-pc-#{$nam}{
@include col($nam);
}
}
@media screen and (max-width: 724px){
@for $nam from 1 through 12{
.col-sp-#{$nam}{
@include col($nam);
}
}
}
.l-row{
display: flex;
flex-wrap: wrap;
}
colクラスだけでは、一列に整列してくれないので、親ブロックにはdisplay:flex
をかけてます。スマホで改行させたいときのために'flex-wrap'
も忘れずに。
基本はこのカタチで'padding
','margin
'有り無しに合わせてカスタマイズしていきます。
'padding
'有りの場合、'@mixin col
'の中身を書き換えてあげましょう。
##padding有りの場合
@mixin col($nam,$col-pd) {
width: 100% * $nam / 12;
padding:0 $col-pd;
box-sizing: border-box;
}
box-sizing
を追加して、paddingとborderも合わせたwidthを取得するように設定します。
##marginもpaddingも有り
$col-mg: 10px;
$col-pd: 20px;
@mixin col($nam,$col-mg,$col-pd) {
width: calc(100% * #{$nam} / 12 - #{$col-mg}*2);
margin:0 $col-mg;
padding:0 $col-pd;
box-sizing: border-box;
background: #333;
}
@for $nam from 1 through 12{
.col-pc-#{$nam}{
@include col($nam,$col-mg,$col-pd);
}
}
@media screen and (max-width: 724px){
@for $nam from 1 through 12{
.col-sp-#{$nam}{
@include col($nam,$col-mg,$col-pd);
}
}
}
.l-row{
display: flex;
flex-wrap: wrap;
}
SASSでは%とpxの計算は合わせて出来ないため'clac()'で囲ってあげないといけません。
× width:(100% * $nam / 12) - $col-mg*2;
//この文ではエラーが発生します。
'clac()
' と'@mixin
'を併用する場合、変数は'@for
'と同様に'#{$}
'の中に入れてあげると読み込んでくれます。
大まかにご紹介しましたが、基本のグリッドスタイルについて以上です。
以下より、関数をおりまぜて、扱いやすいスタイルに改良していきます。
##配列・読み込み用関数を用意する
$col:( //grid
mg-pc : (0,10px),
mg-sp : (0,10px),
pd-pc : (0,20px),
pd-sp : (0,20px)
);
// @debug map-get($col,mg-pc);
@function gMap($name,$prf,$scr){
$i : map-get($col, $prf);
$i : nth($i,$scr);
@return $i;
}
//@debug gMap($col,mg,2) //...10px
$col
という連想配列にmargin
とpadding
を設置し直します。
この値を読み込む用の関数 gMap()
を作ります。
$name
配列の$prf
の要素が持つ、$scr
番目の値を返すという関数です。
##関数を利用する
@function col-calc($num,$name){
$margin : gMap($col,#{$name},2);
$i: calc(100% * #{$num} / 12 - #{$margin} * 2);
@return $i;
}
.pc-col-style{
margin: gMap($col,mg-pc,1) gMap($col,mg-pc,2);
padding: gMap($col,pd-sp,1) gMap($col,pd-sp,2);
box-sizing: border-box;
}
box-sizing: border-box;
}
@mixin col($num,$name) {
width: col-calc(#{$num},#{$name});
}
@for $num from 1 through 12{
.l-pc-#{$num}{
@include col($num,mg-pc);
@extend .pc-col-style;
}
}
@media screen and (max-width: 724px){
.sp-col-style{
margin: gMap($col,mg-sp,1) gMap($col,mg-sp,2);
padding: gMap($col,pd-sp,1) gMap($col,pd-sp,2);
box-sizing: border-box;
}
@for $num from 1 through 12{
.l-sp-#{$num}{
@include col($num,mg-sp);
@extend .sp-col-style;
}
}
}
col-calc()
関数は上述の
calc(100% * #{$nam} / 12 - #{$col-mg}*2);
と同じ処理を行います。
各グリッドのmarginとpaddingを一つの配列で管理するスタイルに変更したので関数で扱いやすいように書き換えてあげました。
@extend .col-style
で同じスタイルはまとめてコンパイルしてあげます。
###containerを追加する
.l-container{
padding:{
top: 75px;
right: 6%;
bottom: 80px;
left: 6%;
}
<div class="l-container">
<div class="l-row">
<div class="l-pc-3">test</div>
<div class="l-pc-3">test</div>
<div class="l-pc-3">test</div>
<div class="l-pc-3">test</div>
</div>
</div>
.container
で全体のレイアウトを調整します。
上記のようなレイアウトが完成します。
###両端を揃える
$col:(//grid
mg-pc : (0,10px),
mg-sp : (0,0px),
pd-pc : (0,20px),
pd-sp : (0,20px),
row-pc: (0,-10px) //←ココを追加
);
@function gMap-col($prf){
$i : map-get($col,$prf);
$str1 : nth($i,1);
$str2 : nth($i,2);
@return $str1 $str2;
}
//@debug gMap-col(row-pc);
.l-row{
display: flex;
flex-wrap: wrap;
margin: gMap-col(row-pc); //←ココを追加
}
各col
クラスにおける左右marginの影響で余分な空白がうまれるので、
.row
からネガティブマージンで両端を調整します。
###inner rowを整える
以下のソースコードのようにグリッドの中にグリッドを入れたい時があります。
<div class="l-pc-12">
<div class="l-row">
<div class="l-pc-6"></div>
<div class="l-pc-6"></div>
</div>
</div>
その場合rowのmargiが邪魔をしてwidthに影響を及ぼします。
対処としてl-row内のmarginを調整します。
.l-row{
display: flex;
flex-wrap: wrap;
@include media(MED(f3)){
// margin: gMap-col(row-pc);
};
.l-row{
margin: gMap-col(row-pc);
}
}
以下、最終コード
/*code / fuction*/
$setMedia:(//media query
f0 : 1170px,
f1 : 960px,
f2 : 720px,
f3 : 540px
);
@function MED($num) {
$i : map-get($setMedia, $num);
@return $i;
}
$col:(//grid
mg-pc : (0,12.5px),
mg-sp : (0,0px),
pd-pc : (0,20px),
pd-sp : (0,20px),
row-pc: (0,-12.5px)
);
// @debug map-get($col,mg);
@function gMap($name,$prf,$scr){
$i : map-get($name, $prf);
$i : nth($i,$scr);
@return $i;
}
@function gMap-col($prf){
$i : map-get($col,$prf);
$str1 : nth($i,1);
$str2 : nth($i,2);
@return $str1 $str2;
}
// @debug gMap-col(row-pc);
//@debug gMap($col,mg,2) //...10px
@function col-calc($num,$name){
$margin : gMap($col,#{$name},2);
$i: calc(100% * #{$num} / 12 - #{$margin} * 2);
@return $i;
}
/* layout
========================================================================== */
@mixin media($width){
@media screen and (max-width: $width){//$width以上の場合適応
@content;//@include media(MED($num)){style}
}
}
//<=========== 以下grid_system ===========>
.pc-col-style{
margin: gMap-col(mg-pc);
padding: gMap-col(pd-pc);
box-sizing: border-box;
}
@mixin col($num,$name) {
width: col-calc(#{$num},#{$name});
}
@for $num from 1 through 12{
.l-pc-#{$num}{
@include col($num,mg-pc);
@extend .pc-col-style;
}
}
@media screen and (max-width: MED(f1)){//Tabletスタイル
.tb-col-style{
margin: gMap-col(mg-sp);
padding: gMap-col(pd-sp);
box-sizing: border-box;
}
@for $num from 1 through 12{
.l-tb-#{$num}{
@include col($num,mg-sp);
@extend .tb-col-style;
}
}
}
@media screen and (max-width: MED(f3)){//SPスタイル
.sp-col-style{
margin: gMap-col(mg-sp);
padding: gMap-col(pd-sp);
box-sizing: border-box;
}
@for $num from 1 through 12{
.l-sp-#{$num}{
@include col($num,mg-sp);
@extend .sp-col-style;
}
}
}
.l-row{
display: flex;
flex-wrap: wrap;
@include media(MED(f3)){
// margin: gMap-col(row-pc);
};
.l-row{
margin: gMap-col(row-pc);
}
}
.l-container{
padding:{
top: 75px;
right: 6%;
bottom: 80px;
left: 6%;
}
margin: auto;
@include media(MED(f3)){
}
}
//<=========== grid_system end ===========>
#おわりに
###お世話になった記事
-
CSS Flexbox チートシート #Webクリエイターボックス さん
-
CSS3 Media Queries を使って、Webサイトをスマートフォンに対応させるときの注意書き#Web Design Recipes さん