cssで良く使うテクニック


## 概要

最近はbootstrap等が出てきて、自分でcssを書く機会も減ってきてます。
そこで、改めて基礎を見直す意味でcssを勉強しています。
その中で良く使うテクニックが結構見えてきたので、忘れないように書いておきます。

### ①縦型のメニューを作る

#### 完成予想図

![スクリーンショット 2016-01-16 10.06.13.png](https://qiita-image-store.s3.amazonaws.com/0/23276/e3634ef4-0407-eeca-2e82-b63eee432d67.png "スクリーンショット 2016-01-16 10.06.13.png")

##### コード

```html
 <div class="menu">
   <ul>
     <li><a href="#">トップ</a></li>
     <li><a href="#">会社概要</a></li>
     <li><a href="#">業務内容</a></li>
     <li><a href="#">決算資料</a></li>
     <li><a href="#">採用情報</a></li>
     <li><a href="#">アクセス</a></li>
   </ul>
 </div>
```

```css
 .menu ul {
   margin: 0;
   padding: 0;
   list-style: none;
 }
 
 .menu li a {
   display: block;
   margin: 0;
   padding: 5px;
   text-decoration: none;
   color: #000;
   font-size: 14px;
 }
 
 .menu li a:hover {
   background: #eee;
 }
```

こんな感じのコーディングになります。

コツは、下の３つです。

* `list-style: none` にして黒丸を消す
* aタグの `text-decoration: none` と `color: #000` でリンクっぽさをなくす
* aタグをblock要素にすることで、`padding`で指定したpx数がリストの大きさになるようにする

### ②ヨコ型のメニューを作る

では、今度はこれを横にしてみます

#### 完成予想図

![スクリーンショット 2016-01-16 10.18.08.png](https://qiita-image-store.s3.amazonaws.com/0/23276/7d61f890-f865-4abe-07fb-36bb69627b19.png "スクリーンショット 2016-01-16 10.18.08.png")


#### コード

縦型のメニューが出来てしまえば簡単で、これは各`li`要素を横並びに`float`してあげるだけで良いです。

なので、先ほどの`css`に下記を加えるだけでOKです。

```css
.menu li {
  float: left;
}

.menu ul:after {
  content: "";
  display: block;
  clear: both;
}
```

## ③borderやpaddingによるカラム落ちを防ぐ

横並びを使っている時に良く起きたりすることなんですが、
それぞれ50%ずつの要素を横に並べてて、そこに`border`や`padding`を入れるとカラム落ちしてしまうことがあります。

#### 横並びの例

こんな感じで、test1とtest2というdiv要素を横に並べた場合を想定します

![スクリーンショット 2016-01-16 11.06.42.png](https://qiita-image-store.s3.amazonaws.com/0/23276/3bd97521-9846-eae4-2b23-0b05d6ec7425.png "スクリーンショット 2016-01-16 11.06.42.png")


```html
<div class="container">
  <div class="test1">test1</div>
  <div class="test2">test2</div>
</div>
```

```css
.container:after {
  content: "";
  display: block;
  clear: both;
}


.test1 {
  width: 50%;
  float: left;
}

.test2 {
  width: 50%;
  float: left;
}
```

#### boarderを入れてみる

test1とtest2の両方に下記ボーダーを入れてみました。

```css
  border: 1px solid black;
```

見事にカラム落ちしました。

![スクリーンショット 2016-01-16 11.08.03.png](https://qiita-image-store.s3.amazonaws.com/0/23276/652ebcb4-d404-8bbd-e187-29caa1a18b01.png "スクリーンショット 2016-01-16 11.08.03.png")

#### そこで`box-sizing`

`box-sizing`というのは、要素の高さや幅を、どこの領域までにするかを指定するもので、[ここ](https://developer.mozilla.org/ja/docs/Web/CSS/box-sizing)の
説明が分かりやすかったです。

`box-sizing`に指定出来る値は3種類あります。

値|結果
---|---
content-box(デフォ)|幅と高さはコンテンツ領域のみを含み、パディング・ボーダー・マージン領域は含まない
padding-box|幅と高さに、パディング領域を含む。ボーダー・マージン領域は含まない
border-box|幅と高さに、パディングとボーダー領域を含む。マージン領域は含まない

現在は`box-sizing`を指定してなかったので、デフォルト値が適用され、幅と高さにボーダーが含まれなかったので、`test1`と`test2`の幅は、50% + 2px(左右のボーダー分)となってしまい、カラム落ちが起きてました。

なので、`border-box`を指定してみましょう。

```css
.test1 {
  width: 50%;
  float: left;
  border: 1px solid black;
  
  /* 追加 */
  box-sizing: border-box;
}

.test2 {
  width: 50%;
  float: left;
  border: 1px solid black;
  
  /* 追加 */
  box-sizing: border-box;
}
```

横幅にボーダー領域が含まれる事で、コンテンツ領域＋ボーダー領域 = 50%という計算になるので、カラム落ちせずに、ちゃんと収まるようになったのがわかります。

![スクリーンショット 2016-01-16 11.15.07.png](https://qiita-image-store.s3.amazonaws.com/0/23276/d83b2830-00ca-f84a-4353-a7f09535933c.png "スクリーンショット 2016-01-16 11.15.07.png")

※ paddingを入れたい時も同じです。
なので、使いドコロとしては、paddingだけを使うときは `padding-box`。borderも使うときは`border-box`で良いかと。

※ どの値を指定してもマージンには使えないので注意！！

##### マージンを入れたい場合

その場合、css3では下記のように、マージン分を引いた分を横幅に指定することで解決出来ます。
但し、calcはブラウザ毎にサポート状況が異なるので注意。
(Android4.3がサポート外などあるそうです)

```css
.test1 {
  /** 追加　**/
  width : -webkit-calc(50% - 10px);
  margin-right: 10px;

  float: left;
  border: 1px solid black;
  box-sizing: border-box;

  background-color: #fee;
  color: #faa;

}

.test2 {
  /** 追加　**/
  width: -webkit-calc(50% - 10px);
  margin-left: 10px;

  float: left;
  border: 1px solid black;
  box-sizing: border-box;

  background-color: #ffe;
  color: #e0e03d;
}

```

左右にマージンが入りました。

![スクリーンショット 2016-01-16 11.24.36.png](https://qiita-image-store.s3.amazonaws.com/0/23276/4853f120-4e2c-247a-a028-f8937c909f75.png "スクリーンショット 2016-01-16 11.24.36.png")

## ④ 片方の幅を固定にしてサイドメニューっぽいことを実現する

例えば、左側のボックスの横幅を100px固定にしたい場合を考えてみます。

#### 完成予想図

![スクリーンショット 2016-01-16 14.48.22.png](https://qiita-image-store.s3.amazonaws.com/0/23276/31e9fe2c-2691-e26a-bccc-3eccda3023ef.png "スクリーンショット 2016-01-16 14.48.22.png")

こんな感じで、コツは3つある。

* 固定じゃない方を `float: none` とし、固定した方の後ろに回りこませる
* 固定じゃない方を`width: auto`とすることで領域いっぱいに広げる
	* 但し、このままだと、高さが固定した方を超える部分が下に回り込むような形になってしまう
* 文字の回り込みを防ぐ為に、`margin-left: 100px`でかいけつ

```html
  <div class="container">
    <div class="test1">test1</div>
    <div class="test2">test2 ... 中略　... test2 test2 test2 </div >
  </div>
```

```css
.container:after {
  content: "";
  display: block;
  clear: both;
}

.test1 {
  float: left;
  width: 100px;

  /** 見やすくするための設定 **/
  border: 2px solid black;
  box-sizing: border-box;
  background-color: #fee;
  color: #faa;

}

.test2 {
  float: none;
  width: auto;
  margin-left: 100px;

  /** 見やすくするための設定 **/
  border: 2px solid black;
  box-sizing: border-box;
  background-color: #ffe;
  color: #e0e03d;
}
```