0
0

JavaScript(でもほぼCSS) 第7回 positionの動作

Posted at

はじめに

今回はCSSのpositionについて整理したいと思います。
というのも、モーダルウィンドウを作りたいと思ったからです。
モーダルウィンドウはよく画面の真ん中に表示されると思いますが、そのための動作のひとつとして、positionの動きを整理しておいたほうが良いと思いました。
色々インターネット上に情報はありますし、MDN Web docにもソースはありますが、自分で納得を得たくまとめたいと思います。

今回実施する内容

Div要素をpositionを使用してどのような位置にくるかをまとめていきたいと思います。

ソースコード(Git Hub)

環境

OS: Windows 10 JP (64bit)
Microsoft Edge: バージョン 120.0.2210.61 (公式ビルド) (64 ビット)

参考

position
https://developer.mozilla.org/ja/docs/Web/CSS/right
top
right
bottom
right

用語

結論

先に結論を表にまとめす。

position 位置基準 top, left,bottom, right width, height調整 後続の要素影響 スクロール
static 通常のフロー 効果なし なし なし する
relative 通常のフロー top, leftかbottom, rightの一方だけ使用 なし なし する
absolute 直近の祖先(親) top, left, bottom, right使用可 あり あり する
fixed 画面 top, left, bottom, right使用可 あり あり する
sticky 通常のフロー top, left, bottom, right使用可 なし なし 粘着

位置基準は、topleftなどの位置指定プロパティの基準となる要素を示す。

width, height調整は、topbottom設定時にその間の高さが埋まるかどうか、およびleftright設定時にその間の幅が埋まるかどうかを示す。

後続の要素影響は、position設定によってその後に記載される要素の位置に影響があるかを示す。

topleft設定時の動作

image.png

bottomright設定時の動作

  • relativeは以下の通り。その他も考え方は同じため省略。
    image.png

topleftbottomright設定時の動作

image.png

potisionの動作の調査

1つのdivに対して、positionに記載のあるpositionのプロパティ値を、記載の内容を鑑みて変更して、それがどのような結果になるかを整理したいと思います。

基本画面

posotionを設定しない場合の画面は以下の通りです。これをもとにpositionや関連するプロパティを設定し、動作を確認します。
image.png

コンソール出力

基本画面の赤字の「あいうえおかきくけこ」の各プロパティの値は以下の通りです。

top:auto
right:auto
bottom:auto
left:auto
height:24px
zIndex:auto
width:808px
fontSize:16px

元となるソースコード

position.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Position</title>
    <link rel="stylesheet" href="position.css" type="text/css">
    <script src="position.js" defer></script>
</head>
<body>
    <div id="parentDiv">
        <div>fiirstDiv</div>
        <div id="targetDiv">
            あいうえおかきくけこ
        </div>
        <div class="clsDiv">あいうえおかきくけこ</div>
    </div>
</body>
</html>
position.css
#parentDiv {
  background-color: yellow;
}

.clsDiv {
  background-color: green;
}

#targetDiv {
  background-color: red;
}
position.js
console.log(`top:${getComputedStyle(document.getElementById("targetDiv")).top}`);
console.log(`right:${getComputedStyle(document.getElementById("targetDiv")).right}`);
console.log(`bottom:${getComputedStyle(document.getElementById("targetDiv")).bottom}`);
console.log(`left:${getComputedStyle(document.getElementById("targetDiv")).left}`);
console.log(`height:${getComputedStyle(document.getElementById("targetDiv")).height}`);
console.log(`zIndex:${getComputedStyle(document.getElementById("targetDiv")).zIndex}`);
console.log(`width:${getComputedStyle(document.getElementById("targetDiv")).width}`);
console.log(`fontSize:${getComputedStyle(document.getElementById("targetDiv")).fontSize}`);

position.htmlでは、<body>の下に親となる<div id="parentDiv">を準備し、その配下にdivタグを3つ作成します。
position.cssでは、#parentDivで親となるdivタグの範囲を背景色黄色で示します。
1つ目の子であるdivタグはスタイルは設定しません。
2つ目の子であるdivタグは、positiontop, bottom, left, rightプロパティの値を設定しますが、最初は何も設定せず、これ以降でそれぞれ試します。
3つ目の子であるdivタグは、2つ目の子のdivタグの動作によって表示位置が影響を受けることがあるため、それがわかるように背景色を緑色で示します。
なお、divタグはBlock要素であり、何も設定しないと幅は画面の幅に合わせて設定されます。
position.jsでは、2つ目の子である"targetDiv"のtoprightbottomleftzIndexheightwidthfontSizeの値をコンソールに表示します。

