Log

いろいろ

カスタムプロパティを使用したショートハンドを含むCSSRule.cssTextが正しい値を返さない

document.styleSheetsにはスタイルシートのリストが格納されています。各スタイルシートCSSルールのリストをcssRulesに保持しており、cssTextCSSルールのテキストを取得できます。この値が想定と異なるので困ったという話です。

ちなみに何も解決していません。今すぐ答えが欲しくてココへ辿り着いた方はブラウザバック推奨。そうでない方はゆっくりしていってね。同様に困っている人への僅かな手がかりと、自分の調査メモとしてインターネットにログを残します。

技術的な内容を書く際はできるだけ公式用語を使いたいのですが、CSSはマジで分からんので不適切な表現が多々あるかもしれません。ご容赦を。

問題のCSSルール

:root {
    --main-color: red;
}

.frame {
    border: 1px solid var(--main-color);
    border-bottom: 3px dashed var(--main-color);
}

見た目はこんな感じです。

borderの一部分だけ異なるstyleを適用するために、先にborder全体のstyleを宣言して、その直後に個別のプロパティで上書きします。*1

このCSSルールをcssTextで取得してみます。

整形するとこんな感じ。

.frame {
    border-top-color: ;
    border-top-style: ;
    border-top-width: ;
    border-right-color: ;
    border-right-style: ;
    border-right-width: ;
    border-left-color: ;
    border-left-style: ;
    border-left-width: ;
    border-image-source: ;
    border-image-slice: ;
    border-image-width: ;
    border-image-outset: ;
    border-image-repeat: ;
    border-bottom: 3px dashed var(--main-color);
}

かなしい。

borderのカスタムプロパティを除くとちゃんとした値が取得できます。

:root {
    --main-color: red;
}

.frame {
    /* border: 1px solid var(--main-color); */
    border: 1px solid red;
    border-bottom: 3px dashed var(--main-color);
}
/* cssTextで取得した値 */
.frame {
    border-top: 1px solid red;
    border-right: 1px solid red;
    border-left: 1px solid red;
    border-image: initial;
    border-bottom: 3px dashed var(--main-color);
}

他に試したケース。

  • カスタムプロパティを使用したborderのみ定義→OK
  • カスタムプロパティを使用したborderとカスタムプロパティを使用していないborder-bottomを定義→NG

どうやらカスタムプロパティを含むborderとborder-bottomが混在する場合に正しい値が取得できないようです。

CSS カスタムプロパティ (変数) の使用 - CSS: カスケーディングスタイルシート | MDN

ショートハンドプロパティの展開

先ほどちゃんと取得できたと述べたcssText。

.frame {
    border-top: 1px solid red;
    border-right: 1px solid red;
    border-left: 1px solid red;
    border-image: initial;
    border-bottom: 3px dashed var(--main-color);
}

オリジナルのCSSルールとは異なりますが問題ありません。borderは複数のプロパティを一括で指定できるショートハンドであり、cssTextではそれらが展開されただけです。

border - CSS: カスケーディングスタイルシート | MDN

CSS Object Model (CSSOM)

The cssText attribute must return a serialization of the CSS rule.

CSSの仕様書なのでmustという表記になっています。ブラウザがちゃんと実装していないのでしょうか。そもそも仕様で考慮されていないのでしょうか。

いずれにせよ、このシリアライズにおいて、カスタムプロパティを含むCSSルールが適切に処理されていないことは明らかです。ここを深ぼっていくと答えが見つかりそう。

a serialization of the CSS rule

CSS Object Model (CSSOM)

あとはこれを読むだけ。がんばれ未来の自分。to be continued...

*1:そもそもこの記述がアンチパターンなのかもしれません。

岡咲美保を聴く

今年は10選をちゃんと書きたいなあと思って今さら楽曲をあさり始めました。

手初めに好きな作曲家ですよね。本多友紀を擁するキングレコードの大型新人の存在を思い出しました。岡咲美保です。

ちょろっと聴いてみよう。

MY SPIRAL

(詞:真崎エリカ 曲・編:本多友紀(Arte Refact))

MY SPIRAL

MY SPIRAL

