buttonタグ押下時の枠線を消す
Vue.jsのScrollBehaviorがCSSのせいで動かなかった時のこと
Vue.jsでScrollBehaviorが動かなかった時のメモ。
以下,Vue Routerの設定ファイルに記したscrollBehaviorメソッド
scrollBehavior(to,from,savedPosition){return{x:0,y:0}},
ページ遷移と同時にページの一番上まで戻ることを期待していたのですが、
時々うまく動作せず、ページの一番上では無い、ページの途中の変なところに移動してしまうことがありました。
Webページを限界以上にスクロールして、空白の部分が見えてしまうの(バウンススクロール)が嫌で
bodyタグに対して、ページの高さの中でのみスクロールが効くようにCSSで設定をかけていたのですが、
これが原因のようでした。
解決策
bodyタグではなく、htmlタグに対してCSSを適用するように修正すると、ScrollBehaviorが正しく動作するようになりました。
body{overflow-x:scroll;overscroll-behavior-y:none;overscroll-behavior-x:none;}
↓
html{overflow-x:scroll;overscroll-behavior-y:none;overscroll-behavior-x:none;}
原因
原因はbodyタグにかかる「overflow-x」でした。
なので、CSSの適用先をbodyタグではなくhtmlタグにするか、
bodyタグの「overflow-x」をコメントアウトすることで、scrollBehaviorを正常に動作させることもできました。(この場合バウンススクロールは制御できない)
初心者によるプログラミング学習ログ 216日目
100日チャレンジの216日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
216日目は
おはようございます
— ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) January 20, 2020
216日目
架空のwebサイトコーディング
wifiの調子がわるくて、調整に手間取ってたら勉強時間少なくなった#100DaysOfCode#駆け出しエンジニアと繋がりたい#早起きチャレンジ
【CSS】position: fixed; と z-index
position: fixed;
指定した位置に要素を固定
位置は top, bottom, left, right を使う
上の動画をご覧いただくと、背景だけが動き
ずーっとログインボタンが同じ位置にあるのがわかるかと思います。
これは position: fixed; でログインボタンを固定しているためです。
position: fixed;
top: 50px;
left: 500px;
【CSS】position: absolute; と position: relative;のときにも説明しましたが、サイトの左上を始点と考えて
上から 50px
左から 500px
のところにログインボタンを配置して
position: fixed; で ログインボタンよ、そこから動くんじゃない!と命令しているわけです。
z-index
要素の重なりの順番を指定する。
0を基準として数字が大きいほど上に重なる。
必ず position プロパティと一緒につかう。
さきほどの動画ですが、のんびりとしてとてもきれいな風景なので気球に乗って景色を観覧するのもいいなと思い、気球に乗ることにしました
ありゃりゃりゃりゃ・・・!
気球が前にきてログインボタンが隠れてしまったじゃないか・・・!
これは気球女子がじゃまだ。。
なんとかせねば
・・・というときに使うのが z-index です
position: fixed;
top: 50px;
left: 500px;
z-index: 1;
z-index は 0 を基準として数字が大きくなるほど上に重なる性質をもっているので、上にきてほしいログインボタンに 1 を設定しました。
z-index を使用するときは必ず position プロパティを使用するのがルールです。
気球女子が重なることなく、ログインボタンが上になりました
flexboxのゲームやって学んだことをまとめてみた
はじめに
最近、HTMLとCSSをしっかりかけるように、Progateをやり始めました。
flexboxについてもっと勉強をしようと思い、このゲームをやってみました。
ゲームなので、理解がしやすいです。1つ1つにしっかり説明がついているので、問題につまった時に、また戻って確認できるのでとても便利です。
justify-content
アイテムを水平方向に並べるもの(横の並べ方をきめるみたいな感じです)
- flex-start: コンテナーの左側に並ぶ
- flex-end: コンテナーの右側に並ぶ
- center: コンテナーの中央に並ぶ
- space-between: アイテム同士の間に等しい間隔を開けて表示
- space-around: アイテムは周囲に等しい間隔を開けて表示
※注意するところは、between
とaround
の違いです
between
は、アイテム同士の間にのみ等しい間隔を開けます。ですが、around
は周囲なので、アイテム同士の間隔だけでなく、左右の間隔なども等しくしてくれます。
See the Pen justify-content by mei (@mei1161) on CodePen.
align-items
アイテムを垂直方向に並べるものです。(縦の並べ方をどうするか決めるみたいな感じ)
- flex-start: コンテナーの上部に並ぶ
- flex-end: コンテナーの下部に並ぶ
- center: 垂直方向の中央に並ぶ
- baseline: アイテムはコンテナーのベースラインに表示される
- stretch: アイテムはコンテナーの大きさに合うよう広がる
stretch
だとflexbox
の高さに合わせて、アイテムのサイズが自動的に伸び縮みする感じですね!
See the Pen align-items by mei (@mei1161) on CodePen.
flex-direction
コンテナー内でアイテムが配置される方向を決める(配置の仕方を決める)
- row: アイテムは文章と同じ方向に並びます
- row-reverse: アイテムは文章と同じ方向にアイテムの順番を逆にして並べます。
- column: アイテムの順番を変えずに、縦方向に配置
- column-reverse: アイテムの順番を逆にして、縦方向に配置
reverseがつくとアイテムの順番が変わることを覚えておきましょう!
※reverse,columnなどを使用する場合、他の配置などにも影響する可能性があるので気をつけてください!
See the Pen flex-direction by mei (@mei1161) on CodePen.
order
アイテムはデフォルトで0の値を取るが、正や負の整数値を設定することで、アイテムの位置を変えたりすることができる。
※同じクラスを1としてみるので、要素の数で正負の整数値を設置しない場合もある。
See the Pen order by mei (@mei1161) on CodePen.
align-self
align-itemsと同じ値を設定することができる。
指定したアイテムのみ変更することができる。
flex-wrap
行におさめるように設定したり、アイテムを他の行に折り返したりするかを設定することができる。
- nowrap: 全てのアイテムを1行にフィットさせる
- wrap: アイテムは他の行へ折り返す
- wrap-reverse: アイテムを逆順にし、他の行へ折り返す。
See the Pen flex-wrap by mei (@mei1161) on CodePen.
flex-flow
flex-direction(縦方向の並び方)とflex-wrap(行を折り返すかどうか)一緒にしたもの。
これを使うと一気に設定することができる
1つ目にflex-direction
の指定、2つ目にflex-wrapの設定をいれます。
(逆でもOK)
align-content
複数の行が他の行とどういう風にどう距離を取り広がるかを指定する。
- flex-start: コンテナーの上側に詰められる
- flex-end: コンテナーの下側に詰められる
- center: コンテナーの中央に詰められる
- space-between: 行はその間に等しい間隔を空けて表示される
- space-around: 行はその周囲に等しい間隔を空けて表示される
- stretch: 行はコンテナに合うように引き延ばされる
space-between
だとアイテム同士の行間が調整されます。space-around
では、上下の間もしっかり等しい間隔を空けます。
※1行だけの場合はalign-content
を使用しても、効果がないので注意!
See the Pen align-content by mei (@mei1161) on CodePen.
最後に
column
wrap
reverse
を使うと位置関係が、少し変わるので、難易度が高くなるような気がします。
このゲームを通して、flexboxの苦手意識を少しでも、無くして行けるといいと思います。
初心者によるプログラミング学習ログ 217日目
100日チャレンジの217日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
217日目は
おはようございます
— ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) January 21, 2020
217日目
・Vue.js
・Css設計
教科書的なインプット重視学習した#早起きチャレンジ#駆け出しエンジニアと繋がりたい#100DaysOfCode
jQueryのメソッド
jQueryとこの記事について
『jQuery』とは、効果やアニメーションを簡単に実装できるJavaScriptライブラリ。
jQueryを使うとWEBページにアニメーションや効果を簡単につけることができる。
jQueryを勉強中(ど素人)なのですが、復習も兼ねて学んだメソッドを
下記にメモとして記述していこうと思います。随時更新していきます。
hide
- セレクタ(HTMLのタグ名やclass名,idなどを指定する)で指定した要素を隠すことができる。
例: $('h1').hide();
show
- セレクタで指定した隠れている要素を表示することができる。
例: $('h1').show(slow);
fadeOut
- セレクタで指定した要素を徐々に隠すことができる。
- アニメーションの速度は()内に引数として指定することができる。(1.0秒 → 1000、slowなど)
例: $('.class').fadeOut(1000);
fadeIn
- セレクタで指定した要素を徐々に表示ことができる。
例: $('.class').fadeIn(slow);
slideUp
- セレクタで指定した要素を下から上にスライドしながら隠すことができる。
例: $('#id').slideUp(1000);
slideDown
- セレクタで指定した要素を上から下にスライドしながら表示することができる。
例: $('#id').slideUp(slow);
css
- セレクタで指定したCSSを変更することができる。引数①にプロパティ、引数②にプロパティの値を設定する。
例: $('p').css('color','blue');
※ちなみに、
$('img').css('display','none');⇦ hideメソッドと同じ
$('img').css('display','block');⇦ showメソッドと同じ
text
- セレクタで指定した要素のHTMLの中身を引数で指定した内容に書き換えることができる。
例: $('p').text('アイウエオ');
html
- セレクタで指定した要素の中身のHTMLを引数で指定したものに書き換えることができる。
例: $('p').html('アイウエオ');
find
- セレクタで指定した要素の子孫要素から、引数で指定した要素を全て取得することができる。
例: $('.class').find('p');
この場合、'.class'というクラス内の'p'要素を取得することができる。
children
- セレクタで指定した要素の子要素(1階層分)から、引数で指定した要素を取得することができる。
例: $('.class').children('p');
p、h1要素の横幅を文字数合わせる
pタグ、h1タグの要素の横幅はデフォルトでは親要素の横幅に合わせられています。
<body><h1>hello world.</h1><p>hello world.</p></body>
h1{background:skyblue;/* デフォルトの状態
display: block */}p{background:pink;/* デフォルトの状態
display: block */}
これはpタグ、h1タグはデフォルトのdisplayプロパティの設定がblockとなるためです。
pタグ、h1タグのようなデフォルトのdisplayがblockの要素の横幅を文字数に合わせて設定する場合は以下のようにCSS設定をします。
h1{background:skyblue;display:inline-block;}p{background:pink;display:inline-block;}
CSS 要素を下揃えにする
以下のように親要素の中にboxがあります。
上揃えになっています。
<divclass="wrapper"><divclass="box"></div></div>
.wrapper{background:gray;width:600px;height:400px;}.box{background:yellow;margin:0auto;width:200px;height:200px;}
boxを下揃えにします。
displayをflex、縦ならびにしたいのでflex-directionはcolumnとなります。
さらにその状態から逆方向に並べたいのでflex-directionをcolumn-reverseとします。
.wrapper{background:gray;width:600px;height:400px;display:flex;flex-direction:column-reverse;}.box{background:yellow;margin:0auto;width:200px;height:200px;}
メディアクエリ_HTML&CSS_20200118
https://bitsofco.de/how-calc-works/
https://coliss.com/articles/build-websites/operation/css/how-calc-works-by-ire.htmla
【calc()】
CSS関数
加算、減算、乗算、除算が可能
width: calc(100% - 50px);
幅いっぱいから50px引いた幅を指定
width: 33.33%;
↓
width: calc(100% / 3);
HTML
CSS
media (max-width: 670px) {
.u-display__pc {
display: none;
}
}
画面幅が671px以上の場合には改行を行う。
画面幅が670px以下の場合には改行を行わない。
これにより、スマホなどで表示を行う際に綺麗に枠に合わせた文字出力が行われる。
CSS
position: fixed;
メニューの画面上部固定などに使える
transform: rotate();
要素を回転表示する(使い方わからない)
文字を右寄せにする
以下のように親要素の中にpタグがあります。
文字は左寄せになっています。
pタグのdisplayはblockのため横幅は、親要素の横幅に合わせられていますので親要素が隠れています。
<div><p>hello world.</p></div>
div{background:gray;width:400px;}p{background:skyblue;}
まず、pタグの横幅を文字数に合わせます。
displayをinline-blockとし、marginが発生するのでmarginを0にします。
div{background:gray;width:400px;}p{background:skyblue;display:inline-block;margin:0;}
pタグを右寄せにするのでpタグを float: right にします。
そのときにdivタグ float: left にします。
div{background:gray;width:400px;float:left;}p{background:skyblue;display:inline-block;margin:0;float:right;}
横並びの「左の子要素数」が「右の要素の開始位置」に干渉する件について
Javascript アロー関数を簡単にまとめて学ぶ
はじめに
アロー関数?書けるよ。あまり理解してないけどって人向けに具体的な使用例の一部をお伝えする記事です。
アロー関数とは、
アロー関数式は、より短く記述できる、通常の function 式の代替構文です。また、this, arguments, super, new.target を束縛しません。アロー関数式は、メソッドでない関数に最適で、コンストラクタとして使うことはできません。
つまり従来より簡潔に書けるし明瞭な構文で書けるってこと。
ちなみに関数とメソッドの違いは、
- 単独で 呼び出せるのが関数
myfunc(); <- こんな形の奴
- 単独で 呼び出せないのが関数
var str = 'user1,user2,user3';
var result = str.split(','); <- メソッド
従来の関数の書き方との書き換え方
引数の値を2倍にして返り値で返す関数で例えると、
- 従来の書き方
functiondoubleUp(num){returnnum*2;}
- アロー関数で書き換えた書き方 その1
constdoubleUp=(num)=>{returnnum*2;}
- アロー関数で書き換えた書き方 その2.0 (引数が一つの場合に限る)
constdoubleUp=num=>{returnnum*2;}
- アロー関数で書き換えた書き方 その2.1 (引数が一つ以上の場合)
constdoubleUp=(a,b)=>a*b;
- アロー関数で書き換えた書き方 その3.0 (関数の処理が returnで一行の場合に限る)
constdoubleUp=num=>num*2;
- アロー関数で書き換えた書き方 その3.1 (関数の処理が returnで一行以上の場合)
constdoubleUp=num=>{alert('hoge');returnnum*2;}
アロー関数と無名関数の挙動って一緒なの?
結論から言うと一緒じゃない。
関数内で this を使う場合は挙動が変わってくるんじゃい。
以下の関数を見るんじゃい。
letperson={age:"30",callName:function(){console.log(this.age);//"30" が出力されるwindow.setTimeout(function(){console.log(this.age)// undefined が出力される},1000);}};
console.log(this)で両方とも出力してもらえればわかると思うんじゃい。
window に関してはそもそも callName というオブジェクトがないんじゃい。
なので参照しようとすると undefined になるんじゃい。
しかし上記のようなオブジェクトにおいてageプロパティをwindow.setTimeout...内で使用したいというケースはよくあるケース。
ではどうするかというと、こうする。
- やり方 その1
letperson={age:"30",callName:function(){console.log(this.age);// "30" が出力されるwindow.setTimeout(function(){console.log(this.age)// "30" が出力される}.bind(this),1000);}};
bind()は引数とされている this と callName直下のスコープ内にある this を同じものとする機能があるんじゃい。
- やり方 その2
letperson={age:"30",callName:function(){console.log(this.age);//"30" が出力されるlethoge=this;window.setTimeout(function(){console.log(hoge.age)//"30" が出力される},1000);}};
hoge変数にpersonオブジェクトのスコープを代入してあげるんじゃい。
- やり方 その3
letperson={age:"30",callName:function(){console.log(this.age);//"30" が出力されるwindow.setTimeout(function(){console.log(this.age)//"30" が出力される}.call(this),1000);}};
callメソッドを使うんじゃい。
- やり方 その4
letperson={age:"30",callName:function(){console.log(this.age);//"30" が出力されるwindow.setTimeout(()=>{console.log(this.age)//"30" が出力される},1000);}};
アロー関数を使うんじゃい。
アロー関数内を使うと、アロー関数内でthisが定義されないんじゃい。
javascriptの性質上, アロー関数内でthisを見つけられない場合スコープチェーンを辿って
上の階層に同じ変数名のものを探すんじゃい。
最終的にグローバル変数まで探して見つかれなければ undefined を返すんじゃい。
こういう使い方があるんじゃい。
以上じゃい。
ps:
こういうやり方もあるよ〜」とかあれば教えて欲しいんじゃい。
勉強になるんじゃい。
画像のwidthと最大幅の指定の仕方
画像を親要素の幅に合わせる場合は下のように設定する。
img {
width: 100%;
}
親要素に合わせるが、拡大しすぎたくないときは、以下のようにmax-widthを設定する。
img {
width: 100%;
max-width: 600px;
}
よく使いそうなCSS
よく見るfont-family
@charset"utf-8";body{font-family:Arial,sans-serif;}
複数書く理由はOSによって入っているフォントが異なるため。
左のものから優先的に使用される。
最後に総称フォントファミリー名を書く
個々のフォント名ではなく、フォントのカテゴリーを指定するもの。
もし指定したフォントが全く入っていなかった場合にせめてこういう系統のフォントを表示してほしいと伝えるためのもの。
総称ファミリー名 | フォント |
---|---|
sans-serif | ゴシック体系 |
serif | 明朝体系 |
cursive | 筆記体系 |
monospace | 等幅フォント |
レイアウトが楽になる
body{box-sizing:border-box;}
こうすることでwidthとheightがmarginとborderを含めるようになる。
コンテンツが領域から溢れた時に使う
#box1{overflow:hidden;//隠れるoverflow:scroll;//スクロールバーがつく}
ボタンを無効っぽく見せる
#btn.disabled{opacity:0.5;}
特定のinputタグにスタイルを当てる
input[type=text]{width:100%;height:100%;}
複数のセレクタにスタイルを当てる
- セレクタをつなげて記述
- 同じ要素にクラス名を複数指定していて、その全てに同じCSSを適用する
- セレクタの間に半角スペースを入れて記述
- 入れ子構造の時に適用
- カンマ区切りで記述
- 異なる要素にクラス名を複数指定している時に適用する
positon
absolute:基準の位置が「親要素」
fixed:基準の位置が「ウィンド全体」
※absolute注意点
子要素をabsoluteにした場合、親要素に必ずrelative(もしくはfixed)を指定しておく
flex-box
参考記事
https://ics.media/entry/13117/
- ボックス(HTMLが生成する領域)の横並びや縦並びといったスタイル付けをする時、ボックスの親要素のスタイルのdisplayプロパティにflexを指定する。
- Flexboxにおけるレイアウトは、主軸と交差軸により決定され、初期状態では横方向の軸が主軸、縦方向の軸が交差軸となる。
- 主軸の並びはjustify-contentプロパティで指定する。
- 交差幅の並びはalign-itemsプロパティで指定する。
ボックスを複数行に並べる
- 初期設定では、ボックスは親要素の幅にかかわらず一行に並ぶ。設定を変えるにはflex-wrapプロパティの値を変える。
- nowrap:ボックスを単一行に配置
- wrap:ボックスを複数行に配置
- ボックスごとの高さは揃う。これはalign-itemsプロパティの初期値(strech)によるもの。
- 初期設定では、ボックスは親要素の幅にかかわらず一行に並ぶ。設定を変えるにはflex-wrapプロパティの値を変える。
ボックスの並び方向
- 初期状態ではボックスは横方向に並ぶ。並び方向を変更するにはflex-directionプロパティを用いる。
margin
左右にautoを指定すると、左右中央に要素を配置できる。
css
.foo {
margin: 0 auto;
}
transformについて[html, css]
はじめに
「transformは何ができるのか」
「transformはどんな時に使うのか」
ということについて書いていきたいと思います。
transform自体を使ったことがない人も多いと思いますが、
Webデザインをしていく中で必ず目にすることになると思います。
そんなtransformについてまとめていきたいと思います。
transformについて
transformを使用することによって、デザインに移動、回転、伸縮、傾斜の効果をつけることができます。二次元的な動きだけではなく、三次元的な動きにも対応しています。
transformの種類
transformには4つの関数が用意されています。
- translate() 「移動」
- rotate() 「回転」
- scale() 「伸縮」
- skew() 「傾斜」
transformの使い方
それぞれの関数にX,Y,Z,3Dが用意されています。translateX()
のように()の前にX,Y,Z,3Dを記入することでその軸に対して関数を使用することができます。
また、translate(X,Y,Z)
のように記入してもそれぞれの軸に対して関数を使用することができます。
<divclass="transform">Transform<div>
.transform{padding:10px20px;background:#59b1eb;text-align:center;color:#fff;width:30%;}
このhtml,cssに対して、transformを使用していきたいと思います。
わかりやすくするために:hover
,transition
を使用していきたいと思います。
hoverはカーソルを要素に置いた時に適用されるようにする要素です。
transitionはtransformを適用するにあたり、開始から終了までの時間を決めることができます。
translate
translateは要素に移動の効果を追加することができます。
.transform{padding:10px20px;background:#59b1eb;text-align:center;color:#fff;width:30%;transition:1s;}.transform:hover{transform:translate(20px,20px)}
.transform
にtransition: 1s;
を追加し.transform:hover{
を新たに追加しました。
transform: translate(20px,20px)
}
動きを確認してみてください。
X軸方向に20px、Y軸方向に20px動くのが確認できたかと思います。
rotate
rotateは要素に回転の効果を追加することができます。
.transform:hover{transform:rotateX(360deg)}
rotateを使用する場合px
ではなくdegree「度」を表すdeg
を使用します。
このコードの場合X軸に対して360度回転します。確認してみてください。
.transform:hover{transform:rotateY(360deg)}
この場合Y軸に対して回転するのが確認できるかと思います。
scale
scaleは要素に伸縮の効果を追加することができます。
.transform:hover{transform:scale(1.5,1.5)}
値にはpx
もdeg
も使用しません。
1.5と書けば要素の1.5倍、2.0と書けば要素の2倍になります。また、-2.0と書けば要素の1/2倍になります。
このコードではX軸、Y軸共に1.5倍になるのが確認できると思います。
skew
skewは要素に傾斜を持たせることができます。
他の要素と異なり、X軸Y軸に対してしか使用できない特徴があります。また、値にはdeg
を使用します。
.transform:hover{transform:skew(30deg,30deg)}
他の要素と異なり、X軸Y軸に対してしか使用できない特徴があります。また、値にはdeg
を使用します。
transform-originについて
transform-origin
を使用することによって、要素の変化の基準点を設けることができます。
.translate:hover{transform:rotate(45deg);transform-origin:topleft;}
基準点の設定方法ですが、
- 絶対指定(px)
- 相対指定(%)
- 位置指定(top, center,left等)
の3つがあります。
ざっくりで良いなら位置指定、細かく決めたいなら絶対指定、相対指定を使用するという風に分けたら良いと思います。
まとめ
transformはマスターするとWebデザインの幅がとても広がります。
基礎的な使用方法でも十分幅が広まります。
ぜひマスターしましょう。
レスポンシブ設計 キホンの基本 part1~display:flex;
CSSでレスポンシブなサイト作成のキホンについてやっていきますが、
その中でも超基本から。
この図のように、何もしないと要素は縦並びになってしましますよね。
レスポンシブにするためにはまず親要素のcontainerにdisplayをflexを設定します。
ちなみに、子要素の幅(width)は均等にするため、各子要素にflexを1に設定します。
.container{display:flex;}.boxA{flex:1;}boxB{flex:1;}
子要素が横並びになます。
デフォルトでは子要素の高さ(hieght)は同じで、幅(width)はコンテンツによって変わります。
今回の場合は、flex:1;を設定しているので、幅は均等です。
これがレスポンシブのキホンの基本です。
では次回は親要素のcontainerの幅を設定して、折り返す方法を書いていきたいと思います。
HTML CSSの基本だけど少し詰まる点
フォントの設定について
フォントの種類を指定するにはfont-familyプロパティを使用する必要がある。
その際に注意すべき点は、Avenir Nextのようにフォント名にスペースがある場合は、
ダブルクオーテーションで囲む必要があります。
ex h1 {
font-family: "Avenir Next";
入れ子のセレクタについて
同じ要素に別々のCSSを使用するには入れ子構造を利用します。
具定例として
.header-list li {
color: #ff0000;
}
上記のようにセレクタにおいてスペースを開けて記述することで特定の
要素にのみ変更を加えることができる。始めてWebサイトを作成した時にお世話になった記事
初めに
プログラミングを始め、初めてWebサイトを作成した時に自分がお世話になった記事をここにあげます。
もし自分と同じようなところで悩んでいるところがあれば、参考にしていってください。
参考にした記事一覧
環境構築編
WindowsでPHP/Apache環境構築(ダウンロード~画面を起動するまで)
なぜか自分のパソコンにxamppがダウンロードできなかったので、この記事を参考にApacheサーバーを入れました。
CSS編
サルワカ ChromeでCSSが反映されない?キャッシュ消去で対処
CSSの変更がブラウザになかなか反映されないという問題がこれで解決しました。
JavaScript編
JavaScriptに"Maximum call stack …"で怒られた1例と解決までにやったこと
Google ChromeのデベロッパーツールのPerformanceを使ったエラーの検出方法、Maximum call stack というエラー文の意味について知ることができました。
Samurai Blog【JavaScript入門】誰でも分かるPromiseの使い方とサンプル例まとめ!
実際のWebサイトには実装しませんでしたが、JavaScriptの関数を同期的に使う方法について学べました。
PHP編
【PHP】HTMLSPECIALCHARS関数でエスケープ処理をしてください【XSSの防止】
利用者の入力情報のエスケープの方法について学ぶことができました。
Qiita PHPオブジェクト指向入門(前半)
本だけでは理解しきれなかったPHPの基本について知ることができました。
終わりに
Webサイトを始めて作成した際にブックマークをつけた記事はもう少し多かったのですが、いくつか消してしまったので7割程度しかあげられませんでした。
Webサイトを作成して思ったことは、自分が悩んでいる問題の解決策を無料で教えてくれる現代のネット環境は素晴らしいな、ということでした。
これからも楽しみながらプログラミングに取り組んでいきたいです。
iOSを“区別”したモーダル背景のスクロール固定
概要
つい先日Win7のサポートが終わり、2020年4月以降にはEdgeもChromium製にアップデートされるとのことで、ようやくIEの壁から目を逸らせる雰囲気になってきた先にそり立つ第二の壁ことiOS Safari(個人の感想です)。
数多のトラップがiOSのアップデートのたびに仕込まれるこのブラウザですが、なまじ日本における(iPhoneの)シェア率が高いばかりに泣く泣く対応せねばなりません。どこかで聞いた話ですね
今回はその中でもモーダルウィンドウを用いるサイトの対応について、iOSかそれ以外かを区別することでうまいこと実装できた気がするので備忘録として投稿します。
あくまで差別ではなく“区別”です。
……iOS版のVivaldiはやく出ないかな。(Safariを虚ろな目で見つめつつ)
要望と仕様
モーダルウィンドウなどのコンテンツに被る情報が表示されているあいだ、背景となったコンテンツ……つまり body
部のスクロールは動かないよう固定されるべきであると考えられます。
背景まる見えレベルのサイズ感であれば許されるかもしれませんが、画面をほとんど覆うような大きさのモーダルの場合、弄っている間にいつの間にかモーダルを開いた時とは全く違う場所までスクロールしていた……となるとユーザに混乱を招くことになりかねないので、固定する方が自然な挙動だと言えます。(お客様からの要望としてもよく言われます)
加えて、モーダルウィンドウで表示される情報が一画面内に収まるとは限りません。
PCのデザインや開発者ツール上では十分収まっている量でも、画面の小さいスマートフォンや横向きにした時(見辛いことこの上なしですが……)、またはヒョコヒョコとウザいツールバーの影響などによって想定よりも狭い表示領域で見られることを考えると、モーダルウィンドウ内もスクロールに対応するのが柔軟性のある実装だと言えるでしょう。
こうした場合、touchmove
イベントをe.preventDefault();
などでキャンセルする暴力的方法は、モーダル内のスクロールも禁止してしまうため使えません。きちんと影響範囲を把握して実装すれば可能ではありますが、そのためだけにタッチイベントを制御するのは別の問題が発生しやすく、手間もリスクも多いと考えます。
よって、手早く背景 body
のスクロールを固定する方法は、おおむね2つに絞られます。
body
にoverflow: hidden;
をかけるbody
をposition: fixed;
にし、その時点のスクロール位置だけ表示をズラす
シンプルな実装
実装がシンプルかつ分かりやすいのは前者の overflow: hidden;
です。
body{overflow:hidden;}
body
(表示領域)外のコンテンツが省略されるため、ほとんどのブラウザではこれだけでスクロールを固定することができます。
モーダルを閉じる時にも overflow:hidden;
を解除するだけ。超超簡単……(カゴノトリ)
そう、iPhone(iOS)“以外”ならね。
面倒な実装
iOS(iPadOSを含む)のSafariのみ、先ほどの実装ではスクロールを止めることができません。
そのため、結局は後者の position: fixed;
による実装が必要となります。
body{width:100%;/* position:fixed;になった際に幅が変わるのを防ぐ */position:fixed;top:-XXXpx;/* モーダルを開いた地点のスクロール量(XXX)だけズラす */}
body
に position: fixed;
をかけることでスクロールを無効化されるため、iOS Safariを含めた全てのブラウザで強制的にスクロールを固定することが可能です。(この際、 body
の内容によっては表示幅が変わってしまうことがあるため、保険としてwidth: 100%;
をかけておきましょう)
ただ、position: fixed;
をかけた時点でこれまでのスクロール情報が失われてしまう(表示がページトップに戻ってしまう)ため、 top
プロパティによってモーダルを開いた地点のスクロール量だけbodyをマイナス(ネガティブ)方向にズラすことで表示位置が変わらないように見せかける必要があります。手間ですね
また、先ほどの方法と同様モーダルを閉じた際には position: fixed;
を解除するのですが、その際にも失われたスクロール情報は戻らないので、今度はスクロール位置をモーダルを開く前と同じ位置に自力で戻す必要があります。二度手間ですね
……愚痴を言っても仕方ないので、モーダルを開いた時点のスクロール量 XXX
をJSのグローバル変数に逐一保持しておくことで、これらの問題を解決します。
さらに面倒な仕様
しかし、position: fixed;
を使う方法にもいくつかの穴があります。
ひとつはスクロール情報が失われることにより、スクロール量に応じて表示が切り替わるコンテンツに影響が出ます。例えばスクロールすると表示されるページトップに戻るボタンであったり、position: sticky;
ないしはそれに近い動きをJSで実装しているものはスクロールを固定した途端に表示が消えます。ただ、これらはスクロールの固定を解除した後にはきちんと元の状態に戻るはずなので、些細な問題ではあります。
別の問題としてはMacOS(PC)のSafariで見た場合に、position: fixed;
によって「ページトップに戻った」瞬間が見えてしまうことがあります。つまりモーダルを開閉するたびにページトップが一瞬チラつくような表示が稀に発生するため、モーダルを開く箇所が多いサイトだと地味に鬱陶しく感じます。IEですら起きないのに
また、よく他サイトなどで紹介されている方法として overflow: hidden;
と position: fixed;
を併用している(2つの実装が合体したような)ものをよく見ますが、そうするとiOSのSafariでモーダルの開閉時に一瞬白いチラつきが発生することがありました。これは overflow: hidden;
がなければ発生しないようなので、上記のCSS例では省いています。同じSafariって名前なら挙動ぐらい統一してくれ
ともあれ、起こってしまうものは仕方ありません。それぞれの環境に適した実装対応を表にまとめてみました。
iOS Safari | MacOS Safari | それ以外 | |
---|---|---|---|
overflow: hidden; | × | ○ | ◎ |
position: fixed; | ○ | △ | ○ |
(併用) | △ | △ | ○ |
iOS, MacOS以外の環境(WinやAndroid等)はどちらの方法でもほぼ同じ挙動にはなるのですが、前述した通り overflow: hidden;
の方がシンプルかつ確実な方法なので二重丸つけてます。
さらにまとめるとこうなります。
- iOS:
position: fixed;
で対応 - MacOS、それ以外:
overflow: hidden;
で対応
つまり、iOSか否かを区別できれば、それぞれに適した方法でスクロールを固定することができそうです。
iOSかどうかをチェックするUA(ユーザーエージェント)は以下を参考にさせていただきました。
https://qiita.com/mtdune/items/97abb9c0bd926d4c8a13
実装
position: fixed;
対策の width: 100%;
は予めCSSの方で適用していてもあまり問題なさそうなので、先に書いておきます。この辺りは好みだと思います。
body{width:100%;/* position:fixed;になった際に幅が変わるのを防ぐ */}
準備が済んだところで、スクロール固定・解除用の関数を作成します。
//モーダルを開いた時のスクロール位置を保持varscrollPosition;//iOS(iPadOSを含む)かどうかのUA判定varua=window.navigator.userAgent.toLowerCase();varisiOS=ua.indexOf('iphone')>-1||ua.indexOf('ipad')>-1||ua.indexOf('macintosh')>-1&&'ontouchend'indocument;//bodyのスクロール固定functionbodyFixedOn(){if(isiOS){// iOSの場合scrollPosition=$(window).scrollTop();$('body').css('position','fixed');$('body').css('top','-'+scrollPosition+'px');}else{// それ以外$('body').css('overflow','hidden');}}//bodyのスクロール固定を解除functionbodyFixedOff(){if(isiOS){// iOSの場合$('body').css('position','');$('body').css('top','');$(window).scrollTop(scrollPosition);}else{// それ以外$('body').css('overflow','');}}
これでモーダルを開く際に bodyFixedOn()
を読み込むことで、
- iOS(iPhone, iPad):
position:fixed;
による固定 - それ以外のPC(Win,Mac)やAndroid等:
overflow:hidden;
による固定
が成されるようになります。
また、モーダルを閉じる際には bodyFixedOff()
で解除すれば元通り。
ちなみに、上記の条件だと端末部分のみの判定となるため、iOSアプリ版のChromeなどを使った場合であっても同じくiOSに該当するかと思います(iOSだとSafariしかちゃんと開発者ツールでの検証ができない……)。
ただ、そういった環境でもチェックした限り挙動としてはほとんど問題はないかなと思っています。
とはいえ、そもそもUAを廃止する流れやiOSのアップデートによってコロコロ仕様が変わることを考えるとこの方法も永久に使えるわけではなさそうなので、ひとまず現在(2020年1月)時点の暫定対応というつもりです。備えよう。無理……しんどい……
おまけ
ES6できちんと書くならこういう感じ……?(テンプレート文字列って便利ですね)
letscrollPosition;constua=window.navigator.userAgent.toLowerCase();constisiOS=ua.indexOf('iphone')>-1||ua.indexOf('ipad')>-1||ua.indexOf('macintosh')>-1&&'ontouchend'indocument;constbody=document.querySelector('body');functionbodyFixedOn(){if(isiOS){scrollPosition=window.pageYOffset;body.style.position='fixed';body.style.top=`-${scrollPosition}px`;}else{body.style.overflow='hidden';}}functionbodyFixedOff(){if(isiOS){body.style.removeProperty('position');body.style.removeProperty('top');window.scrollTo(0,scrollPosition);}else{body.style.removeProperty('overflow');}}
余談
この記事ではSafariばかりを目の敵にしてしまいましたが、今回紹介したどの方法でも「スクロールを固定する」=「スクロールバーが非表示になる」ので、スクロールバーの常時表示がデフォルトであるWindows環境ではスクロール固定時に画面がスクロールバーの幅の分だけ横にガタつくなどの問題もあります。
挙動自体は正しいものなので気になるなら〜程度ですが、対応策としてはいちおうIE/Edge(レガシ)専用ですが -ms-overflow-style: -ms-autohiding-scrollbar;
あたりで強制的にauto-hide(コンテンツに被るスクロールバー)に変えてやるのが良さげです。ただWin版のFireFoxやChrome、Chromium版Edgeなどはスクロールバーごと非表示にする以外どうしようもなさそう……?
結論としてはなんでもかんでもモーダルに頼るのをやめるのがよさそうというオチでした。やめて(懇願)