20200225のCSSに関する記事は4件です。

いつから、z-indexがpositionだけのものだと錯覚していた?

タイトルの元ネタになっている『BLEACH』は読んだことありません。

悩ましいz-index問題

CSSを学んだことある人なら一度は通るz-index問題。単純にz-indexの値で重なりが決まるのではなく、親要素との関係によって重なりが変わるので複雑です。ついz-index: 9999はやってしまいます。(一番上なんだな、っていうのが分かりやすいので良いとは思いますが)

これが問題になるのはpositionのプロパティを使ったときが多いですが、position以外にもz-indexが有効になるプロパティがあります。

具体例がこちら↓


See the Pen
z-index
by Nishihara (@Nishihara)
on CodePen.


この記事ではHTMLは以下のようにidの小さい方から書かれている前提になります。

<section class="section section1">
  <div id="block1">z-index: 3</div>
  <div id="block2">z-index: 2</div>
  <div id="block3">z-index: 1</div>
</section>

display: flexの時

display: flexを使った際の子要素も実はz-indexが有効になります。flexだけを使って重ねるというのは、あまりない場面かもしれませんが、ネガティブマージンを使って重ねるとz-indexが効いているのが分かります。

.section1 {
  display: flex;
  justify-content: flex-start;
}

#block1 {
  background-color: rgb(228, 100, 100);
  z-index: 3;
}

#block2 {
  background-color: rgb(100, 228, 100);
  z-index: 2;
  margin-top: 40px;
  margin-left: -80px;
}

#block3 {
  background-color: rgb(100, 100, 228);
  z-index: 1;
  margin-top: 80px;
  margin-left: -80px;
}

display: gridも

flexと同様にdisplay: gridでもz-indexが使えます。そもそもgridでレイアウトを重ねることは少ないと思いますが。。。

.section2 {
  display: grid;
  justify-content: flex-start;
  grid-template:
    "block1 block2 block3" 120px /
    120px 120px 120px;
}

#block4 {
  background-color: rgb(228, 100, 100);
  z-index: 3;
}

#block5 {
  background-color: rgb(100, 228, 100);
  z-index: 2;
  margin-top: 40px;
  margin-left: -80px;
}

#block6 {
  background-color: rgb(100, 100, 228);
  z-index: 1;
  margin-top: 80px;
  margin-left: -160px;
}

組み合わせても有効になる

これらも要素にz-indexが有効であることを知らなくても、それぞれを単体で使う場合にはそんなに問題はありません。問題になってくるのは、positionやこれらを組み合わせた時です。

例えば下記のように、flexで並べて、子要素にposition: absoluteを使って配置し、transform: translateで重ねた場合はどうでしょう?その場合もz-indexの値が効いてきます。

.section3 {
  display: flex;
  position: relative;
  justify-content: flex-start;
}

#block7 {
  background-color: rgb(228, 100, 100);
  z-index: 3;
}

#block8 {
  background-color: rgb(100, 228, 100);
  z-index: 2;
  position: absolute;
  top: 40px;
  left: 40px;
}

#block9 {
  background-color: rgb(100, 100, 228);
  z-index: 1;
  transform: translate(-40px, 80px);
}

この場合は、#block7が一番上にきます。

z-indexパズル

z-indexを指定しない場合は重ね合わせコンテキストのルールに従って、HTMLで後に書かれているものが上になります。では、次のような場合どうでしょう。

.section4 {
  display: flex;
  position: relative;
  justify-content: flex-start;
}

#block10 {
  background-color: rgb(228, 100, 100);
}

#block11 {
  background-color: rgb(100, 228, 100);
  position: relative;
  margin-top: 40px;
  margin-left: -80px;
}

#block12 {
  background-color: rgb(100, 100, 228);
  margin-top: 80px;
  margin-left: -80px;
}

子要素にはz-indexが指定されていません。なのでHTMLで一番最後の要素の#block12が一番上に来そうですが、実はそうではありません

よく見ると、#block11にはposition: relativeが指定されています。そうすると、新たに重ね合わせコンテキストが発生するので#block11が一番上にきます。しかしここに、

#block10 {
  background-color: rgb(228, 100, 100);
  z-index: 1;
}

z-indexを指定すると通常の重ね合わせコンテキストを上書きするように#block10が一番上に来ます。ここまでくるとz-indexパズルですね!

transform?

Firefoxだけ、要素にtransformのプロパティを使った時もz-indexが有効になります。

#block13 {
  background-color: rgb(228, 100, 100);
  transform: translate(0, 0);
  z-index: 3;
}

#block14 {
  background-color: rgb(100, 228, 100);
  transform: translate(40px, -80px);
  z-index: 2;
}

#block15 {
  background-color: rgb(100, 100, 228);
  transform: translate(80px, -160px);
  z-index: 1;
}