position:static(規定値)の動作

positionの記載を抜粋しつつ、動作を確認します。

static
要素は文書の通常のフローに従って配置されます。 top, right, bottom, left, z-index プロパティは効果がありません。これが既定値です。

static設定時の画面

image.png

コンソール出力

画面の赤字の「あいうえおかきくけこ」の各プロパティの値は以下の通りです。

top:auto
right:auto
bottom:auto
left:auto
height:24px
zIndex:auto
width:808px
fontSize:16px

ソースと説明

position.htmlはファイル名を変更してpositionStatic.htmlにし参照するCSSファイル名やJavaScriptファイル名を変更していますが、それ以外の変更がないため、説明を割愛します。GitHubにはソースとしては載せておきます。

positionStatic.css
#parentDiv {
  background-color: yellow;
}

.clsDiv {
  background-color: green;
}

#targetDiv {
  background-color: red;
  position: static;
}

position: staticは規定値であり、staticを設定しても、設定していない時と動作は変わりませんでした。
要素は文書の通常のフローに従って配置されます。 と記載のある通り、1つ目の子のdivタグの次に2つ目の今回positionの値を変えていくターゲットのdivタグが表示され、その後に、3つ目の子のdivタグが配置されました。

position:staticとtop, leftの動作

statictopleft設定時の画面

image.png

コンソール出力

画面の赤字の「あいうえおかきくけこ」の各プロパティの値は以下の通りです。

top:32px
right:auto
bottom:auto
left:32px
height:24px
zIndex:auto
width:808px
fontSize:16px

ソースと説明

htmlファイル、JavaScriptファイルは上記記載通り、割愛します。

positionStatic2.css
#parentDiv {
  background-color: yellow;
}

.clsDiv {
  background-color: green;
}

#targetDiv {
  background-color: red;
  position: static;
  top: 2em;
  left: 2em;
}

top, right, bottom, left, z-index プロパティは効果がありません。 と記載のある通り、topleftを設定しても画面上は変わりませんでした。
しかし、コンソール出力では、top: 32pxとなり、設定としてはされていることを確認しました。

position:relativeの動作

relative
要素は文書の通常のフローに従って配置され、 top, right, bottom, left の値に基づいて自分自身からの相対オフセットで配置されます。オフセットは他の要素の配置には影響を与えません。つまり、ページレイアウト内で要素に与えられる空間は、位置が static であった時と同じです。

z-index の値が auto でない場合、新しい重ね合わせコンテキストを生成します。 table-*-group, table-row, table-column, table-cell, table-caption の要素における効果は未定義です。

relative設定時の画面

image.png

コンソール出力

画面の赤字の「あいうえおかきくけこ」の各プロパティの値は以下の通りです。

top:0px
right:0px
bottom:0px
left:0px
height:24px
zIndex:auto
width:808px
fontSize:16px

ソースと説明

htmlファイル、JavaScriptファイルは上記記載通り、割愛します。

positionRelative.css
#parentDiv {
  background-color: yellow;
}

.clsDiv {
  background-color: green;
}

#targetDiv {
  background-color: red;
  position: relative;
}

position: relativeに設定すると、画面上ではstaticと同様ですが、コンソール出力では、top: 0pxright: 0pxbottom: 0pxleft: 0pxとなっていることを確認しました。

position:relativeとtop、leftの動作

relativetopleft設定時の画面

image.png
赤字は右にはみ出しました。
Edgeでは横スクロールバーが表示され、右にスクロールすることができました。
image.png

コンソール出力

画面の赤字の「あいうえおかきくけこ」の各プロパティの値は以下の通りです。

top:32px
right:-32px
bottom:-32px
left:32px
height:24px
zIndex:auto
width:808px
fontSize:16px

ソースと説明

htmlファイル、JavaScriptファイルは上記記載通り、割愛します。

positionRelative2.css
#parentDiv {
  background-color: yellow;
}

