2011/11/07 22:09

何のひねりもないタイトルですね・・・
すでに多くの方が公開しているなネタですが、最近ちょっとはまったしまったので・・・
cssで対応するのがなかなか難しい「画像を縦横中央に配置する」方法をいくつか考えてみました。

漢(オトコ)はだまってテーブルさ

一番簡単な方法です。tableにすればセル内でvertical-alignが使えます。

DEMO

HTML
<table class="cel">
<tr>
<td><img src="images/001.jpg" /></td>
</tr>
</table>
css
table.cel td {
	padding: 20px;
	background: #d9d9d9;
	width: 150px;
	height: 200px;
	text-align: center;
}

上記デモでは、cssのリセットをしていないので、デフォルトでvertical-align:middleが適用されています。

簡単だけど、これじゃあれなんで・・・

display:table-cell

一部のモダンブラウザしか対応していませんが、display:table-cellというプロパティを使うと比較的簡単に実装できます。
対応ブラウザ:firefox3,chrome,IE8(後方互換モードは除く)

DEMO

HTML
<div class="box">
<img src="images/001.jpg" />
</div>
css
.box {
	padding: 20px;
	background: #d9d9d9;
	width: 150px;
	height: 200px;
	text-align: center;
	vertical-align: middle;
	display:table-cell;
}

cssの行数は少しだけ多くなりますが、HTMLの可読性は高まると思います。まー、一部対応していないブラウザがあるので、これがベストプラクティスではないのですが。
IE6は無視するとして、IE7がクセモノですね。
個人的には、このようないわゆる表現的な部分では、IE7まで切り捨てちゃってもいいんじゃないかと思っています。
プログレッシブ・エンハンスメントってことで。

というか、8月以降これ系のエントリーをしていなかったことに愕然としています(--;)
年末までにあと5本くらいはテクニカルな話題を書きます。はい。

2011/07/14 0:56

この前参加したswapskillsで、yahoo!の中の方が、yahoo!のモバイルページのトランジッションはcss3を使って実装しているというお話を聞いたので、見よう見まねでサンプルを作ってみましたよ。というお話です。 ・・・はい。さっそくdemoを。

DEMO

IEでは動かないと思いますので、chromeとかfirefoxとかでご覧ください。

細かいところまで作り込んでいないので、やはりjquery mobileと比べると若干見劣りしますが、このサンプル実は画像やjava scriptを一切使っておりません。
css3だけでここまでの表現ができるというのは素晴らしいですね。

では、簡単に解説を。

ボタン

ボタン部分は、aタグをブロック化して、背景色をグラデーションで表現し、角丸にしています。
あと、テキストに影もつけました。

     display:block;
     border: #d9d9d9 1px solid;
     background: -moz-linear-gradient(top, #242426, #5b5b60);
     background: -webkit-gradient(linear, center top, center bottom, from(#242426), to(#5b5b60));
     color:#fff;
     text-shadow: 1px 1px 3px #000;
     border-radius: 13px;
     -webkit-border-radius: 13px;
     -moz-border-radius: 13px;

ページ遷移

html側で、

<div id="i1" class="page">

</div>

というブロックが、1ページとなります。
今回は3ページ分用意しましたので、それぞれを横に並ぶようにして表示されていない部分はウインドウの外にくるようにしてあります。

ページ遷移は、transitionでアニメーションの所要時間をしていして、translateXで移動させています。

/* アニメーション */
.page { 
	-webkit-transition: 0.8s;
	-moz-transition: 0.8s;
	-o-transition: 0.8s;
}
 
/* ページ遷移 */
#a1:target .page { 
	-webkit-transform: translateX(-100%);
	-moz-transform: translateX(-100%);
	-o-transform: translateX(-100%);
}
#a2:target .page {
	-webkit-transform: translateX(-200%);
	-moz-transform: translateX(-200%);
	-o-transform: translateX(-200%);
}
#a3:target .page {
	-webkit-transform: translateX(-300%);
	-moz-transform: translateX(-300%);
	-o-transform: translateX(-300%);
}

で、:targetという擬似クラスでハッシュが変わった時に、該当するページが表示されるようにページが動くという仕組みになってます。

