第5章 現場で使える実践Sassコーディング
5-3 レイアウト・パーツで使える
clearfix を @extend で活用する
$supportIE: true; // IE非対応の場合 false
.clearfix {
@if $supportIE {
*zoom: 1;
}
&:after {
content: "";
display: table;
clear: both;
}
}
.item {
@extend .clearfix;
background: #eee;
.image {
float: left;
height: 100px;
}
.text {
float: left;
}
}
.clearfix, .item {
*zoom: 1;
}
.clearfix:after, .item:after {
content: "";
display: table;
clear: both;
}
.item {
background: #eee;
}
.item .image {
float: left;
height: 100px;
}
.item .text {
float: left;
}
@function を使って px 指定する感覚でフォントサイズを % 指定する
//フォントサイズのリスト
$fontSizeList: 62%, 70%, 77%, 85%, 93%, 100%, 108%, 116%, 123.1%, 131%, 138.5%, 146.5%, 153.9%, 161.6%, 167%, 174%, 182%, 189%, 197%, 205%, 213%, 220%, 227%, 235%, 243%, 250%, 258%, 265%, 272%, 280%, 288%, 295%, 302%;
//指定したフォントサイズに該当する%を返す関数
@function fz($size) {
@if $size < 8 {
$size: 8;
}
@if $size > 40 {
$size: 40;
}
@return nth($fontSizeList, $size - 7);
}
article {
font-size: fz(16);
}
article {
font-size: 123.1%;
}
変数を使って YUI の CSS Fonts を管理する
$fz_10: 77%; $fz_11: 85%; $fz_12: 93%; $fz_13: 100%; $fz_14: 108%; $fz_15: 116%; $fz_16: 123.1%; $fz_17: 131%; $fz_18: 138.5%; $fz_19: 146.5%; $fz_20: 153.9%; $fz_21: 161.6%; $fz_22: 167%; $fz_23: 174%; $fz_24: 182%; $fz_25: 189%; $fz_26: 197%;
#main {
font-size: $fz_15;
}
#main {
font-size: 116%;
}
変数を使って、サイドバーの幅を自動的に計算する
// 全体の幅
$wrap_width: 960px;
// メインエリアの幅
$main_width: 640px;
// サイドバーの幅
$side_width: $wrap_width - $main_width - 20;
#contents {
float: left;
width: $wrap_width;
}
#main {
float: left;
width: $main_width;
}
#side {
float: right;
width: $side_width;
}
#contents {
float: left;
width: 960px;
}
#main {
float: left;
width: 640px;
}
#side {
float: right;
width: 300px;
}
#side {
float: right;
width: 294px;
}
null でカンタンに条件分岐をしてレイアウトをする
$height: false;
.item {
width: 500px;
@if $height {
height: $height;
}
}
.item {
width: 500px;
}
// 高さが必要な場合は値を単位付きで。不要な場合はnull。
$height: null;
.item {
width: 500px;
height: $height;
}
.item {
width: 500px;
}
@mixin itemBox ($width, $height, $margin:null, $padding:null) {
width: $width;
height: $height;
margin: $margin;
padding: $padding;
}
.itemA {
// 不要なプロパティはnull。
@include itemBox(100px, null, 10px, 20px);
}
.itemB {
@include itemBox(null, auto, 20px auto);
}
.itemA {
width: 100px;
margin: 10px;
padding: 20px;
}
.itemB {
height: auto;
margin: 20px auto;
}
$duration: null;
a {
transition: all $duration linear;
}
a {
transition: all linear;
}
calcを使って全体の横幅からボーダーの横幅をカンタンに計算する
.item {
width: calc(100% - 1px * 2);
}
.item {
width: calc(100% - 1px * 2);
}
$border: 1px;
.item {
width: calc(100% - $border * 2);
}
.item {
width: calc(100% - $border * 2);
}
$border: 1px;
.item {
width: calc(100% - #{$border} * 2);
}
.item {
width: calc(100% - 1px * 2);
}
$border: 100px - 1px * 2;
.item {
width: calc(#{$border});
}
.item {
width: calc(98px);
}
$border: "100px - 1px * 2";
.item {
width: calc(#{$border});
}
.item {
width: calc(100px - 1px * 2);
}
@for を使って余白調整用のclassを生成する
$spaceClass: true !default;
$spacePadding: false !default;
$endValue: 10 !default;
@if $spaceClass {
@for $i from 0 through $endValue {
.mt#{$i * 5} {
margin-top: 5px * $i !important;
}
.mb#{$i * 5} {
margin-bottom: 5px * $i !important;
}
@if $spacePadding {
.pt#{$i * 5} {
padding-top: 5px * $i !important;
}
.pb#{$i * 5} {
padding-bottom: 5px * $i !important;
}
}
}
}
.mt0 {
margin-top: 0px !important;
}
.mb0 {
margin-bottom: 0px !important;
}
.mt5 {
margin-top: 5px !important;
}
.mb5 {
margin-bottom: 5px !important;
}
...(略)...
.mt50 {
margin-top: 50px !important;
}
.mb50 {
margin-bottom: 50px !important;
}
リストマーカー用の連番を使ったclass名を作成する
%markBase {
padding-left: 15px;
background-position: 0em .5em;
background-repeat: no-repeat;
}
@for $i from 1 through 3 {
.mark_#{$i} {
@extend %markBase;
background-image: url(../img/mark_#{$i}.png);
}
}
.mark_1, .mark_2, .mark_3 {
padding-left: 15px;
background-position: 0em .5em;
background-repeat: no-repeat;
}
.mark_1 {
background-image: url(../img/mark_1.png);
}
.mark_2 {
background-image: url(../img/mark_2.png);
}
.mark_3 {
background-image: url(../img/mark_3.png);
}
連番を使ったclass名のゼロパディング(0埋め)をする
$tmp: "";
@for $i from 1 through 15 {
@if $i < 10 {
$tmp: "0#{$i}";
} @else {
$tmp: $i;
}
.mark_#{$tmp} {
background-image: url(../img/mark_#{$tmp}.png);
}
}
.mark_01 {
background-image: url(../img/mark_01.png);
}
.mark_02 {
background-image: url(../img/mark_02.png);
}
...(略)...
.mark_14 {
background-image: url(../img/mark_14.png);
}
.mark_15 {
background-image: url(../img/mark_15.png);
}
変数と演算で opacity を使った簡易ロールオーバーを作成する
%opacity {
$opacityValue: .7 !default;
opacity: $opacityValue;
-ms-filter: "alpha(opacity=#{$opacityValue * 100})";
filter: alpha(opacity=#{$opacityValue * 100});
}
p.btn a:hover img {
@extend %opacity;
}
p.btn a:hover img {
opacity: 0.7;
-ms-filter: "alpha(opacity=70)";
filter: alpha(opacity=70);
}
グローバルナビゲーションのCSSスプライトを作成する
<header class="global"> <h1><a href="/">Web制作者のためのSass入門(仮) 公式サポートサイト</a></h1> <p class="description">~ これからのWeb制作の現場で活用するCSSメタ言語 ~</p> <nav> <ul> <li><a href="/">トップ</a></li> <li><a href="/about/">書籍について</a></li> <li><a href="/source/">サンプルソース</a></li> <li><a href="/dl/">ダウンロード</a></li> <li><a href="/profile/">著者プロフィール</a></li> <li><a href="/contact/">お問い合わせ</a></li> </ul> </nav> </header>
/* グローバルナビゲーション */
header.global nav {
margin: 0 0 50px;
ul {
overflow: hidden;
margin: 0;
padding: 0;
li {
list-style: none;
float: left;
width: 160px;
a {
display: block;
height: 50px;
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
background: url(../img/nav.png) no-repeat left top;
&:hover {
background-position: 0 -50px;
}
}
}
}
}
header.global nav {
// スライドさせる距離
$pos-x: -160px;
margin: 0 0 50px;
ul {
overflow: hidden;
margin: 0;
padding: 0;
li {
list-style: none;
float: left;
// 絶対値を返すabs() 関数を使って - を + に
width: abs($pos-x);
a {
display: block;
height: 50px;
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
background: url(../img/nav.png) no-repeat left top;
&:hover {
background-position: 0 -50px;
}
&[href^="/about/"] {
background-position: $pos-x 0;
&:hover {
background-position: $pos-x -50px;
}
}
&[href^="/source/"] {
background-position: $pos-x * 2 0;
&:hover {
background-position: $pos-x * 2 -50px;
}
}
&[href^="/dl/"] {
background-position: $pos-x * 3 0;
&:hover {
background-position: $pos-x * 3 -50px;
}
}
&[href^="/profile/"] {
background-position: $pos-x * 4 0;
&:hover {
background-position: $pos-x * 4 -50px;
}
}
&[href^="/contact/"] {
background-position: $pos-x * 5 0;
&:hover {
background-position: $pos-x * 5 -50px;
}
}
}
}
}
}
header.global nav {
// 各コンテンツのリスト
$navList: about, source, dl, profile, contact;
// スライドさせる距離
$pos-x: -160px;
margin: 0 0 50px;
ul {
overflow: hidden;
margin: 0;
padding: 0;
li {
list-style: none;
float: left;
width: abs($pos-x);
a {
display: block;
height: 50px;
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
background: url(../img/nav.png) no-repeat left top;
&:hover {
background-position: 0 -50px;
}
}
@for $i from 1 through length($navList) {
a[href^="/#{nth($navList, $i)}/"] {
background-position: $i * $pos-x 0;
&:hover {
background-position: $i * $pos-x -50px;
}
}
}
}
}
}
/* グローバルナビゲーション */
header.global nav {
margin: 0 0 50px;
}
header.global nav ul {
overflow: hidden;
margin: 0;
padding: 0;
}
header.global nav ul li {
list-style: none;
float: left;
width: 160px;
}
header.global nav ul li a {
display: block;
height: 50px;
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
background: url(../img/nav.png) no-repeat left top;
}
header.global nav ul li a:hover {
background-position: 0 -50px;
}
header.global nav ul li a[href^="/about/"] {
background-position: -160px 0;
}
header.global nav ul li a[href^="/about/"]:hover {
background-position: -160px -50px;
}
header.global nav ul li a[href^="/source/"] {
background-position: -320px 0;
}
header.global nav ul li a[href^="/source/"]:hover {
background-position: -320px -50px;
}
header.global nav ul li a[href^="/dl/"] {
background-position: -480px 0;
}
header.global nav ul li a[href^="/dl/"]:hover {
background-position: -480px -50px;
}
header.global nav ul li a[href^="/profile/"] {
background-position: -640px 0;
}
header.global nav ul li a[href^="/profile/"]:hover {
background-position: -640px -50px;
}
header.global nav ul li a[href^="/contact/"] {
background-position: -800px 0;
}
header.global nav ul li a[href^="/contact/"]:hover {
background-position: -800px -50px;
}
文字リンクカラーのミックスインを作る
@mixin link-color($normal, $hover) {
color: $normal;
&:hover {
color: $hover;
text-decoration: none;
}
}
a {
@include link-color(#f00, #00f);
}
a {
color: red;
}
a:hover {
color: blue;
text-decoration: none;
}
$normal: #f00;
$hover: #00f;
@mixin link-color($n:$normal, $h:$hover) {
color: $n;
&:hover {
color: $h;
text-decoration: none;
}
}
a {
@include link-color;
}
a {
color: red;
}
a:hover {
color: blue;
text-decoration: none;
}
@mixin link-color2($n) {
color: $n;
&:hover {
color: lighten($n, 30%);
text-decoration: none;
}
}
a {
@include link-color2(#f00);
}
a {
color: red;
}
a:hover {
color: #ff9999;
text-decoration: none;
}
複数の値を@eachでループし、ページによって背景を変更する
$setBG: top, about, company, contact;
@each $i in $setBG {
.body-#{$i} {
background-image: url(../img/bg_#{$i}.png);
}
}
.body-top {
background-image: url(../img/bg_top.png);
}
.body-about {
background-image: url(../img/bg_about.png);
}
.body-company {
background-image: url(../img/bg_company.png);
}
.body-contact {
background-image: url(../img/bg_contact.png);
}
$setBG: top red, about blue, company green, contact yellow;
@each $i in $setBG {
.body-#{nth($i, 1)} {
background-image: url(../img/bg_#{nth($i, 2)}.png);
}
}
.body-top {
background-image: url(../img/bg_red.png);
}
.body-about {
background-image: url(../img/bg_blue.png);
}
.body-company {
background-image: url(../img/bg_green.png);
}
.body-contact {
background-image: url(../img/bg_yellow.png);
}
$setBG: (top red)(about blue)(company green)(contact yellow); $setBG: (top,red)(about,blue)(company,green)(contact,yellow); $setBG: ((top)(red))((about)(blue))((company)(green))((contact)(yellow));
シンプルなグラデーションのミックスインを作る
@mixin linear-gradient($color:#f00, $way:top, $percent:20%) {
background-color: $color;
background-image: -webkit-linear-gradient($way, $color 0%, lighten($color, $percent) 100%);
background-image: -moz-linear-gradient($way, $color 0%, lighten($color, $percent) 100%);
background-image: linear-gradient($way, $color 0%, lighten($color, $percent) 100%);
}
.item {
@include linear-gradient;
}
.item {
background-color: red;
background-image: -webkit-linear-gradient(top, red 0%, #ff6666 100%);
background-image: -moz-linear-gradient(top, red 0%, #ff6666 100%);
background-image: linear-gradient(top, red 0%, #ff6666 100%);
}
.item {
@include linear-gradient(#999, left, 50%);
}
.item {
background-color: #666666;
background-image: -webkit-linear-gradient(left, #666666 0%, #e6e6e6 100%);
background-image: -moz-linear-gradient(left, #666666 0%, #e6e6e6 100%);
background-image: linear-gradient(left, #666666 0%, #e6e6e6 100%);
}
【追記】「to」を使った新しい構文の場合、
グラデーションの開始位置と終了位置を指定しましょう。
@mixin linear-gradient($color:#f00, $start:top, $end:bottom, $percent:20%) {
background-color: $color;
background-image: -webkit-linear-gradient($start, $color 0%, lighten($color, $percent) 100%);
background-image: -moz-linear-gradient($start, $color 0%, lighten($color, $percent) 100%);
background-image: linear-gradient(to $end, $color 0%, lighten($color, $percent) 100%);
}
.item {
@include linear-gradient;
}
.item {
background-color: red;
background-image: -webkit-linear-gradient(top, red 0%, #ff6666 100%);
background-image: -moz-linear-gradient(top, red 0%, #ff6666 100%);
background-image: linear-gradient(to bottom, red 0%, #ff6666 100%);
}