.clsDiv {
  background-color: green;
}

#targetDiv {
  background-color: red;
  position: relative;
  top: 2em;
  left: 2em;
}

position:relatiiveに設定時は、要素は文書の通常のフローに従って配置され、 top, right, bottom, left の値に基づいて自分自身からの相対オフセットで配置されます。 と記載のある通り、2つ目の子のdivタグは、元の場所からtopleftが2em分移動、fontSizeが16pxのため掛ける2倍で32px分移動しました。
オフセットは他の要素の配置には影響を与えません。 と記載のある通り、元の場所は空白として残り、3つ目の子のdivタグ(背景色緑色の部分)は移動しませんでした。
驚いたのは、コンソール出力の結果で、right:-32pxbottom:-32pxで、設定していないのに値が入っていたことでした。
確かにrightは画面右部からのオフセットであり、bottomは含有ブロック下部からのオフセットなため、-32pxと言われればそうなのだと思いました。

position:relativeとtop、left、bottom、rightの動作

relativetopleftbottomright設定時の画面

image.png

コンソール出力

画面の赤字の「あいうえおかきくけこ」の各プロパティの値は以下の通りです。

top:32px
right:32px
bottom:32px
left:32px
height:24px
zIndex:auto
width:808px
fontSize:16px
margin:0px
padding:0px
border:0px

ソースと説明

htmlファイル、JavaScriptファイルは上記記載通り、割愛します。

positionRelative3.css
#parentDiv {
  background-color: yellow;
}

.clsDiv {
  background-color: green;
}

#targetDiv {
  background-color: red;
  position: relative;
  top: 2em;
  left: 2em;
  bottom: 2em;
  right: 2em;
}

topには、以下の記載があります。

topbottom の両方が指定されており、 positionabsolute または fixed に設定されており、かつ height が未指定 (auto または 100% のどちらか) の場合は、 topbottom の距離が尊重されます。それ以外の場合、 height が何らかの形で制約されていた場合、または positionrelative に設定されていた場合は、 top プロパティが優先されて bottom プロパティは無視されます。

上記の通り今回は両方設定したため、コンソール出力では、bottom: 32pxに設定されているように見えますが、画面ではbottom設定は無視されました。

leftには、以下の記載があります。

leftright の両方が定義されていて、幅の制約がない場合、要素は両方を満たすように伸縮されます。要素が両方を満たすように伸縮できない場合、要素の位置は過剰指定になります。このような場合、包含ブロックが左書きの場合は left の値が優先され、包含ブロックが右書きの場合は right の値が優先されます。

上記の通り今回は両方設定したため、コンソール出力では、right:32pxに設定されているように見えますが、画面ではright設定は無視されました。
左書きは、directionの値のことでがデフォルトでは左書きであるため、leftが優先されるということだと思います。

結局、relativeの場合、bottomrightは、topleftと同時に使用しdivタグの幅や高さを調整するようなことはできず、どちらかだけを使用するということだと思います。

position:absoluteの動作

absolute
要素は文書の通常のフローから除外され、ページレイアウト内に要素のための空間が作成されません。直近の配置されている祖先があれば、それに対して相対配置されます。そうでなければ、初期の包含ブロックに対して相対配置されます。最終的な位置は top, right, bottom, left の値によって決定されます。

この値では、 z-index の値が auto ではない場合、新しい重ね合わせコンテキストを作成します。絶対位置指定ボックスのマージンは、他の要素のマージンと相殺されません。

absolute設定時の画面

image.png

補足
image.png

コンソール出力

画面の赤字の「あいうえおかきくけこ」の各プロパティの値は以下の通りです。

top:32px
right:656px
bottom:602px
left:8px
height:24px
zIndex:auto
width:160px
fontSize:16px
margin:0px
padding:0px
borderWidth:0px

ソースと説明

htmlファイルは上記記載通り、割愛します。

positionAbsolute.css
#parentDiv {
  background-color: yellow;
}

.clsDiv {
  background-color: green;
}

