読者です 読者をやめる 読者になる 読者になる

風柳メモ

ソフトウェア・プログラミング関連の覚書が中心。

【覚書】 Twitterのタイムラインなどで、表示位置(スクロール位置)を固定したまま、ポップアップ表示させる方法

css

Twitter 原寸びゅーで、原寸画像をオーバーレイ(ポップアップ)表示させる際、タイムラインのスクロール位置はそのままにするためにはまっていたので、覚え書き。
つくづく、CSS は苦手やわぁ……。

ヘッダ及び表示範囲に相当する要素を、position: fixed を指定することで固定する、ところまではすぐ思いついたのだが、原寸画像が表示範囲よりも大きい場合にどうすればよいのかが当初は思い付かなかった。

苦肉の策として、オーバーレイ表示時には、

  • 表示範囲を、position: absolute で BODY の上端に合わせる
  • タイムラインについては、ネガティブマージンを設定して、見かけ上、オーバーレイ表示したときと同じ位置のものが表示されるようにする

のようにして対処していた(0.1.5.500まで)

しかし、どうしても無理があったので、パフォーマンスが悪く(反応がにぶく)なってしまった。

その後、

  • 表示範囲は、position: fixed; top: 0; right: 0; bottom: 0; left: 0; overflow-y: auto; を指定
  • BODY には、overflow-y: hidden; を指定

のようにしておけば、原寸画像を表示している範囲だけをスクロールさせることが出来ることに気付き、対応。

パフォーマンスについても改善されたように思われる。

なお、このようにした場合、表示範囲の操作(スクロール)に関しては(ブラウザでBODY(HTML)の標準的なキー操作として用意されている)[Space][Home][End]等のキーによる移動は効かなくなるので、自前で用意する必要があった。

TABLE の TD 要素内全てをチェックボックス化したいが……

html css

HTMLのチェックボックス要素(input[type="checkbox"])で表示される□は、閲覧環境によっては小さく表示されてしまい、チェックを入れたり外したりしにくい場合がある。

その場合の対処法として、

  1. チェックボックスそのものをCSSで拡大する(参考:チェックボックスやラジオボタンを大きくする方法: 小粋空間チェックボックスを大きくしたい - Qiita
  2. LABEL 要素を用いて、有効な範囲を拡大する
  3. チェックボックスの代替として、画像+JavaScript 等でなんとかする

といった方法があると思われる。

で、2. の手法でやろうとしたのだが、条件を

  • チェックボックスを、TABLE 内の TD 要素下に置く
  • TD の高さや横幅は不定
  • TD 内部全体を有効範囲としたい
  • チェックボックスそのものは、TD要素の上下左右中央に表示

のように定めたところ、どうやって CSS を書けばよいのかわからなくて、悩んでしまった。




    td {
        position: relative;
    }
    
    label {
        display: block;
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        background: lime;
    }
    
    input[type="checkbox"] {
        display: block; /* 無くてもよい模様 */
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        margin: auto;
    }

どうにも、冗長な書き方をしている気がしてならない。

もっとシンプルな記述方法を知りたい……ご存知の方はご教授いただきたい。

【覚書】 z-index により手前に来ている透明要素が原因でイベントが発火しないときには、 pointer-events をうまく使う

JavaScript CSS

Twitter 原寸びゅーで、画像クリック時に原寸画像を開くようにしようとして、ギャラリー表示時にはうまくクリックイベントが発火しないことに気が付いた。

原因は(z-index 指定により)画像の手前に透明な要素が存在したため*1
pointer-eventsの設定を行うことで対処できそうということが分かったので、メモ書き。
なお、pointer-events は IE では IE11 以上でサポート(IE10 以下は未サポート)となる。

サンプル




(A)




(B)




(C)


画像(BUTTON)や枠の部分をクリックしたときの動作に違いがある。

覚え書き

目的として、透明要素(枠の部分・"z-index: 1"が指定されている)のクリックイベントは残しつつ、画像をクリックしたときには別のイベントを発火させたい。

  1. 最初は、単に画像にクリックイベントを設定するだけにしていた(A)。
    ところが、実際には手前に来る透明要素(枠)のイベントしか発火しない(なお、サンプルでは、画像(BUTTON)の CSS に "cursor: pointer" を設定してあるが、これも効いていないのが判る)。
  2. 手前に来る要素の CSS に "pointer-events: none" を設定(B)。
    これで、画像をクリックしたときのイベントは発火するようになったが、逆に手前の透明要素(枠)のイベントが発火しなくなってしまう。
  3. 画像を含む要素の z-index 値を、透明要素(枠)のものより大きくし、かつ、CSS に "pointer-events: none" を設定。また、このままだと、画像のイベントも発火しなくなるため、画像の方には "pointer-events: auto" を設定(C)。
    これで、画像と枠それぞれのイベントが発火するようになった。
HTMLソースコード
<div>

    <div style="width: 120px; height: 120px; position: relative; float: left; margin: 5px; background: pink;">
        <div style="width: 100%; height: 100%; position: absolute; top: 0; left: 0; background: rgba( 0, 0, 0, 0 )">
            <button style="display: block; width: 50%; height: 50%; position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; font-size: 12px; cursor: pointer;" onclick="alert( '画像をクリック' )">画像</button>
        </div>
        <div style="width: 100%; height: 100%; position: absolute; top: 0; left: 0; background: rgba( 0, 0, 0, 0 ); z-index: 1;" onclick="alert( '枠をクリック')">(A)</div>
    </div>

    <div style="width: 120px; height: 120px; position: relative; float: left; margin: 5px; background: limegreen;">
        <div style="width: 100%; height: 100%; position: absolute; top: 0; left: 0; background: rgba( 0, 0, 0, 0 )">
            <button style="display: block; width: 50%; height: 50%; position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; font-size: 12px; cursor: pointer;" onclick="alert( '画像をクリック' )">画像</button>
        </div>
        <div style="width: 100%; height: 100%; position: absolute; top: 0; left: 0; background: rgba( 0, 0, 0, 0 ); z-index: 1; pointer-events: none;" onclick="alert( '枠をクリック')">(B)</div>
    </div>

    <div style="width: 120px; height: 120px; position: relative; float: left; margin: 5px; background: lightblue;">
        <div style="width: 100%; height: 100%; position: absolute; top: 0; left: 0; background: rgba( 0, 0, 0, 0 ); z-index: 2; pointer-events: none;">
            <button style="display: block; width: 50%; height: 50%; position: absolute; top: 0; right: 0; bottom: 0; left: 0; margin: auto; font-size: 12px; cursor: pointer; pointer-events: auto;" onclick="alert( '画像をクリック' )">画像</button>
        </div>
        <div style="width: 100%; height: 100%; position: absolute; top: 0; left: 0; background: rgba( 0, 0, 0, 0 ); z-index: 1;" onclick="alert( '枠をクリック')">(C)</div>
    </div>

    <br style="clear:both;">
</div>

*1:前後移動用のナビで、こちらもクリックイベントが設定されている