イントロ一音目で天井に刺さる感覚。夏に出会った岡咲美保さんのオタクに勧められて聴いたなと脳裏にメロディが蘇ってきました。あの時も天井に刺さっていて、今の今まで記憶を失っていたようです。

『Petit Etoile』を彷彿とさせる本多友紀ですね。四つ打ちデジタルサウンドがイケイケでノリノリでぐるぐるです。サビは裏で電子音が耳のなかをぐるぐる泳いでいて、それを追っていたら酔ってきました。

歌い方もハッピーな感じ伝わってきて好きです。さすが声優。

バブルス

(詞:真崎エリカ 曲:本多友紀(Arte Refact) 編:脇眞富(Arte Refact))

バブルス

バブルス

先ほどより落ち着いた。ライブで振りが付きそうな曲。ゆらゆらです。

聴いていて疲れないので無限に聴けるし、これくらいがちょうどいい。

最近やたらとカレイドスコープって歌詞を見る気がする。

ペタルズ

(詞:真崎エリカ 曲:本多友紀(Arte Refact) 編:脇眞富(Arte Refact))

ペタルズ

ペタルズ

瞳揺らす色彩は
花びらによく似て
いつも鮮やか賑やか
世界はおしゃべりだ

世界はおしゃべりだ、、、パンチライン!超気に入りました。

「揺らす」の部分も裏声もクセになります。裏声なので実際に揺れているのだ。

ラジオ「岡咲美保の世界はおしゃべりだ」を配信しろください。

ALRIGHT!

(詞:いつきおと 曲:光増ハジメ(FirstCall) 編:EFFY(FirstCall))

ALRIGHT!

ALRIGHT!

ギターが『純真Always』ぶるのかと思って焦りました。それはもう『Believer Switch』がやった。

このギターがサビで躍動していてライブ映えしそうです。キングレコード光増だと水樹奈々さんの『Clutch!!』や水瀬いのりさんの『Catch the Rainbow!』を思い浮かべると思います。ブラスでウキウキしつつもエモさもある感じかと予想したので、ギターを担いで殴り込んできた点は意表を突かれました。

ハピネス