#targetDiv {
  background-color: red;
  position: absolute;
}
positionAbsolute.js
console.log(`top:${getComputedStyle(document.getElementById("targetDiv")).top}`);
console.log(`right:${getComputedStyle(document.getElementById("targetDiv")).right}`);
console.log(`bottom:${getComputedStyle(document.getElementById("targetDiv")).bottom}`);
console.log(`left:${getComputedStyle(document.getElementById("targetDiv")).left}`);
console.log(`height:${getComputedStyle(document.getElementById("targetDiv")).height}`);
console.log(`zIndex:${getComputedStyle(document.getElementById("targetDiv")).zIndex}`);
console.log(`width:${getComputedStyle(document.getElementById("targetDiv")).width}`);
console.log(`fontSize:${getComputedStyle(document.getElementById("targetDiv")).fontSize}`);
console.log(`margin:${getComputedStyle(document.getElementById("parentDiv")).margin}`);
console.log(`padding:${getComputedStyle(document.getElementById("parentDiv")).padding}`);
console.log(`borderWidth:${getComputedStyle(document.getElementById("parentDiv")).borderWidth}`);

position: absoluteに設定すると、要素は文書の通常のフローから除外され、ページレイアウト内に要素のための空間が作成されません。 と記載のあるように、通常のフローから外れたため3つ目の子のdivタグは2つ目の子のdivタグがなかったかように1つ目の子のdivタグの直後に配置されました。
2つ目の子のdivタグはposition: staticの時と同様の位置には配置されました。topleftなどを設定しないと、もともとの場所に配置されると理解しました。
widthについては、文字が入る分だけの幅に変わっており、positionには、

ほとんどの場合、絶対位置指定要素に height および widthauto が設定されると、内容に合うように大きさが調整されます。しかし、非置換要素で絶対位置指定要素は、 top および bottom を指定して height を指定しない (つまり auto の) ままにすることで、利用できる垂直の空間を埋めることができます。同様に、 left および right を指定して widthauto のままにすることで、利用できる水平の空間を埋めることができます。

と記載があります。「絶対指定位置要素」はposition: absolute、もしくは、fixedに設定した要素であり、widthは未指定の初期値はautoであり、今回はこのケースに合致することから、内容に合うように大きさが調整 されたと理解しました。
heightについては、もともとブロック要素で1行だっため変化は見られませんが、同様の動作になると理解しました。

コンソール出力したtopleftなどのプロパティの値は0pxになると思っていましたが、実際には、top: 32pxright: 656pxbottom: 641pxleft: 8pxとなり、位置が指定されていました。
これは、直近の配置されている祖先があれば、それに対して相対配置されます。そうでなければ、初期の包含ブロックに対して相対配置されます。 とあるため、親のdivタグからの相対位置が設定されました。
topは32pxで、一行の高さ分の24pxではなく、8px分余分で、leftも8pxで0pxではなく、少しオフセットがあると理解しました。気になったため、JavaScriptファイルを少し修正して、marginpaddingborderのサイズを確認してみましたが、いずれも0pxで、8pxのオフセットの理由はわかりませんでしたが、レイアウトの都合上の話なのかもしれません。

position:absoluteとtop、leftの動作

absolutetopleft設定時の画面

image.png

コンソール出力

画面の赤字の「あいうえおかきくけこ」の各プロパティの値は以下の通りです。

top:56px
right:624px
bottom:578px
left:40px
height:24px
zIndex:auto
width:160px
fontSize:16px
margin:0px
padding:0px
borderWidth:0px

ソースと説明

htmlファイルは上記記載通り、割愛します。
JavascriptファイルはpositionAbsolute.jsと同様のため、割愛します。

positionAbsolute2.css
#parentDiv {
  background-color: yellow;
}

.clsDiv {
  background-color: green;
}

#targetDiv {
  background-color: red;
  position: absolute;
  top: 56px;    /* 8 + 24 + 24 = 56 */
  left: 40px;   /* 8 + 16 + 16 */
}

position: absoluteに設定時にtopleftを設定すると、親のdivタグからの相対オフセットで配置されました。
top: 56pxは、8pxのオフセットに加え、2行分(24px + 24px)でちょうど2行の下に配置するように計算した値です。
left: 40pxは、8pxのオフセットに加え、2文字分右に配置するように計算した値です。
topleftも期待通り動作しました。

position:absoluteとtop、left、bottom、rightの動作

absolutetopleftbottomright設定時の画面

image.png
補足
image.png