では、transform: translate3d(x,y,z)でz方向に奥行きに移動させたらz-indexの位置関係が変わるのでしょうか?

結論から言うと変わりません。transformのz軸方向とz-indexのレイヤーは別ものなので重なりが入れ替わるようなことはありません。

transformを使って重ねるときにはブラウザで差が出てくるので要注意です。

最後に

重ね合わせがうまく行かなかったら、これらz-indexが有効なプロパティも疑ってみてください。それでもダメな場合は重ね合わせコンテキストを考慮してみてください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Sassの基礎の基礎

Sass(サス)って聞いたことあるんです。

聞いたことがあったんだけど、まぁCSSの新たな効率的な書き方でしょ。くらいしか知りませんでした。なので、独学で学んでみることに。

学んでいる途中でいろんな開発者さんのブログとかも参考にして自分なりにまとめてみました。

Sassとは

そもそもSassって何の略だ。って調べてみると、、、

Syntactically = 構文的な
Awesome =  オーサムな
Style Sheet = スタイルシート

まじか。Awesomeとか入れちゃうあたり、自由すぎる。堅っ苦しくない感じ。好き。

Sassの種類

ちなみに、Sassの種類は「SASS」型と「SCSS」型があるみたい。

今回はSCSS型で進めていきます。拡張子も『.css』ではなく、『.scss』となりますので注意。

Sassは入れ子構造

普通のCSS

.qiita {
  width: 1280px;
}

.qiita h1{
  font-size: 20px;
}

入れ子構造のSass

.qiita {
  width: 1280px;

   h1{
     font-size: 20px;
   }
}


このように、クラス名qiitaの中に入れこんで記述できるのです。

具体的なSassの使い方

