知識の枝

"All is well"

CSS position:relativeで右寄せ

約181日前 2021年5月29日12:57
デジタル
CSS

改訂履歴


2021/5/29 投稿

1. 背景


Djangoを使った開発中に覚えたことを備忘録として残します。

今回はCSSのposition:relativeを使い、コンテンツを右寄せする方法を解説します。


2. ゴール


行内のボタンだけを右寄せして表示する。


3. はじめに


まずはイメージの共有です。



このプロジェクト管理アプリの一部です。


項目名の行の右端にフォルダアイコンが表示されています。
この行はフォルダアイコン以外の箇所をクリックするとモーダル画面が表示され、フォルダアイコンをクリックすると折り畳みのON/OFFが実行されるようになっています。



このフォルダアイコンの位置は「同じ行内のコンテンツの幅」に関係なく、一番右端に揃っています。


このような使い方を実装するCSSの書き方を解説します。


4. 右寄せ


単純に右寄せするなら対象の要素に「position: relative;」を付与し、右寄せの設定を書きつつ、
位置の基準となる要素に「position: absolute;」を付ければOKです。

html
<h3>
<span style="position: absolute;" data-bs-toggle="modal" data-bs-target="#modal_id">行の項目名</span> #位置の基準になる要素かつ、モーダルのトグル
<span>
<i class="fa fa-folder-open content-expand" aria-hidden="true" data-bs-toggle="collapse" href="#target_id" aria-expand="false" aria-controls="target_id"></i> #右寄せするアイコンかつ、折り畳みのトグル
</span>
</h3>

下記はアイコン要素に付与しているスタイルです。
css
.content-expand {
position: relative;
left: 100%; #右寄せの設定1
transform: translateX(-100%); #右寄せの設定2
}
この書き方で一応は1行の中に2つの機能(モーダルと折り畳み)を実装できます。

「項目名」をクリックするとモーダルが働き、
「フォルダアイコン」をクリックすると折り畳みが働きます



更に使い勝手を良くしたい場合。
例えば項目名の
「行」をクリックしたらモーダル
「フォルダアイコン」をクリックしたら折り畳み が働くようにしたいと思います。


行全体をクリックの対象とするには、スタイルに「display: block;」を付与すると可能です。
<span style="position: absolute; display: block;" data-bs-toggle="modal" data-bs-target="#modal_id">行の項目名</span>   #スタイルに追記



あともう一息です。
このままの状態で良さそうに見えるのですが、折り畳みの部分に問題があります。

折り畳みの中身が無いとき、言い換えると「absolute要素の中のrelative要素が無い」場合、
absoluteが付与されている要素のサイズが無いように扱われてしまいます。

結果、レイアウト(見た目だけ)が崩れます。




中身が空っぽでも要素が崩れないようにするには、「空っぽに見える要素を入れる」という方法で解決可能です。
無理やりな方法なのでどうかとは思うのですが。。。

「空に見える要素」を作りたいと思います。
html
<h3>
<span style="position: absolute;" data-bs-toggle="modal" data-bs-target="#modal_id">行の項目名</span>
<span>
<i class="fa fa-folder-open content-expand" aria-hidden="true" data-bs-toggle="collapse" href="#target_id" aria-expand="false" aria-controls="target_id"></i>
</span>
<span class="test-transparent">.</span> #ここが空っぽに見える要素
</h3>


css
.test-transparent {
position: relative;
left: 50%;
transform: translateX(-50%);
color: transparent;
-ms-user-select: none;
-moz-user-select: -moz-none;
-khtml-user-select: none;
-webkit-user-select: none;
user-select: none;
}
文字は何でも良いのですが、スペースだとダメだったので「.」にしています。

どうせ透明なので文字の位置はどこでも良いです。
上記例では真ん中に表示されるようになっています。

また、ドラッグで文字を選択できないように「user-select」をnoneにしています。


透明かつ選択できない要素なのでしっかり「空っぽ」に見えます。


5. さいごに


おそらくもっと良い方法があるのでしょうが、今の私の力ではこれが限界です。
一応動くので安心して下さい!
お疲れ様でした。