jquery mobileと比べると、動きは滑らかじゃないかと思います。
ただ、jquery mobileのように別ページでのページ遷移などはできませんし、UIも自分で作らないといけないのでちょっとめんどくさいですね。

まだまだ、検証が足りませんが、ライブラリに依存しないというのは魅力的かもしれません。

via:Pure CSS Slideshow

2010/12/26 23:31

今月は毎日更新しております。
なんかほとんどCSSしかもCSS2ネタなんですが、そろそろ終にしたいと思っております。(とかいって、書くことなくて復活するかもしれないけど・・・) 最後ということで、レイアウトについてまとめます。

CSSでレイアウトをする方法はいくつかあります。
今日は、代表的な手法をご紹介したいと思います。

floatを使った2カラム(float:left/float:right)

サンプル

HTML
<div class="leftCol">
左だよ<br />
ほげほげ
</div>

<div class="rightCol">
右だよ<br />
ほげほげ
</div>
CSS
.leftCol {
width: 390px;
float: left;
}
.rightCol {
width: 390px;
float: right;
}

大変一般的なレイアウトパターンですね。

floatを使った2カラム(float:left/float:left)

サンプル

HTML
<div class="leftCol">
左だよ<br />
ほげほげ
</div>

<div class="rightCol">
右だよ<br />
ほげほげ
</div>
CSS
.leftCol {
width: 390px;
float: left;
}
.rightCol {
width: 390px;
float: left;
margin-left: 15px;
}

どちらも同じ方向にフロートさせているのでどちらかのブロックでスペースを作らないとブロックがくっついてしまいます。

positionを使ったレイアウト

サンプル

HTML
<div id="container">

<div class="leftCol">
左だよ<br />
ほげほげ
</div>

<div class="rightCol">
右だよ<br />
ほげほげ
</div>

</div>
CSS
#container {
padding: 1em 0;
margin: 0 auto;
text-align: left;
width: 800px;
position: relative;
}
.leftCol {
width: 390px;
height: 500px;
background: #facade;
}
.rightCol {
width: 390px;
position: absolute;
right: 0;
top: 1em;
}

親ブロックでposition: relative;と指定して、positionの基準点にします。小ブロックでposition: absolute;と指定して、位置を指定します。

このパターンの場合、固定したブロックの高さが長すぎると、後続のブロックにかぶってしまいます。

サンプル

主なレイアウトの方法はこんな感じでしょうか?
今回紹介したサンプルを組み合わせると、3カラム以上の複雑なレイアウトも可能になります。

2010/12/25 21:52

ふと、思い当たったことあるので、メモ的にまとめます。

web制作をしていると背景画像の扱いなど少し悩んでしまう場合があります。
たとえば・・・


このようにコンテンツの幅から少しだけはみだした画像。

この画像を表示するためには、本来は画像を含むブロックのwidthを1120px(画像の幅)としないいけません。
そうすると、画面が小さいPCで見ている人にはデフォルトで横のスクロールバーが出てしまいます。
一般的に最近のホームページは最大でも960pxくらいが妥当かなと思っているので、それ以上大きい画像を入れるときには、少し工夫が必要です。

img要素として画像をいれ、マイナスマージンで左右を表示する。

親ブロックではコンテンツ幅を指定して(960px)そのなかにimg要素として画像を入れます。
当然、親ブロックのほうが小さいので表示されませんが、このimg要素にマイナスマージンで左右の不足分を指定してあげると、うまいこと表示されます。

サンプル

css
.negativeMargen {
	margin: 0 -80px 0 -80px;
}

ただし、IE6ではうまくいかない場合がありますし、マイナスマージンを指定した分は、横幅があると認識されてしまいますので、冒頭のスクロールバー問題も解決されません。
これが使えるのは、~40pxくらいのはみ出しかなと思います。

背景画像にして、センタリングする。

今回のような画像であれば、body直下のブロック(横巾を指定していないブロック)の背景画像として画像を入れ、センタリングしておけば、画面の広さに応じてスクロールバーなしで画像が表示されます。 サンプルでは、#containerでページの横幅を指定していますので、それより上の位置に.bgというブロックを作り、その背景画像にしています。

サンプル