&でbuttonの反復使用をなくす

  .button {
    color: white;
    opacity: 0.8;
    background-color: lightblue;
    cursor: pointer;

    // ここの"&"で".button"と同じ意味。
    &:hover{
      opacity: 1;
    }

if, while, for 文を使用する


// ===if文===

$number: 10; //変数の定義

p{
  @if number > 5 {
    color: red;
  }@else{
    color: green;
  }
}

// ===for文===

//変数i が 10~12の間
@for $i from 10 through 12 {

  .fs#{$i} { font-size: #{$i}px; }

}

//#{}の中にいれることでconcatenateしなくて良くなる
// 上記だと、.fs10 .fs11 .fs12 というクラスが生成される


// ===while文===

//同じく変数i が 10~12の間

$i: 10;

@while $i <= 12 {

  .fs#{$i} { font-size: #{$i}px; }
  $i: $i + 1;

}


参考: ドットインストール

関数を使用する

// 変数を定義

$widthSize: 900px;

//関数の定義

@function onethirdSize($length){
  @return $length / 3;
}

// 関数を使用

.box-reponsive{
  width: onethirdSize($widthSize);
}



これで.box-responsiveのクラスを持つ要素はそのwidthが900pxの3分の1になりました。使い方次第では、非常に有能な関数です。

参考: https://book.scss.jp/code/c4/05.html

用途別にscssファイルを作成する

main.scss というファイルがあったとして、関数とか変数とか全てを同じファイル内に記述していくとぐちゃぐちゃでAwesomeではないファイルが出来上がってしまいます。それを防ぐために関数用のファイルを作成します。

main.scss
_functions.scss ← 関数用のscssファイルを追加

しかし、追加しただけだと連携されていないので、main.scssに適用できるように、@importします。

main.scss

@import "functions";

Sass の便利な機能

ちょっと覚えておきたい便利な機能を挙げていきます。

変数を使用する

まずSassの最大の特徴が変数を使用できること。例えば、WEBサイト内のテーマ色を変えたい場合。文字にも、ボタンにも、水平線にもテーマ色がついていて、CSSだと全て変更するのが大変!って時ありますよね。

でもSassなら変数を定義しておけば、その変数を変更するだけで一気に全て変えられます。

// 関数theme-colorの定義 
$theme-color: #eee;


// h1で変数を使用する
h1{
  color: $theme-color;
}

//もしtheme-colorが数値、文字列だったら下記のように+とかで記述することも可能。
h1{
  font-size: $theme-color - 2px;
}



こんな感じで記述しておくと、最初の$theme-color変数を変更するだけで全て変更できます。めっちゃ便利。

変数の色ならlighten, darkenを使用しよう

テーマカラーを決めたら、見出しも、文字も、背景も全部まったく同じ色にしたい。とは思わないですよね。やっぱり、ボタンは多少明るくしようか。もしくはhoverしたら、ちょっと暗くしようか。とか思いますよね。

そんな色の明るさ、暗さの調整ができるのがlighten, darkenです。

// 関数theme-colorの定義 
$theme-color: blue;


// 明るさを20%アップさせる

div{
  background-color: lighten($theme-color, 20%);
}

// hover で逆に暗さを70%アップさせる

a{
  color: $theme-color; 
  &:hover{
     color: darken($theme-color,70%);
  }
}

こうやっていちいち色自体を定義しなくても、明るさ、暗さを調整できるのは便利です。
さらに詳しい色関係の関数一覧
https://book.scss.jp/code/c8/07.html

@mixin であらかじめスタイルを定義

次に同じようなスタイルを様々な要素に適用したいんだけど、ちょっとずつサイズとか違うのよね。そしたら、毎回同じものを色んなクラスにコピペしなきゃいけない。そんな時は@mixinが便利です。

あらかじめテンプレート的なスタイルを定義しておくことで、そのスタイルを色んなクラスに転用することができるのです。

例えば、サイト内で使用しているボタンに共通するスタイルを定義しておき、細かい所は個々で調整するとコードの反復を最小限に止めることができますよね。


// ここで共通のスタイルを定義しておく。
@mixin contentStyle { 
   width: 980px;
   margin: 0;
   border: 1px solid black;
}


// borderとかmargin, widthはcontentStyleを使用したまま、、、

//一つ目のboxは背景をblueに。
.first-content-box { 
  background-color: blue;
  @include contentStyle;
} 

//二つ目のboxは背景をorangeに。
.second-content-box { 
  background-color: orange;
  @include contentStyle;
} 


共通のスタイルを定義しておくと、細部だけ個々に記述すれば良いから楽ですね!

@extend でスタイルを継承

先ほどの@mixinと似ているのですが、使いようによってはmixinよりも効率的にコーディングできるので追記しておきます。

まずは継承の方法。


// ここで共通のスタイルをクラスで定義しておく。
.contentStyle { 
   width: 980px;
   margin: 0;
   border: 1px solid black;
}


// borderとかmargin, widthはcontentStyleを使用したまま、、、

//一つ目のboxは背景をblueに。
.first-content-box { 
  background-color: blue;
  @extend .contentStyle;
} 

//二つ目のboxは背景をorangeに。
.second-content-box { 
  background-color: orange;
  @extend .contentStyle;
} 

そうほとんど同じ。違いはscssファイルからcssファイルに変換された時にどうなるか。

// @mixinの場合
// それぞれのクラスに割り振られ、includeされます。

.first-content-box { 
  background-color: blue;
  margin: 0;
  border: 1px solid black;
} 

.second-content-box { 
  background-color: orange;
  margin: 0;
  border: 1px solid black;
} 


// @extendの場合
// 割り振られるのではなく、共通のクラスが作成されます。
// こちらの方が変換後のcssが綺麗で重複がない。

.first-content-box .second-content-box { 
   width: 980px;
   margin: 0;
   border: 1px solid black;
}

.first-content-box { 
  background-color: blue;
} 

.second-content-box { 
  background-color: orange;
} 


参考: https://webdesign-trends.net/entry/4448

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

cssでオンオフtoggleボタン

完成物

これです。

スクリーンショット 2020-02-22 22.29.50.png
スクリーンショット 2020-02-22 22.29.57.png

html

index.html
<!DOCTYPE html>
<html lang ="ja">
<head>
    <link rel="stylesheet" href="../css/toggle.css">
</head>
<body>
    <div class="toggle-switch">
        <input id="toggle" class="toggle-input" type='checkbox' />
        <label for="toggle" class="toggle-label"/>
    </div>
</body>
</html>

css

toggle.css
.toggle-input {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  z-index: 5;
  opacity: 0;
  cursor: pointer;
}

.toggle-label {
  width: 75px;
  height: 42px;
  background: #ccc;
  position: relative;
  display: inline-block;
  border-radius: 46px;
  transition: 0.4s;
  box-sizing: border-box;
}
.toggle-label:after {
  content: "";
  position: absolute;
  width: 42px;
  height: 42px;
  border-radius: 100%;
  left: 0;
  top: 0;
  z-index: 2;
  background: #fff;
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
  transition: 0.4s;
}

.toggle-input:checked + .toggle-label {
  background-color: #4BD865;
}
.toggle-input:checked + .toggle-label:after {
  left: 40px;
}

.toggle-switch {
  position: relative;
  width: 75px;
  height: 42px;
  margin: auto;
}

ちょっと説明

よくあるやり方ですがcheckboxにデザインをあてて実現してます。
上に乗っている丸いボタンはlabelタグです。

checkedの時に背景色を変え、labelタグを動かし、この時の変化をアニメーションにするためにtransitionを付与します。
あとはデザインの話なのでお好きにどうぞで。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初心者によるプログラミング学習ログ 248日目

100日チャレンジの248日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

248日目は、

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む