(詞・曲:DECO*27 編:Rockwell

ハピネス

ハピネス

デビュー曲がアンセムなタイプだ。曲全体は3分ちょっととコンパクトにまとまっているけどアウトロは厚め。

寄り添うタイプの応援ソングですね。「それは超いい感じだ」「笑えたらおっけーだよ」「寝て起きてハッピーでしょ」など、歌詞のゆるい感じが超いい感じ。「ハピネスがモットーだよ」には岡咲美保さんらしさが詰まっていて、彼女を象徴するようなハッピーな楽曲です。岡咲美保さんのことは全く知らないのでテキトーなことを書きましたが、曲を聴いた感じとジャケを見た感じの印象がそんな感じなのでおっけーでしょう。

おわりに

ほとんど去年の曲だった。かなしい。

ながら見と 相性わるいsilent 相性ばつぐんW杯

ポケットモンスター スカーレット』を買いました。

ブラック・ホワイト以来12年ぶりのポケモン。驚いたことはたくさんあります。自分が御三家で水タイプを選んだところ、ライバルは炎タイプを選んできたので衝撃でした。相性悪いタイプでいじめてくるスパルタ方式は令和の時代にそぐわないのでしょうか。

最近はほとんどやりませんがゲームは現代では贅沢な娯楽だと感じます。操作が必要なためゲーム自体に集中するがあり、他のコンテンツやタスクと併用することが難しい。私の時間を独り占めです。

といってもアクションゲームではないのでポケモンはマシですね。ながらプレイでも何とかなります。となると併用するコンテンツ側を考えるべきか。

今期覇権ドラマらしいので見ている『slient』。ながら見と相性最悪です。気を抜くとすぐに手話を始めやがるので、常に映像を見ていないといけません。

絶賛開催中のサッカーW杯。これは相性最高。それっぽい展開になったら歓声が上がるので、それにあわせて目をやればいい。もちろん得点シーン意外もサッカーはおもしろいです。が、私は限られた時間で最大限たのしみたいので。タイムパフォーマンス。

というわけで毎日サッカーやれ⚽

寝坊、「牛って自分の美味しい舌をいつでもしゃぶれて幸せだよねぇ〜」、ランダムサーファー

寝坊

社会人5年目にして遂に寝坊しました。

諸事情で今週はとても忙しくなり、1日で2人日を生み出すために0時過ぎまで働く日々を送っていたら途中で限界が来たようです。寝坊しないために今後は0時から働きます。

「牛って自分の美味しい舌をいつでもしゃぶれて幸せだよねぇ〜」

『Do It Yourself!! -どぅー・いっと・ゆあせるふ-』すてっぷ⑤で牛タンを食べた主人公のセリフです。衝撃を受けました。天才はいるんだな。その後に「反芻もできるしねぇ〜」とも言っていました。

アニメ自体はDIYが題材のほのぼの日常アニメーションです。私はこの天才の次なる名言を待ち望んでいるし牛タンが食べたい。

オリジナルTVアニメ「Do It Yourself!! -どぅー・いっと・ゆあせるふ-」公式サイト

Googleの根幹になった論文を読む。検索エンジンの解剖。【Google1】#42

youtu.be

『ゆるコンピュータ科学ラジオ』の検索エンジンアルゴリズムについて話す回。

上記は前編で、ランダムサーファーが出てくるのは後編です。検索エンジンについては何となく知っているくらいだったので、おさらいしている感じがして楽しかったです。知らない人に対して説明するという形式であり、内容も分かりやすく、家事のついでにでも聴くのがオススメ。

普段はPodcastで聴いていますが、ここには敷居の低いプラットフォームとしてYouTubeのリンクを載せています。YouTubeは映像付きなんですね。あとやっぱり牛タンが食べたい。

ツールチップが画面右端からはみ出すせいで横スクロールが発生しやがる

なんの変哲もないツールチップです。

要素を画面の右端に配置すると横スクロールが発生しやがりました。

left: 0を指定しているので当たり前といえば当たり前なのでしょう。ツールチップの実装は以下です。MDNを参考にしています。

<span data-tooltip="ツールチップの表示内容です。">
    ツールチップ
</span>
[data-tooltip] {
    position: relative;
}

[data-tooltip]::before,
[data-tooltip]::after {
    position: absolute;
    top: 100%;
    left: 0%;
    z-index: 1;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
}

/* ツールチップの吹き出し部分 */
[data-tooltip]::before {
    margin-top: -5px;
    margin-left: 10px;
    border: 5px solid transparent;
    border-bottom-color: #000000;
    content: "";
}

/* ツールチップのテキスト部分 */
[data-tooltip]::after {
    margin-top: 5px;
    padding: 4px 7px;
    border-radius: 5px;
    background: #000000;
    color: #ffffff;
    font-size: 12px;
    white-space: nowrap;
    content: attr(data-tooltip);
}

[data-tooltip]:hover::before,
[data-tooltip]:hover::after {
    opacity: 0.8;
    visibility: visible;
}

シンプルな対応

せっかくHTMLとCSSだけでツールチップを実装できているので余計なことはしたくありません。要素を右端に配置する場合のみクラスを付与して、ツールチップのテキスト部分を右寄せにします。

<span class="tooltip-right" data-tooltip="ツールチップの表示内容です。">
    ツールチップ
</span>
[data-tooltip].tooltip-right::after {
    left: auto;
    right: 0%;
}

スタイル指定を打ち消すために初期値であるleft: autoを指定します。打ち消すくらいなら.tooltip-leftを用意しいいかもしれませんね。

要素が動的に配置される場合は?

私のケースでは今のところ上記の方法で解決できそう。

要素が動的に配置される場合はどうでしょうか。これはもう計算するしかありません。

  1. ウィンドウの横幅を取得
  2. 要素の左端のX座標を取得
  3. ツールチップのテキスト部分の幅を取得
  4. 1 - (2 + 3)が負の場合に右寄せクラスを付与する

といったイメージ。ツールチップのテキスト部分は疑似要素なのでgetComputedStyleを使うとよさそうです。Reactの話になりますが、コンポートを作成してrefを使うと要素の特定が楽です。短縮表示の際の実装が参考になります。

Reactで長文を短縮表示してツールチップを表示する - Log