CSSでアニメーションするにはtransitionもありますが今回は animationを使う方法です
このページでは手抜きのため ベンダープレフィックスは-webkitだけ書いてますが必要に応じて-mozなどをつけてください

animationの使いかた

/* キーフレームを作成 */ @-webkit-keyframes fadein { 0%{ opacity:0; } 75%{ opacity:0.5; } 100% { opacity:1; } } /* キーフレームをanimationプロパティで指定 */ div#in{ -webkit-animation: fadein 3s linear 0s 1; }
key-framesは0%や100%などの%ごとにスタイルを指定します
0%が最初で100%最後のフレームです
0%から100%の間で途中経過を指定できます
50%ならちょうど真ん中の時のスタイルです

上の例だとopacityが0から1に変化します
その途中で75%のときにopactyが0.5と指定されています
0%から75%でopacityが0から0.5になって75%から100%でopacityが0.5から1になるので最初の75%までは変化は遅くて 75%以降は早く変化します

animationはkeyframesの名前, 0%から100%の間にかかる時間, 変化の仕方, ディレイ, ループ回数, 逆再生するか をまとめて設定します

フェードイン


CSS
div#in{ display: none; background: green; width: 200px; height: 200px; -webkit-animation: fadein 3s linear 0s 1; } @-webkit-keyframes fadein { 0%{ opacity:0; } 100% { opacity:1; } }
HTML
<input type="button" onclick="document.querySelector('#in').style.display='block'" value="fadein [green]"> <div id="in"></div>

ボタンを押すとdisplayがblockになってアニメーションが始まります
始まるまではdisplayがnoneで 始まるとdisplayがblockですがopacityが0なので表示されません
100%になってからはdiv#inに指定したスタイルになるのでそのまま表示され続けます

基本的にdisplay要素はアニメーションできないのでフェードイン・フェードアウトで要素を完全に消してしまうことが難しいです
ですが フェードインの場合はdisplay部分をアニメーションに含めずにdisplayをblockにしたらアニメーションが始まるということを利用してdisplay:none;を使ったアニメーションにできます

フェードアウト

CSSだけでopacityを0にアニメーションした後displayをnoneにするというのはできないです
JavaScriptでanimationやtransition後のイベントを監視して次のアニメーションが起きるようにスタイルやクラスを書き換えることになります

なので CSSでアニメーションするためにはdisplay:none;は使わずにheight:0;を使います
高さ0なので表示はされませんが幅はあるのでinline-blockで横に並べているときなどはdisplay:none;とは異なる見た目になってしまいます
完全にdisplay:none;と同じようにしたいときはwidth:0;もheight:0;と同時に指定しないといけません
paddingやborderを設定している場合はこれらも0にしないとダメです

CSS
div#out { background: blue; width: 200px; height: 0px; -webkit-animation: fadeout 3s linear 0s 1; } @-webkit-keyframes fadeout { 0% { opacity :1; height:200px; } 95%{ height:200px; } 100% { opacity:0; } }
HTML
<div id="out"></div>
100%じゃなくて95%にheight:200px;を設定しているのは最後の5%でheightを200pxから0pxへアニメーションさせるためです
こうすることで急に0にした場合に起きる 下の要素の瞬間移動が起きずになめらかになります

また div#outはheightが0なので0%と100%(今回は95%)でheight:200pxは必須です

フェードイン/アウト

フェードインとフェードアウトをinputボタンで切り替えます

CSS
div#fade{ background: red; width: 200px; } div#fade.in { height: 200px; -webkit-animation: fadein2 2s linear 0s 1; } div#fade.out{ height:0px; -webkit-animation: fadeout 2s linear 0s 1; } @-webkit-keyframes fadeout { 0% { opacity :1; height:200px; } 95%{ height:200px; } 100% { opacity:0; } } @-webkit-keyframes fadein2 { 0%{ opacity:0; height:0px; } 5% { height:200px; } 100% { opacity:1; } }
HTML
<input type="button" onclick="document.querySelector('#fade').className=document.querySelector('#fade').className=='in'?'out':'in'" value="switch fade [red]"> <div id="fade" class="in"></div>

フェードアウトは一緒です
フェードインをdisplay使わずheightを使うようしました
animationを切り替えると再度アニメーションをしてくれます

サンプル

ベンダープレフィックスを-webkitしかつけてないのでChromeなどでしか動きません