コンソール出力

画面の赤字の「あいうえおかきくけこ」の各プロパティの値は以下の通りです。

top:56px
right:32px
bottom:32px
left:40px
height:570px
zIndex:auto
width:752px
fontSize:16px
margin:0px
padding:0px
borderWidth:0px

ソースと説明

htmlファイルは上記記載通り、割愛します。
JavascriptファイルはpositionAbsolute.jsと同様のため、割愛します。

positionAbsolute2.css
#parentDiv {
  background-color: yellow;
}

.clsDiv {
  background-color: green;
}

#targetDiv {
  background-color: red;
  position: absolute;
  top: 56px;    /* 8 + 24 + 24 = 56 */
  left: 40px;   /* 8 + 16 + 16 */
  bottom: 2em;
  right: 2em;
}

position: absoluteに設定時にtopleftbottomrightを設定すると2つ目の子のdivタグは、親のdivタグからの相対オフセットで配置されました。
高さは、topbottomの間の垂直を埋める高さになり、横幅は、leftrightの間の幅を埋める幅になりました。

position:fixedの動作

fixed
要素は文書の通常のフローから除外され、ページレイアウト内に要素のための空間が作成されません。ビューポートによって定められた初期の包含ブロックに対して相対配置されますが、祖先の一つに transform, perspective, filter の何れかのプロパティが none 以外 (CSS Transforms 仕様書を参照) に設定されている場合は例外で、その場合は祖先が包含ブロックとしてふるまいます。 (なお、包含ブロック形成に寄与している perspectivefilter に矛盾のあるブラウザーがあります。) 最終的な位置は top, right, bottom, left の値によって決定されます。

この値は、常に新しい重ね合わせコンテキストを作成します。印刷文書の場合、要素は各ページの同じ位置に配置されます。

fixed設定時の画面

image.png

コンソール出力

画面の赤字の「あいうえおかきくけこ」の各プロパティの値は以下の通りです。

top:32px
right:656px
bottom:602px
left:8px
height:24px
zIndex:auto
width:160px
fontSize:16px

ソースと説明

htmlファイル、JavaScriptファイルは上記記載通り、割愛します。

positionfixed.css
#parentDiv {
  background-color: yellow;
}

.clsDiv {
  background-color: green;
}

#targetDiv {
  background-color: red;
  position: fixed;
}

position: fixedに設定すると、画面上ではabsoluteと同様ですが、ビューポートによって定められた初期の包含ブロックに対して相対配置されます と記載のある通り、ビューポートから相対配置されます。要するに画面の端から相対配置されます。これに対してabsoluteは祖先から相対配置されます。
これがわかる例を次の章で記載します。

position:fixedとtop、leftの動作

fixedtopleft設定時の画面

image.png

コンソール出力

画面の赤字の「あいうえおかきくけこ」の各プロパティの値は以下の通りです。

top:0px
right:664px
bottom:634px
left:0px
height:24px
zIndex:auto
width:160px
fontSize:16px

ソースと説明

htmlファイル、JavaScriptファイルは上記記載通り、割愛します。

positionFixed2.css
#parentDiv {
  background-color: yellow;
  position: absolute;
  top: 2em;
  left: 2em;
}

.clsDiv {
  background-color: green;
}

#targetDiv {
  background-color: red;
  position: fixed;
  top: 0px;
  left: 0px;
}

position: fixedに設定時の ビューボードによって定められた初期の含有ブロックに対して相対配置されますの確認のため、親のdivタグをposition: absolutetopleftを2emに設定し、2つ目の子のdivタグに対しては、topleftを0emに設定し、2つ目の子の配置を確認できるようにしました。
結果としては、画面の通りで、2つ目の子のdivタグは画面の左上に配置され、親のdivタグはtopleftともに2emほど移動した場所に配置され、2つ目の子のdivタグが親のdivタグからの相対配置ではないことがわかりました。

position:fixedとtop、left、bottom、rightの動作

fixedtopleftbottomright設定時の画面

image.png

コンソール出力

画面の赤字の「あいうえおかきくけこ」の各プロパティの値は以下の通りです。

top:32px
right:32px
bottom:32px
left:32px
height:594px
zIndex:auto
width:760px
fontSize:16px

ソースと説明

