Home / Diary / タグ: css

123

目次

  1. CSSによる擬似フレームに潜む落とし穴
  2. JavaScriptでCSSを弄る際のメモをまとめた
  3. JavaScriptでCSSを弄る際のメモ その3 Opera9について
  4. JavaScriptでCSSを弄る際のメモ その2
  5. Operaで動的にグローバルなスタイルを変更する
  6. JavaScriptでCSSを弄る際のメモ

CSSによる擬似フレームに潜む落とし穴

まずった。

Opera for Wii(以下Wipera、勝手に略称付け)をダウンロードして早速自分のホームページにアクセス。おお、予想以上にまともっつーか、数ヶ月前にも似たような感覚を覚えたな、とか思いながらカドゥケウスZ攻略ページを開くと・・・上下にスクロールできない。

理由は分かってる。擬似フレームを利用したせいだ。擬似フレームというのはhtmlとbodyにheight:100%とoverflow:hiddenをつけてから中のボックスにoverflow:autoを与えて、さもframeを使っているかのような視覚効果を生み出すCSSウル技の一つ。

この時bodyの高さ=ウインドウの高さになるのだが、そこに問題がある。

基本的に、ブラウザでページを開いた際に真っ先にフォーカスが移るのはbody(htmlかも)要素になる。そして、キーボードの入力はフォーカスされている要素に送られる。

つまり、どういうことかというと、フォーカスを中の要素に移さない限りキーボードでスクロールに関する一切の操作を受け付けなくなる。

OperaかIEで上記のページを開いて適当なチャプターを開いてからPageDownやPageUpやカーソルキーを押してみよう。恐らく一切スクロールしないはずだ。理由は簡単。フォーカスがあるbodyは既にheight:100%でスクロールしようが無いから。

フォーカスを移すには、クリックするのが一番なわけだが、さすがにそれはインターフェース的によろしくない。

各ブラウザともホイールの操作はマウスが乗っている要素に送られるので、幸いにもマウス派には全く問題無いのだが、閲覧者の中にはキーボード派もいるだろう。となると無視するわけにはいかない。

んで、最初に言ったWipera。Aボタンを押してもフォーカスが移動しない。スクロールするにはわざわざスクロールバーを直接弄らなければいけない。他のブラウザならスクロールバーを弄った時点でフォーカスが移るはずなんだが、それも無し。アンカーで移動してもフォーカスは微動だにせず。

ではどうするか。

・・・・・・どうしよう。

PC用ブラウザならJavaScriptを使うことで、ある程度の補助は可能になる。が、JavaScript無効だと手も足も出ない。

Wiperaはフォーカスを移動させることができない。JavaScriptによる補助もたぶん無理。

となると・・・

ざんねん! わたしのちょうせんは これでおわってしまった!

あー、レイアウト作り直すかー。

補足

Firefoxは通常の要素にもfocusが使えるので、上記ページではFirefoxのみフォーカスが中の要素に合っている。元々focusはフォーム要素に使うものなんだが、Firefoxが正しいかどうかは知らん。このうえなく便利だが。

Info

SBM Comments

use.rna.me
Wiperaって呼称は一般的に・・・どうなんだろうなあ。流行る?
toinami
時々、画面のどこかをクリックしないとスクロールできないのはこれのせいかも?
shisojura
フォーカスを中の要素に移さない限りキーボードでスクロールに関する一切の操作を受け付けなくなる
brazil
Wii/Opera、overflow:autoのDIVなどに初期フォーカスを当てる

2006
1223

Tagscss

JavaScriptでCSSを弄る際のメモをまとめた

JavaScriptによるCSSの操作

まとめた理由
書いた俺自身が、あれどーやんだっけな~、と自分の書いた文書をあちこち探してたことがあったから。

というわけで、サクっとまとめつつ、Opera9の仕様とかにも合わせたり、関数を微妙に改良したりとかいろいろ変更を加えた。

今後CSS関係で何か分かったらこっちに追加するつもり。

Info

2006
0824

Tagscssjavascript

JavaScriptでCSSを弄る際のメモ その3 Opera9について

このエントリは、JavaScriptによるCSSの操作として新たに書き直しました。

-

前々回前回同様いい加減な部分もあるので、鵜呑みにしないように。

