#author("2020-06-16T13:26:04+09:00","default:inoue.ko","inoue.ko") #author("2021-08-05T12:52:36+09:00;2020-06-16T13:26:04+09:00","default:inoue.ko","inoue.ko") *CSS Tips 質問の多い事項について、簡単なサンプルで回答しています。 ~ #contents2_1 ~ #hr ~ ***ウィンドウの拡大縮小に合わせて画像のサイズを変えたい まず基本的なことですが、HTML側の img タグに width を書かないようにします。HTML側にサイズ指定があると、それが優先されてしまいます。 画像単体であれば CSSでサイズを%指定すれば可変サイズになります。 img{ width: 50%; } ただし、画像を配置したボックスが固定サイズだと、そのボックスに対する 比率になるので、変化が生じません。そこで実際には、以下のように全体をフレキシブル(リキッドレイアウト)にする必要があります。 -HTML <div id="container"> <article> <img src="sample.jpg"> : -CSS #container { width: 80%; } article { width: 60%; } article img { width: 50%; } 以上のように書いてあるとすると、ウインドウサイズに対する画像サイズは 0.8 x 0.6 x 0.5 のサイズになります。 &size(12){※実際には 各ボックスの magin、padding も加味する必要があります。}; ~ ~ ***ウィンドウの拡大縮小に合わせて文字サイズを変えたい CSSの font-size で、ビューポート-パーセンテージ:vw(viewport width)という相対単位を使うと解決します。1.0vw でビューポートの幅の1/100です。 font-size: 2vw; /* 画面幅 = 50文字 */ ~ ~ ***YouTubeの埋め込み幅をフレキシブルにするには この問題は、多くの人を悩ませているようで、Webで検索すると様々な方法が解説されていますが、一般に以下のようにするとうまくいくようです。 -HTML:iframe を <div> で囲んで、CLASS名を与えます。 <div class="youtube"> <iframe src="https://www.youtube.com/embed/EexXu1UhLMY" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen> </iframe> </div> -CSS:かなりトリッキーな書き方ですが、以下のパターンが良いようです。 .youtube { position: relative; padding-bottom: 56.25%; /* 16:9の場合*/ height: 0; overflow: hidden; } .youtube iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } ~ ~ ***marginやpaddingをゼロにしているのに余白が残る ブラウザは、各セレクタごとにデフォルトスタイルを持っていて、ユーザーのスタイルシートに特に指定がない場合は、デフォルトの余白や行間情報が適用されます。で、時にはこれが邪魔な存在になるわけです。そこで・・ CSSファイルの先頭に以下のような記述を加えてみて下さい。 * { margin: 0px; padding: 0px; line-height: 100%; } *(アスタリスク)はユニバーサルセレクタといって、すべてのセレクタに適用されます。この記述をすることで、ブラウザがデフォルトで持っているマージンの設定等を、すべてリセットすることができます。 すべてを0リセットした上で、必要な箇所ごとにマージン、パディング、行間を設定する・・という流れで作るのがスムーズです。 ~ ~ ***画像の下に隙間ができる(これを消したい) <img>はインライン要素であるため、位置の扱いは文字と同様になります。文字というのは、デフォルトではベースラインに合わせて置くので親領域の下端にはぴったりと合いません。以下のような解決方法があるのでいずれかをお試しください。 -img の vertical-align を bottom にする ← 大半がこれで解決 img { vertical-align: bottom; } -img のdisplay属性を block にしてサイズを指定 img{ display: block; } ~ ~ ***スタイルシートで定義した背景画像が表示されなくなった HTMLと同一階層にあった CSSファイルを、例えばCSSという名前のフォルダへ移動すると、ファイルの相対的な位置関係が変わるので、パスが通らなくなります。例えば、以下のようなファイルレイアウトの場合は・・ -index.html -css --style.css -images --back.gif この場合は、CSSでは以下のようにURL指定する必要があります。 background-image: url(../images/back.gif); ''../''という表記は「現在の場所からひとつ上の階層へ上がる」ことを意味します。上のような階層構造の場合、style.css の位置からは images が見えないので、一旦上の階層に出てから images>back.gif と辿る・・ということです。 ~ ~ ***要素を中央に置くには インライン要素の場合 text-align: center; で解決しますが、ボックス要素は text-align ではセンタリングできません。一般に以下のような方法があります。 -''margin: auto; を使う方法'' #container{ width: 480px; /* 要素の幅を具体的に指定します */ margin: auto; /* 左右の余白を自動にすることで中央に配置されます */ } -''position を使う方法'' 例えば #container領域を画面中央に配置するには、position: absolute; で、top:50%:, left: 50%;の位置に置きます。その際 marginを用いて、サイズの50%分だけ上と左へ移動(ネガティブマージン)させると中央に配置されます。 //ただし、前提として親要素にheight : 100%; が適用されていないとうまくいきません。 #container{ position: absolute; top: 50%; left: 50%; margin-left: -300px; margin-top: -200px; width: 600px; height: 400px; } 尚、Web は縦方向については「成り行き」で考えることが多いので、縦方向での中央については設定が面倒です。・・というより、縦:中央は考えない方が賢明です。また、これはCSSだけで実現する方法よりも、JavaScript を使ってユーザーのが画面の高さを取得する方がよいでしょう。 [[Google:JavaScript 画面中央配置]] ~ ~ ***ナビ(横並び)を画面中央に配列する方法 -HTML <nav> <ul> <li><a href="#" >home</a></li> <li><a href="#">about me</a></li> <li><a href="#">works</a></li> <li><a href="#">contact</a></li> </ul> </nav> -CSS(margin: auto; で左右の余白を均等にする方法) nav ul{ width: 50%; margin: auto; display: flex; flex-direction: row; } nav ul li{ width: 25%; } nav ul li a { display: block; } --nav ul にdisplay: flex; を定義して幅を制限(上の例では50%に)したうえで、margin: auto; とすることで中央配置になります。 --項目が4つあるので、nav ul li の幅は 1/4 つまり 25% にしています。 -CSS(別解:nav 要素の text-align: center; を使う方法) nav { text-align: center; } nav ul { width: 50%; display: inline-flex; flex-direction: row; } nav ul li { width: 25%; } nav ul li a { display: block; } --nav に text-align: cener; を定義します。 --nav ul を inline-flex として幅を制限(上の例では50%に)することで、nav ブロック内の ul が中央配置になります。 --項目が4つあるので、nav ul li の幅は 1/4 つまり 25% にしています。 ~ ~ ***ナビを画面に固定する方法1 画面の小さなスマートフォンでは、スクロールするとメニュー(ナビ)が見えなくなって不便・・という問題が生じます。そこで利用されるのが position: fixed;です。これを使うとスクロール操作に関わらずメニューをブラウザの画面上の同じ位置に固定させることができます。 nav { position: fixed; top 0px; left 40px; } ~ ~ ***ナビを画面に固定する方法2 [[HTML5 DEMO Site>http://html5-demos.appspot.com/static/css/sticky.html]] &color(red){将来的にはOKですが、現状ではサポートしないブラウザがあります。}; 相対位置指定と固定位置指定を組み合わせたもので、スクロールが指定値に達するまでは相対位置を保って移動し、その後は固定になります。便利です。 nav { position: sticky; top: 0; } ~ ~ ***ナビを画面に固定する方法3(JS) [[→''DEMO'' >https://design.kyusan-u.ac.jp/SampleSite/ScrollFix/]] 単にナビをウインドウに固定するのではなく、スクロールアップの途中でナビをウインドウトップに固定するには・・という応用バージョンです。 以下、DEMOの要点のみ、ソースを記載して説明します。 なお、このサンプルでは[[jQuery]] が必要です。 -HTML <nav id="SiteNavi"> : 途中省略 </nav> スクロール時に固定したい要素に id = "SiteNavi"を定義します。 -CSS header { height: 120px; } #SiteNavi { position: absolute; top: 120px; : 以下詳細略 } #SiteNavi.fixed { position: fixed; top: 0px; } ヘッダーの120px分はスクロールアップで見えなくなりますが、その下にあるSiteNavi は、それが120pxを超えてスクロールしたとき、つまり、ウインドウの上端を越えそうになったところで、上端( top : 0px )に固定になります。 -JavaScript $(function() { $(window).on('scroll', function() { if ($(this).scrollTop() > 120) { $('#SiteNavi').addClass('fixed'); } else { $('#SiteNavi').removeClass('fixed'); } }); }); 120という数字は、スクロールで消える分の header の高さです。 スクロールが120px越えたら、SiteNavi に fixed クラスを付加 それ以外の場合は、SiteNavi から fixed クラスを削除 ~ ~ ***CSSのみでメニューのトグル表示 [[→DEMO>https://koichi-inoue.github.io/SlideMenu/]] CSSの :checked擬似クラスを使うと、チェックの有無ごとに異なるスタイルを設定するかたちでメニューの開閉を行うことができます。 &color(red){本件の説明記事は別ページに移動しました。}; > [[CSS/SlideMenu]] ~ ~ ***マウスホバーで吹き出し [[→DEMO>https://design.kyusan-u.ac.jp/SampleSite/Balloon/]] ターゲットと吹き出し(ツールチップ)を同じボックス内に置いて、ボックスのホバリング時に吹き出しが表示されるようにします。以下は、その要点部分のみ書いたものです。 -HTML <div class="box"> <P>ここにマウスをのせて下さい。</p> <p class="balloon">説明文が表示されます。</p> </div> -CSS .box{ position: relative; width: 240px; padding: 40px; background: silver; } .box .balloon{ position: absolute; top: 140px; left: 0px; width: 240px; padding: 40px; background: red; color: white; display: none; } .box:hover .balloon{ display: block; } 通常は吹き出し部分が非表示(display: none;)になっていて、マウスホバー時に表示(display: block;)されるようにします。位置については、親要素を position: relative; として、そこを基準に 子要素の場所を position: absolute; で指定する・・ということです。 -CSS 別解(transition で演出) .box .balloon{ position: absolute; : visibility: hidden; opacity: 0; transition: .5s; } .box:hover .balloon{ visibility: visible; opacity: 1; } [[CSSアニメーション>CSS/Animation]]の ''transition'' を使うと、ふんわりと出すことができます。その場合は、display ではなく、visibility と opacity を使って、不透明度が変化するように設定します。要点のみ記載したものです。 ~ ~ ***マウスホバーで吹き出し 2 [[→DEMO>https://design.kyusan-u.ac.jp/SampleSite/BalloonCSS/]] ''Balloon.css'' という便利な ''CSSライブラリ'' があります。 これを読み込むだけで、上下左右好きな方向に吹き出し(ツールチップ)を表示することが可能になります。 download > http://kazzkiq.github.io/balloon.css/ 必要なのは、 ''balloon.min.css'' のみです。 -HTMLのHEAD部分:以下の一行を追加(PATHの部分は各自の仕様で) <link rel="stylesheet" href="[PATH]/balloon.min.css"> -HTMLのHEAD部分:以下の一行を追加(path/to/の部分は各自の仕様で) <link rel="stylesheet" href="path/to/balloon.min.css"> -HTMLのBODY部分:以下のように書くだけです。 <ul> <li data-balloon-length="large" data-balloon="任意のテキスト" data-balloon-pos="up">上の例</li> <li data-balloon-length="large" data-balloon="任意のテキスト" data-balloon-pos="left">左の例</li> <li data-balloon-length="large" data-balloon="任意のテキスト" data-balloon-pos="right">右の例</li> <li data-balloon-length="large" data-balloon="任意のテキスト" data-balloon-pos="down">下の例</li> </ul> --data-balloon:吹き出しの中に入るテキスト --data-balloon-length:吹き出しの大きさ small, medium, large, xlarge, fit --data-balloon-pos:吹き出しの位置 up, left, right, down ~ ~ ***マウスホバーでサブメニュー メインメニューのマウスホバー時に、下位のサブメニューが出現する例です。 JavaScript等は使わず、CSSの hover 擬似クラスのみで実現可能です。 [[記事は NavigationDesign のページへ移動しました。>NavigationDesign]] ~ ~ ***画像の部分領域でマウスホバー [[→DEMO>https://design.kyusan-u.ac.jp/SampleSite/MapArea/]] 基本的には、上の事例の応用になりますが、area タグはブロックでもインラインでもない特殊なタグで、CSSのみではホバリング動作はうまくいきません。そこで実際には、以下のようにJavaScriptを使って実装することが多いようです。 -HTML <div id="MAP"> <img src="3x3.gif" usemap="#sample"> <map name="sample"> <area onmouseover="ShowMessage(0)" shape="rect" coords="0,0,99,99" href="#"> <area onmouseover="ShowMessage(1)" shape="rect" coords="100,0,199,99" href="#"> <area onmouseover="ShowMessage(2)" shape="rect" coords="200,0,299,99" href="#"> : 途中略 </map> </div> <div id="MESSAGE"> <h1>TITLE</h1> <p>description</p> </div> 各 area 上にマウスオーバーの際の動作を定義しています。引数は、エリアを特定するための番号です。マウスオーバーの際の関連メッセージは、MESSAGE の中に埋め込まれます。 -JavaScript function ShowMessage(n){ var text = []; //配列を用意して必要数分の説明情報を定義 text[0] = "<h1>00</h1><p>エリア00についての説明</p>"; text[1] = "<h1>01</h1><p>エリア01についての説明</p>"; text[2] = "<h1>02</h1><p>エリア02についての説明</p>"; : 途中略 MESSAGE.innerHTML = text[n]; // 当該番号の情報を埋め込み } 必要な分だけ HTML を定義した上で、渡された引数に応じて、該当するHTML をMESSAGE 部分に適用する・・という発想で記述しています。 尚、ここではシンプルに書くことを優先し、[[DOM>JavaScript/DOM]]は使っていません。 ~ ~ ***フッターをページの一番下に固定したい CASE1 最も簡単なのは、position: fixed; でウインドウの下に固定する方法です。 footer { width: 100%; position: fixed; bottom 0; left 0; } ~ ***フッターをページの一番下に固定したい CASE2 [[→ DEMO >https://design.kyusan-u.ac.jp/SampleSite/SampleSiteH100/]] すべての要素を囲む#containerがあり、その中にfooterが含まれている場合、footerを一番下に固定するには、#containerの高さを100%に、かつ、ページの下に position:absolute; bottom:0; にする…という発想もあります。 ボックスの height は、その親要素の height に依存するので、高さ100%を実現するには、大元の親要素である、html と body の段階から height:100%; が定義されている必要があります。 //http://peterned.home.xs4all.nl/examples/csslayout1.html 要点を書き出すと以下のような感じです。 html,body { height: 100%; } : #container { position: relative; height: auto !important; min-height: 100%; } : footer { position:absolute; bottom:0; } ~ ~ ***リンクの反応エリアを拡大したい リンク動作は<a>タグの中身、つまり文字にしか反応しません。このままだと、例えばメニュー上でリンク文字が3文字であれば3文字分の範囲にしかマウスが反応せず、操作性が悪い・・ということになります。反応エリアを拡大するは、以下のように<a>の領域をブロック領域として扱い、幅や高さを定義します。こうすると、<a>自体がボックス領域になるので、マウスに反応するエリアを大きくすることができます。以下メニュー部分の構成例です。 ul li{ /* ここには幅や高さの情報は書かない */ } ul li a{ display: block; width: 180px; padding: 10px; background-color: white; color: black; } ul li a:hover{ background-color: black; color: white; } ~ ~ ***ギャラリーページにサムネイルを並べるには →[[''DEMO'' >https://design.kyusan-u.ac.jp/SampleSite/SampleSiteA/gallery.html]] DEMOのソースをご覧ください。画像とキャプションをまとめて羅列している部分が見えると思います。また、そのままCSSの方を見ていただくと、最後の3項目、.box, .thumb, .notesが、サムネイルとキャプションに関する記述です。一行に何個入るかは、親要素の幅によります。以下、要点のみ掲載。 -HTML:以下のようにサムネイルブロックを繰り返し記述するだけです。 <div id="gallery"> <div class="box"> <img class="thumb" src="images/monalisa.jpg"> <p class="notes"> La Gioconda (1519)<br> Leonardo da Vinci<br> 30 × 21 inch<br> </p> </div> <div class="box"> <img class="thumb" src="images/xxxxxxx.jpg"> : </div> <div class="box"> <img class="thumb" src="images/xxxxxxxx.jpg"> : </div> : 以下同様に羅列 </div> -CSS:以下のようにサムネイルブロックを左回り込みするだけです。 #gallery{ width: 960px; } .box { float: left; width: 100px; height: 240px; margin-right: 40px; margin-bottom: 40px; } -CSS別解:サムネイルブロックの親要素を display: flex; でも実現できます。 利点は、柔軟な配列が簡単にできることです。→参考:[[CSS/Flexbox]] &size(12){※最近のブラウザは Flexboxに対応していますので、こちらの方がオススメです。}; #gallery{ width: 960px; display: flex; } .box { width: 100px; height: 240px; margin-right: 40px; margin-bottom: 40px; } ~ ~ ***印刷用のCSSについて 画面表示と印刷でスタイルを区別したい場合は・・・ -印刷用のCSSを用意して、その読み込み時に media="print" を指定します。 <link rel="stylesheet" type="text/css" media="print" href="print.css"> -CSSに直接メディアクエリーを書く @media print { header { height: 40px; border-bottom: 1px solid #000; } } -ブラウザでの確認方法 #image(debug_print_css.png,right,40%) 印刷用のCSS は、当然ブラウザの画面(media="screen")には反映しないため、ふつうは ''印刷>プレビュー'' として確認することになります。 しかし、これでは作業効率が悪いので、例えば Chrome には開発コンソールに ''メディアエミュレータ'' が用意されています。以下の手順で印刷時のCSSがブラウザに反映されます。CSSを確認しながら CSS の編集が可能です。 -ページが表示された状態で 右クリック>[ 検証 ] -開発パネル右上の三連ドットボタンから MoreTools > Rendering -右上図のパネルが開くので、 Emulate CSS media > [ print ] ~ ~ ***IEでCSS3を使いたい &color(red){この話は時間の問題で、やがて不要になると思います。}; 現状では、PIE.htcを使うという方法があります。 [[PIE CSS3 decorations for IE>Google:PIE CSS3 decorations for IE]] -DLすると複数のファイルがありますが、必要なのは「PIE.htc」 これを任意のフォルダに置きます。 → 「css/PIE.htc」 -使い方は、CSS3を適応させたい部分で以下のように書くだけです。 #selector { border-radius: 5px; -webkit-border-radius: 5px; -moz-border-radius: 5px; behavior: url(“css/PIE.htc”); } ~ ~