htmlファイル、JavaScriptファイルは上記記載通り、割愛します。

positionFixed3.css
#parentDiv {
  background-color: yellow;
}

.clsDiv {
  background-color: green;
}

#targetDiv {
  background-color: red;
  position: fixed;
  top: 2em;
  left: 2em;
  bottom: 2em;
  right: 2em;
}

position: fixedに設定時にtopleftbottomrightを設定すると、ビューポートから相対オフセットで配置されました。
高さは、topbottomの間の垂直を埋める高さになり、横幅は、leftrightの間の幅を埋める幅になりました。動作は、position: absolute設定時と同じと理解しました。

position:stickyの動作

sticky
要素は文書の通常のフローに従って配置され、直近のスクロールする祖先および包含ブロック (直近のブロックレベル祖先、表関連要素を含む) に対して top, right, bottom, left の値に基づいて相対配置されます。オフセットは他の要素の配置には影響を与えません。

この値は、常に新しい重ね合わせコンテキストを生成します。なお粘着要素は、直近の祖先がスクロールしない場合でも、「スクロールの仕組み」を持つ直近の祖先 (overflowhidden, scroll, auto, overlay として作成されたもの) に「粘着」します。これによって「粘着」のふるまいを効果的に抑止します (GitHub issue on W3C CSSWG を参照)。

sticky設定時の画面

image.png

コンソール出力

画面の赤字の「あいうえおかきくけこ」の各プロパティの値は以下の通りです。

top:auto
right:auto
bottom:auto
left:auto
height:24px
zIndex:auto
width:809px
fontSize:16px

ソースと説明

JavaScriptファイルは上記記載通り、割愛します。

positionSticky.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Position</title>
    <link rel="stylesheet" href="positionSticky.css" type="text/css">
    <script src="positionSticky.js" defer></script>
</head>
<body>
    <div id="parentDiv">
        <div>fiirstDiv</div>
        <div id="targetDiv">
            あいうえおかきくけこ
        </div>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <div class="clsDiv">あいうえお</div>
    </div>
</body>
</html>
positionSticky.css
#parentDiv {
  background-color: yellow;
}

.clsDiv {
  background-color: green;
}

#targetDiv {
  background-color: red;
  position: sticky;
}

positionSticky.htmlについては、sticky(粘着位置指定要素)のため、親のdivタグに<br>で改行を多めに入れました。
「粘着」とは、要するにブラウザ上でスクロールしたとしても、画面にへばりついてスクロールされないということです。 細かくいうとスクロールされるポイントもありますので、それは後ほど記載します。
sticky設定時の画面では、スクロールバーのない全体の画面を載せております。
position: stickyに設定すると、要素は文書の通常のフローに従って配置され、直近のスクロールする祖先および包含ブロック (直近のブロックレベル祖先、表関連要素を含む) に対して top, right, bottom, left の値に基づいて相対配置されます。 と記載のあるように、2つ目の子のdivタグはposition: staticの時と同じ場所に配置されました。topleftなどを設定しないと、もともとの場所に配置されると理解しました。

画面がスクロールするように、Edgeのサイズを小さくしても 「粘着」 動作は見られません。
コンソール出力のtopleftなどの値は、autoになっており、** 直近のスクロールする祖先および包含ブロック (直近のブロックレベル祖先、表関連要素を含む) に対して top, right, bottom, left の値に基づいて相対配置されます。** と記載のあるように、具体的に設定しないと **「粘着」**は動作しないと理解しました。

position:stickyとtop、leftの動作

stickytopleft設定時の画面

sticky.gif

コンソール出力

画面の赤字の「あいうえおかきくけこ」の各プロパティの値は以下の通りです。

top:80px
right:auto
bottom:auto
left:32px
height:24px
zIndex:auto
width:753px
fontSize:16px

ソースと説明

JavaScriptファイルは上記記載通り、割愛します。

positionSticky2.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Position</title>
    <link rel="stylesheet" href="positionSticky2.css" type="text/css">
    <script src="positionSticky2.css" defer></script>
</head>
<body>
    <div id="parentDiv">
        <div>fiirstDiv</div>
        <div id="targetDiv">
            あいうえおかきくけこ
        </div>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <div class="clsDiv">あいうえお</div>
    </div>