Changelog

  • Added support for DOM level 2 Style Sheets and associated parts of DOM level 2 CSS. (Yay!!)

Friday once more! - Opera Desktop Team

DOM2CSSが遂に!

早速インストールして色々試してみたけど、基本はFirefoxと一緒でIEの良いとこ取りになってる。コードの書き換えはほとんど必要なし。ありがとう、おぺらたん

スタイルシートルールの追加と無効

基本的な方法は前々回と一緒。3ブラウザ共通。

スタイルシートルールの取得

基本的な使い方は前々回と一緒。

Operaの場合、返ってくる値の自動補完は無効。つまりIEと一緒で、実際に記述したプロパティの値しか返ってこないっぽい。

div.hoge { background : #668 }

getStyleValue( "div.hoge", "background" );
//IE : #668
//Firefox : rgb(136, 102, 102) none repeat scroll 0% 0%
//Opera : #668

要素に適用されているスタイルを取得する

ここでちょいと前々回の修正。

FirefoxはgetComputedStyleを利用して取得するが、この場合得られる値は何が何でもpx換算されてしまう。

仮にemで指定した場合、ブラウザのフォント設定によって結果が変わってしまう。ブラウザ側で18pxと設定してCSSに1emと記述した場合、1em=1文字の大きさ=設定された18pxとなり、18pxが返ってくる。

ブラウザ側でCtrl++でフォントを大きくした場合でもしっかり対応してくれるので、使いようによっては便利かもしれない。上記の例なら、2回フォントを大きくしてから取得すれば、しっかり50%増しの27pxが返ってくる。試していないが、モニタ解像度を96dpiから72dpiに変えたりすれば、pt指定の値も変化するものと思われる。

なお、OperaはgetComputedStyleでもcurrentStyleでも両方イケるので、記述した値をまんま取得したいならcurrentStyleで取得するべきだ。

getComputedStyleで取得する場合、OperaはFirefoxと違ってブラウザ側のフォントサイズ変更には追従してくれないので注意。300%まで拡大してもデフォルトサイズが返ってくる。

それと、OperaのgetPropertyValueはFirefoxと違い、一括指定したプロパティでもIE同様に取得することができる。

#hoge { margin : 1em }

getActiveStyle( $( "hoge" ), "margin" );
//IE : 1em
//Firefox : null
//Opera(currentStyle) : 1em
//Opera(getPropertyValue) : 16px

軽くまとめる

IE
- セレクタ毎に分割登録される
× 擬似要素(:visited等)が取得できない
× 全称セレクタが削除されて登録される
Firefox
- セレクタ毎に分割登録されない
○ ブラウザに忠実なpxサイズ取得
△ プロパティの自動補完
× 一括指定セレクタで取得できない
Opera
- セレクタ毎に分割登録されない
○ IE/Firefox両方の方法で取得できる

雑感

Operaがいい感じに仕上がってきたので、ボチボチ使い始めてる。

デフォルトでも最低限の機能が揃ってるOperaをライトユーザーに。拡張をブヂュルブヂュル入れてパワーアップ! スワップしてくれるぜー! というコアユーザーはFirefox、という風に住み分けてもいいんじゃないかと思えるようになってきた。

描画周りが速いOperaをwebアプリケーション専用ランチャーにでもしようかなーとか思ってたり。メーラーとして使ってもいいだろうし。

そういやOperaは各種携帯端末だけじゃなく、DSでも使える上にwii標準搭載らしい。実にいいね。

InternetExplorer? dataスキーム未実装でスクリプト処理速度が亀でAcid2が血の海でまともにCSSが使えないブラウザなんて存在しませんよ。ファンタジーやメルヘンじゃあるまいし。

Info

SBM Comments

tsukkee
getComputedStyle
takayuki0510
niyagawa
青汁ふいた
niyagawa
acqua_alta
IEは都市伝説だったのか!

2006
0614

Tagscssjavascript

JavaScriptでCSSを弄る際のメモ その2

このエントリは、JavaScriptによるCSSの操作として新たに書き直しました。

-

前回同様、結構適当に書いてる部分もあるので鵜呑みにしないように。

IEとMozillaでは、スタイルシートの値を取得するには以下の処理を利用すればよい。

function getStyleValue( selector, property ) {
  property = ( property.match( /-/ ) ) ? property.camelize( ) : property;
  var stylesheets = document.styleSheets[0].rules  //IE
                 || document.styleSheets[0].cssRules; //Mozilla
  for( var i = 0, len = stylesheets.length; i < len; i++ ) {
    var css = stylesheets[i];
    if( css.selectorText.toLowerCase( ) == selector.toLowerCase( ) ) {
      if( css.style[ property ] ) return css.style[ property ];
    }
  }
  return null;
}

しかし・・・

全称セレクタ

IEにはほとんどの場面で取得出来なくなる仕様が存在する。

ul * { line-height : 150% }

このようにスタイルシートに記述していた場合

getStyleValue( "ul *", "line-height" );

このようにしてもIEでは取得できない。どうやら内部でアスタリスクが消されるようで、document.styleSheets[0].rulesを参照しても、上記の場合はselectorTextがulのみになってしまう。

じゃあアスタリスクを除いたulだけ指定して取得すればいいじゃん、と思うが

ul { margin : 1em }
ul * { margin : 0.5em }

もし、このように指定されていたら、forループ中に先に指定したulがひっかかってしまい、本来取得したいul要素の子要素全てのmarginは取得できなくなってしまう。

ブラウザの差異を無くすために以下のように記述することがある。

* {
margin : 0;
padding : 0;
font-size : 100%;
font-weight : normal;
font-style : normal;
line-height : 100%;
list-style-type : none;
}

この場合は以下のようにすることで取得することができる。

getStyleValue( "", "line-height" );

ちなみに

ul * span { line-height : 150% }

これを取得する場合は以下のようにする。

getStyleValue( "ul  span", "line-height" );

スペースを二つ空けるのがポイント。一つではダメ。

これらは全てIEのみで、mozillaは関係ない。

グループ化

ul li, span { line-height : 150% }

カンマで区切ってグループ化する場合、IEでは内部で分解される。

getStyleValue( "ul li", "line-height" );
getStyleValue( "span", "line-height" );

上記で両方とも取得できる。が、「ul li, span」では取得できない。

逆にmozillaは内部で分解されないので

getStyleValue( "ul li, span", "line-height" );

と指定する必要がある。ややこしい。

まとめ

JavaScriptでCSSを弄るつもりなら、全称セレクタは使うな。グループ化は避けろ。

そこでプロパティ別整理法をプッシュしてみる。

全てとは言わず、デザイン段階での変更頻度が高い「margin、padding、color、background、border」あたりだけでもやっておくと結構楽。ただし、CSSのサイズが小さい場合は逆効果。

どうでもいいこと

getStyleValueを、同じセレクタで複数スタイルを指定していても(たぶん)大丈夫なように変更。

愚痴

OperaはWidgets実装して浮かれてる暇があったらさっさとDOM2 CSSをサポートしやがれ。ってゆーかサポートしてくださいお願いしますおぺらたん

愚痴 その2

IE7はタブ+RSS実装して浮かれてる暇があったらさっさとdataスキームを実装しやがれ。

Info

SBM Comments

mhrs
IEの罠。「JavaScriptでCSSを弄るつもりなら、全称セレクタは使うな。グループ化は避けろ。」
ll_koba_ll
JavaScriptでCSSを弄る際のメモ その2
ll_koba_ll
JavaScriptでCSSを弄る際のメモ その2
facet
愚痴つき。w
nilab
暴満館 � JavaScriptでCSSを弄る際のメモ その2
hiro_y
JavaScriptでスタイルシートを操作、続編。
brazil
CSS、IE、セレクタ、←Behaviour、←cssQuery
akiyan
意外なところで久しぶりにプロパティ別整理法を言及されました。

2006
0513

Tagscssjavascript

Operaで動的にグローバルなスタイルを変更する

サンプルページ(Opera専用、別ウインドウで開く)

OperaはstyleSheetsオブジェクト等、スタイルシートを直接弄れるプロパティが存在しないので、グローバルなスタイルを変更するのは、既存のcssファイルを追加する以外は不可能だった(ハズ)。

そこで、動的に変更したいスタイルをデータスキームに変換してcssファイルとして追加することで、動的にスタイルを変更させてみた。

欠点は現在の値を読み取れないこと。別途適当なオブジェクトを作成して、追加する度にそのオブジェクトにも反映させるなどして、自分で見るしかない。また、追加しまくるとどんどんメモリを食うと思うので、適当なところで一旦削除する必要があると思われる。

Opera9見てると、そのうちdocument.styleSheetsが追加されそうな雰囲気だが、まあそれまでの一時しのぎってことで。

Info

2006
0418

Tagscssopera

JavaScriptでCSSを弄る際のメモ

このエントリは、JavaScriptによるCSSの操作として新たに書き直しました。

-

俺の探し方が悪いんだろうが、JavaScriptでCSSを弄るリファレンスが中々見当たらなかったので、メモも兼ねて書く。

結構適当に書いてる部分もあるので鵜呑みにしないように。あと、Operaは知らね。

スタイルシートのルールを弄る

div内の全要素をgetElementsByTagNameで拾ってforで回してstyleに・・・ってなことをやるよりも、スタイルシート側から操作できるようになれば楽になる。

function addRule( selector, property ) {
 if( document.styleSheets[0].addRule ) //IE
  document.styleSheets[0].addRule( selector, "{" + property + "}" );
 else if( document.styleSheets[0].insertRule ) //Mozilla
  document.styleSheets[0].insertRule( selector + "{" + property + "}", document.styleSheets[0].cssRules.length );
 else
  return false;
}

addRule及びinsertRuleはルールの先頭に追加していく。ルールは基本的に対象が同じなら後から指定したものが有効になるので、どんどん追加していって構わない。

addRule( "div ul.hoge", "display : none" );

これでdiv以下のhogeクラスが指定されてるリスト要素にdisplay:noneを適用して表示しないようにすることができる。

addRule( "div ul.hoge", "display : block" );

あとから追加したものが有効になるので、こうすれば元に戻る。

スタイルシートのルールを取得する

設定できたなら、取得したい時もある。

function getStyleValue( selector, property ) {
 property = ( property.match( /-/ ) ) ? property.camelize( ) : property;
 var stylesheets = document.styleSheets[0].rules        //IE
  || document.styleSheets[0].cssRules;  //Mozilla
 for( var i = 0, len = stylesheets.length; i < len; i++ ) {
  var css = stylesheets[i];
  if( css.selectorText.toLowerCase( ) == selector.toLowerCase( ) )
   return css.style[ property ];
 }
}

こうすることで、現在適用されているルールの値を直接取得することができる。

IEの場合、直接指定されたもののみ取得できるが、Mozillaの場合は、指定していないものはデフォルトの値が入って返ってくる

getStyleValue( "div.hoge", "background" )

IE : #668
Mozilla : rgb(136, 102, 102) none repeat scroll 0% 0%

MozillaはRGBの値が自動的に変換されるのにも気を付ける。

camelizeはハイフン+小文字アルファベットを大文字アルファベットに直す関数。deCamelizeはその逆。

String.prototype.camelize = function( ) {
 return this.replace( /-([a-z])/g,
  function( $0, $1 ) { return $1.toUpperCase( ) } );
}
String.prototype.deCamelize = function( ) {
 return this.replace( /[A-Z]/g,
  function( $0 ) { return "-" + $0.toLowerCase( ) } );
}

こげな感じに宣言しておく。

どうでもいいが、camelizeの逆の動作はdeCamelizeでいいんだろうか? 英語っつーかそこらへんの命名規則に全然詳しくないからわからん。

スタイルシートを無効にする

document.styleSheets[0].disabled = true

これだけ。インライン指定したものは有効なままなので注意。

要素に適用されているスタイルを取得する

div#hoge { margin-top : 10px }

このようにスタイルシートに記述して、該当要素を取得してstyle.marginTopの値を見ても中身は空である。インラインレベル、つまり今現在適用されているスタイルを取得したい場合は以下のようにする。

function getActiveStyle( element, property, pseudo ) {
 if( element.currentStyle ) {           //IE
  property = ( property.match( /-/ ) ) ? property.camelize( ) : property;
  return element.currentStyle[ property.camelize( ) ];
 }
 else if( document.defaultView.getComputedStyle ) { //Mozilla
  property = ( property.match( /-/ ) == null ) ? property.deCamelize( ) : property;
  return document.defaultView.getComputedStyle( element, pseudo ).getPropertyValue( property );
 }
 return "";
}

getActiveStyle( $( "hoge" ), "marginTop" );
getActiveStyle( $( "hoge" ), "margin-top" );
getActiveStyle( $( "hoge" ), "margin-top", ":first-line" );

こんな感じで使う。

getComputedStyleについて

getComputedStyleの第二引数は擬似要素・セレクタを取得したいときに使う。:first-lineとか:visitedとか。

IEの場合は擬似要素・セレクタの取得が不可能っぽい。currentStyle周辺を掘ってみてもそれっぽいものは見当たらなかった。

getPropertyValueについて

div { margin : 20px }

と指定してgetPropertyValueからmarginで取得しても空の文字列が返ってくる。どうやら一括指定のプロパティは指定できないようになっているらしい。

margin :
marginTop : 20px
marginRight : 20px
marginBottom : 20px
marginLeft : 20px

この場合だとこのようになってしまっているので、1方向ずつ取得しなければならない。IEのcurrentStyleならmargin指定でも問題なし。

続く

Info

SBM Comments

tsukkee
JavascriptからCSSを弄るための関数をいくつか
webmarksjp
javascript
owaranai_dobby
JSからCSSをいじる時(特にClass)
toby_net
スタイルシートをJavaScriptでいじる
hisasann
addRule、insertRule
toby
mackato
getElementsByTagNameで拾ってforで回してstyleに・・・ってなことをやるよりも、スタイルシート側から操作できるようになれば楽になる
fmreal
俺の探し方が悪いんだろうが、JavaScriptでCSSを弄るリファレンスが中々見当たらなかったので、メモも兼ねて書く。 結構適当に書いてる部分もあるので鵜呑みにしないように。あと、Operaは
shokai
JavaScriptでCSSにaddRule insertRule など
wozozo
スタイルの追加・取得・無効化などの方法。
lesamoureuses
CSSから取得して、CSSを変更
yuki_2021
なるほど
hakobe
そのうちjavascriptっ子になったらよもう
sakishuh
スタイルをjsで弄る
ono_matope
丁度今必要だった!
masui
JavaScriptでスタイルシートを操作する
zetamatta
&lt;div&gt;とか&lt;span&gt;の class を変更するのではなく、「CSSを」追加・参照するやり方
mhrs
「まとめ」が http://bmky.net/text/note/javascript-css.html にある。
koyhoge
document.styleSheets を js でほげる。
sousk
DOM2 CSS, よくまとまっている
ll_koba_ll
JavaScriptでCSSを弄る際のメモ
hakobe932
nilab
暴満館 >> JavaScriptでCSSを弄る際のメモ
yuki_neko_nyan
をいじるメモ
shokai
zyun1109
JavaScriptでCSSを弄るつもりなら、全称セレクタは使うな。グループ化は避けろ。
vine_hate
[javascript]
wakaspec
[CSS]
hiro_y
JavaScriptでスタイルシートを操作。
fukken
JavaScriptからCSSをいじる&スタイルを取得する。//addRule/insertRuleなんてあるのか、直でCSSいじってた…
saladdays
JSでCSSを制御。Ajax時代の今、アツい…かも。
kkobayashi
う、document.styleSheets なんてあるのか。その辺まじめに勉強したいな
brazil
CSS、操作、クロスブラウザ、addRule/cssRules、わかりやすい
ka2u
getComputedStyleってインラインでないときにつかうんじゃなかったけ。おれの勘違いかな

2006
0314

Tagscssjavascript

暴満館

最新のエントリ
注目のエントリ(はてな)
ゲーム攻略

暴満館 ~The House of Full Violence~
Powered by WordPress.
About | Contact | 新着のエントリ情報 RSS

ページ内の見出し一覧
CSSによる擬似フレームに潜む落とし穴
JavaScriptでCSSを弄る際のメモをまとめた
JavaScriptでCSSを弄る際のメモ その3 Opera9について
JavaScriptでCSSを弄る際のメモ その2
Operaで動的にグローバルなスタイルを変更する
JavaScriptでCSSを弄る際のメモ