HTML
<div class="bg">
<div id="container">
<p>ここにテキストとか画像を入れる</p>
</div>
</div>
css
#container {
margin: 0 auto;
text-align: left;
width: 960px;
}
.bg {
background: url(.http://www.matsuaz.com/4_1/images/img.gif) no-repeat center top;
}

今回紹介したサンプルはまったく異なった使い方ですが、デザインや状況に合わせてうまく使い分けられればと思います。

JustGivingで、「1日1回ブログを書く!」というチャレンジを行っています。 ご共感頂ければ、こちらもご覧ください。 「4_1のチャレンジ 1日1回ブログを書く!

2010/12/24 22:59

メリークリスマス!
でも、僕的には今日は普通の平日なので、数日間サボった制作系ネタでエントリーです。

今更、こんなネタ・・・という気もしますが、最近、自分が昔作ったサイトを大幅にリニューアルする機会があり、当時の自分があまりに初歩的なミスをしていたので、自戒の念も込めてご紹介します。

リストの背景に画像を入れる



よく見かけるリストの表示方法です。

html側では
<ul>
<li>ほげほげ</li>
<li>ほげほげ</li>
</ul>

このように書きます。
で、css側ですが、まず昔の僕が書いたやり方。

ul li {
background:url() no-repeat 0 0;
text-indent:30px;
}

画像が右側にくるので、text-indentで文字をずらしています。

これ、間違いではないのですが、リストの文字が長くなって改行が入ると、サンプル1のようになってしまいます。

そもそもtext-indentプロパティは文章の一行目のインデント幅を調整するものですので、当然複数行になった時は、2行目以降のインデントは効きません。

なので、テキストが長くなる事を想定して、padding-leftでスペースを取るのが良いかと。

ul li {
background:url() no-repeat 0 0;
padding-left:30px;
}

こんな感じです。

このtext-indentですが、margin-leftと一緒に使うと面白い使い方ができます。
このように、二行目にインデントをつけたい場合です。 定義リストを使えば簡単にできるのですが、コーディング上そうできないような場合、

p {
text-indent: -85px;
margin-left: 85px;
}

text-indentは一行目のインデントのみ有効なので、 text-indent: -85px;で、タイトル的な部分の幅を左側(ネガティブ指定なので)に移動します。
次に、margin-left:85pxでpタグ全体を元の位置に戻してあげるというロジックです。
意外と使えるので、覚えておくと便利だと思います。

今日のサンプルはこちらです。
サンプル

2010/12/20 22:47

週が変わりましたが、もう少しcssネタでひっぱります。

今日は、継承の話。
cssとは、Cascading Style Sheetsの略です。
Style Sheets≒デザインを定義するファイル
Cascading≒滝状の段階
かなり意訳ですが滝のように上の階層からのスタイルシートを継承していく意味です。

なので、cssを使ってデザインをする時、この継承という事がとても重要になってきます。

例えば、

<body>
<div id="header">
<p class="text">ほげほげ</p>
</div>
</body>

このようなhtmlがあった場合
一番下層にあるpタグには
body>div#header>pというようにbody以下のスタイルデータが継承されてきます。

このようにシンプルな状態でしたら、それほど困りませんが、複雑なhtml構造をつくっていくと、よく「あれcssが効かない」という場面に遭遇します。

そんな時、知っておくと便利なのがセレクタの固有性を利用した計算です。

セレクタの固有性


要素:1
class:10
id:100
インラインスタイル:1000

として、その数値を計算して、数値が大きいものが優先的に適用されます。

例えば

p {
color:red;
}
p.text {
color:blue;
}
とした場合は 前者:要素(1)
後者:要素(1)+クラス(10)=11なので後者のスタイルが適用されます。

但し、あまり細かく指定しすぎると、今度は表示時間が遅くなってしまうので、自分の親がその親くらいまでが望ましかと思います。

あまり良くないパターン body div#header p.text
たぶん好ましいパターン p.text / #header p.text

このように、継承のルールをしっかり把握しておけば、無駄に!importantを使わずに、きれいなcssを書くことが可能になります。

2010/12/16 22:16

今週はcss縛りでお送りしております。
色々書きたいネタはあるのですが、ちょうど今日ハマってしまったことがあったのでその事について書きたいと思います。
例によって、マニアックなネタですが・・・

htmlにはブロック要素、インライン要素という2つの状態があります。
(状態という表現は違うかもしれませんが)

ブロック要素


内容の前後に改行がはいり、必ずその要素の周辺を矩形で囲むことができる状態。
具体的には、
div,dl,hx,p,talbe,ulなどが初期状態でブロック要素となっています。

インライン要素


ブロック要素の逆の状態です。内容の前後に改行が入らず、その要素の周辺を矩形で囲むことができない状態。
具体的には
span,a,img,emなど

初期状態では、上に挙げたような要素がそれぞれブロック要素、インライン要素となるのですが、cssのプロパティでdisplayというものがあります。
これは、指定した要素の表示形態を変更するプロパティです。
display:inlineとしていすれば、ボックス要素であっても、インライン要素に変更されます。

この状態では、marginやpaddingといった要素周辺のスペースをとるプロパティが上下方向には効きません。

但し、imgに関しては効きます。
この辺の仕様がどうなっているのか、詳しくはわかりませんが・・・

とても初歩的な事で、理解していたつもりですが、ちょっとハマってしまったので、情報をシェアできればと。

JustGivingで、「1日1回ブログを書く!」というチャレンジを行っています。
ご共感頂ければ、こちらもご覧ください。
4_1のチャレンジ 1日1回ブログを書く!

やっと、折り返しです。これまでの頑張りを評価してくださる方がいらっしゃれば、ぼちっとご寄付をお願い致します。

2010/12/15 22:37

web制作の現場でよく使われる手法としてclearfixという技術があります。
これは、フロートを解除するためのテクニックです。

具体的には
.clearfix{
     zoom: 1;/*for IE 5.5-7*/
}
.clearfix:after{/*for modern browser*/ content:"."; display: block; height: 0; clear: both; visibility: hidden; } * html .clearfix{ display: inline-table; /*\*/display: block;/**/ }

こんな感じのスタイルセットから出来ています。(人によって若干異なりますが・・・)

僕も普段から何気に使っていますが、復習の意味も込めてどうゆうロジックで動いているのか考えてみたいと思います。

まず、どうゆう時にclearfixが使われるか?

1.後続ブロックで clear:bothなどフロートの解除ができない場合
2.フロートしているブロックの親ブロックで背景画像の指定があり、フロートが原因で背景が表示されない、また親要素が下まで表示されない場合

このような時にclearfixを使うとうまくいきます。

要因1については、どうしようもないのですが、要因2が起こる理由は
フロートするとその親ブロックではコンテンツがないと解釈されてしまう
という、仕様があるためです。

それをクリアーするために、clearfixが使われているという事なんですね。

では、具体的にソースを見ていきましょう。

.clearfix{
     zoom: 1;/*for IE 5.5-7*/
}

これは、IE5.5~7対策です。
今回の状況では、フロートしているためコンテンツがないと解釈されています。
そこでzoom:1という指定。これによって、IE独自の仕様であるhasLayoutをtrueにすることができます。

hasLayoutとはオブジェクトがレイアウトを持っているかどうかを示すものです。

これによって、zoom:1と指定したブロックではレイアウトがある=コンテンツがあると解釈されます。
実はIE5.5~7には、コンテンツの高さがある場合は自動で高さが伸びるという仕様がありますので、背景画像が下まで表示されるようになるという事です。 zoomの代わりにheight:1pxとかでもいいんですが、実際にはもっと高さがあるのに1pxってのもどうかと思うので、zoomに指定しました。

.clearfix:after{/*for modern browser*/ 
     content:"."; 
     display: block; 
     height: 0; 
     clear: both; 
     visibility: hidden; 
} 

これはいわゆるモダンブラウザ対策です。
モダンブラウザには、:afterという擬似クラスが用意されています。
これを指定したブロックの後ろに本当はないけど、擬似的にコンテンツを表示できます。
それを使って
content:"."; 「.」を表示させ
display: block;ブロック要素に変換して
height: 0; 高さを0にして(高さがあると、下に余白ができてしまいます)
clear: both; ここまででできたブロックでフロートをクリアーして
visibility: hidden; そのブロックを非表示にする
というロジックになっています。

すごい・・・誰が考えたんだろ・・・

最後の

* html .clearfix{ 
     display: inline-table; 
     /*\*/display: block;/**/ 
}

は、MacIE対策です。これはもはやなくてもいいかもしれないですが・・・

今日は、サンプルはありません。(また時間があれば追記します)

2010/12/14 22:32

cssにはline-heightというプロパティがあります。
行間の高さを指定するものです。
このline-heightですが、パラメータは、px,%,数値のみ,normal,inheritが指定できます。慣例的にpxや%指定よりは、数値のみの指定が好ましいと言われています。
理由は、フォントサイズによっては、行間が詰まって見えるからなのですが、その辺のことについてかなり詳しく紹介しているスライドがありましたので、ご紹介します。
(既出のネタですが、とてもいいスライドなので、このブログでも紹介させてもらいます。)
英語なんですが、とても分かりやすく説明してあります。


上記のスライドを元に実際にそれぞれの指定の仕方を試してみました。

前提条件として以下のようにしました。


パーセント指定した場合


サンプル


%指定の場合、子要素のフォントサイズに関わらず親要素(body)のline-heightの数値が適用されます。
つまり、
body font-size:16px×line-height:160%=25.6px
となります。

px指定の場合


サンプル


計算をするまでもなく、全てline-heightは16pxになっています。
論外ですね。

数値のみの指定


サンプル


数値のみの指定の場合、%指定とは逆に親要素(body)に関わらず、子要素のfont-sizeに応じて計算されます。

body=font-size(16px)×line-height(1.6)=25.6px
h1=font-size(20px)×line-height(1.6)=32px
h2=font-size(16px)×line-height(1.6)=25.6px
p=font-size(14px)×line-height(160%)=22.4px

このように、なります。


line-heightの高さはどこのこと?


上記のサンプルを見てみると、計算した数値よりも行間の幅が狭い事がわかります。
計算が間違っている?

スライドの76ページあたりから説明していますが、
font-size 例えば
font-size:16px
line-height:20px
だったとすると
line-height:20px-font-size:16px=4px
この4pxを上下に割り振り文字の周りの高さが2pxになるという計算ができます。

なので、上のサンプルもそれぞれ検証をすればきっとまちがっていない・・・と思います。

・・・むずかしい。


実際にここまで理解してコーディングをする必要はないかもしれませんが、こういったロジックを理解しているとより細かなデザインの再現が可能になるかもしれませんね。

2010/12/13 21:55

今日から数日間は、cssの復習をまとめたいと思っております。

手始めの1日目はboxモデル。
cssでコーディングする上では、忘れてはいけない概念の一つです。テキストや画像の内容領域とborder,padding,marginの周辺領域の関係をしめす概念の事です。
なんのこっちゃな説明ですが、次の図を見ると分かりやすいかと思います。



padding:内容領域のすぐ周りの領域で、cssのbackgroundプロパティの表示領域にもなります。
数値は、正の数値のみ(マイナスは使えない)
ie6,7(後方互換モード)以前では、widthにこの数値も含まれる。

border:padding領域の周りのボーダー領域。
ie6,7(後方互換モード)以前では、widthにこの数値も含まれる。

margin:周辺領域の一番外側の領域。
数値は、負の数値も指定可能。(ただし、ブラウザによっては意図しない動きがある場合があるので要注意。)


縦・横幅の計算方法



上記のようなパターンをコーディングするとき
html側で
<div class="box">
テキスト
</div>

css
.box {
width:270px;
height:20px;
padding: 10px 0 0 30px;
background: url(画像のパス) no-repeat 0 0;
}

このように表記します。
ポイントは、テキストをずらす方法としてpaddingを使用すること。paddingには背景画像が表示されますので、それを考慮して

幅(width)=画像の幅(300px)-左パディング(30px)=270px
縦(height)=画像の高さ(30px)-上パディング(10px)=20px

となります。


marginの相殺


隣り合っているブロックのマージン(padding,borderで隔てられていない場合)は、結合され、その最大値をとる。


marginの相殺は、親子関係のブロックでも適用されるようですね。

paddingは相殺されないので、上記のような例でそれぞれをpaddingで指定した場合は
上下の隙間は
padding-bottom(100px)+padding-top(50px)=150px
となる。


css3の時代になりつつありますが、今回説明したような基本的なことは、css3でもベースとなることです。今のうちにきちんと基礎を見なおしておくことも必要かと思いました。

※コードの表示少し見にくいですよね。またCSSを調整します。しばらく我慢してください。