</body>
</html>
positionSticky2.css
#parentDiv {
  background-color: yellow;
}

.clsDiv {
  background-color: green;
}

#targetDiv {
  background-color: red;
  position: sticky;
  top: 5em;
  left: 2em;
}

position: stickyに設定時にtopleftを設定すると、topについては親のdivタグからの相対位置で設定されましたが、leftについては効果がありませんでした。widthは画面一杯となっており、これが要因でleftは効果がなかったように見受けられます。
画面スクロールするようにすると、2つ目の子のdivタグは位置固定されスクロールされませんでした。これが 「粘着」 の動作です。

position:stickyとtop、leftの粘着の終わりの動作

stickytopleftの粘着の終わりの設定時の画面

sticky2.gif

コンソール出力

画面の赤字の「あいうえおかきくけこ」の各プロパティの値は以下の通りです。

top:32px
right:auto
bottom:auto
left:32px
height:24px
zIndex:auto
width:160px
fontSize:16px

ソースと説明

JavaScriptファイルは上記記載通り、割愛します。

positionSticky3.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Position</title>
    <link rel="stylesheet" href="positionSticky3.css" type="text/css">
    <script src="positionSticky3.js" defer></script>
</head>
<body>
    <div id="parentDiv">
        <div>fiirstDiv</div>
        <div id="targetDiv">
            あいうえおかきくけこ
        </div>
        <br>
        <br>
        <div class="clsDiv">あいうえお</div>
    </div>
    <div id="parentDiv2">
        <div>fiirstDiv</div>
        <div id="targetDiv2">
            さしすせそたちつてと
        </div>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <br>
        <div class="clsDiv">あいうえお</div>
    </div>
</body>
</html>
positionSticky3.css
#parentDiv {
  background-color: yellow;
}

.clsDiv {
  background-color: green;
}

#targetDiv {
  background-color: red;
  position: sticky;
  top: 5em;
  left: 2em;
}

position: stickyに設定時にtopleftを設定すると 「粘着」 しますが、この 「粘着」 はずっと続くわけではありません。
positionには、以下の記載があります。

粘着位置指定要素 (stickily positioned element) とは、 position の計算値が sticky である要素です。これは包含ブロックがフロールート (またはその中でスクロールするコンテナー) 内の指定されたしきい値 (例えば top に設定された auto 以外の値など) を達するまでは相対的な配置として扱われ、包含ブロックの反対の端が来るまでその位置に「粘着」するものとして扱われます。

上記の通り、包含ブロックの反対の端が来るまでその位置に「粘着」するため、親のdivタグを2つ作り、それぞれにposition: stickyを設定し、1つ目の親のdivタグの下端(反対側の端)が **「粘着」の位置に到達すると、「粘着」**した部分は一緒にスクロールしました。
2つ目の親のdivタグ配下の2つ目の子のdivタグも 粘着 することを確認しました。

position:stickyとtop、left、bottom、rightの動作

stickytopleftbottomright設定時の画面

image.png

コンソール出力

画面の赤字の「あいうえおかきくけこ」の各プロパティの値は以下の通りです。

top:32px
right:32px
bottom:32px
left:32px
height:24px
zIndex:auto
width:753px
fontSize:16px

ソースと説明

htmlファイル、JavaScriptファイルは上記記載通り、割愛します。

positionSticky4.css
#parentDiv {
  background-color: yellow;
}

.clsDiv {
  background-color: green;
}

#targetDiv {
  background-color: red;
  position: sticky;
  top: 2em;
  left: 2em;
  bottom: 2em;
  right: 2em;
}

#parentDiv2 {
  background-color: blue;
}

#targetDiv2 {
  background-color: red;
  position: sticky;
  top: 12em;
  left: 2em;
  width: 10em;
}

position: stickyに設定時にtopleftbottomrightを設定すると、topは、親のdivタグからのオフセットで配置されました。rightは無視され、この動作は、「position:stickyとtop、leftの動作」と同じでした。
bottomrightは設定されても無視されており、この動作は、「position:relativetop、left、bottom、rightの動作」と同じでした。

おわりに

今回、positionの値を色々変更し、どのような動作になるかを確認しました。
実際に試してみることで、説明に記載のあることが理解できてよかったと思いました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0