- 投稿日:2019-12-11T23:59:27+09:00
CSSでdashedとは違う破線をつくる方法
はじめに
いままで画像で対応していたことが実はCSSで再現できると知ったとき少しうれしいですよね。
今回は最近知ったことを1つ。ボーダーの破線
普段、borderを破線にしたい場合、border-styleはdashedを指定するかと思います。
See the Pen vYEGbxv by Shinji (@Shinji_Shinji) on CodePen.
dashedは線の太さは指定できるけど、線の長さや線と線の間隔が設定できず
デザインによってはdashedが使えないということがありました。
その際、自分の場合はいままで画像で対応していました。もし、
CSSで線の長さや間隔が自由に設定できたらいいですね。解決方法
グラデーションを使って破線を作ります。
例えば、
線の幅が「5px」、間隔が「5px」の破線を作る場合See the Pen dyPMmyx by Shinji (@Shinji_Shinji) on CodePen.
これで完成です。
- 投稿日:2019-12-11T23:59:17+09:00
年末まで毎日webサイトを作り続ける大学生 〜54日目 JavaScriptでじゃんけんゲームを作る〜
はじめに
こんにちは!@70days_jsです。
じゃんけんゲームを作りました。
例のごとく何も参考にせずに作りました。
ので、もっといいじゃんけんのアルゴリズムがあれば教えて欲しいです。今日は54日目。(2019/12/11)
よろしくお願いします。サイトURL
https://sin2cos21.github.io/day54.html
やったこと
勝ちは赤、
負けは青、
引き分けは黄色で表現しています。ソース全文
html↓
<body> <section> <div id="jankenWord">勝負の刻!</div> </section> <section> <div id="MyjankenImage"></div> <div id="jankenImage"></div> </section> <section> <div id="rock" class="jankenButton">グー</div> <div id="scissors" class="jankenButton">チョキ</div> <div id="paper" class="jankenButton">パー</div> </section> </body>css↓
body { margin: 0; display: flex; justify-content: center; align-items: center; flex-direction: column; } section { display: flex; } div { width: 100px; height: 100px; border: solid 1px black; margin: 50px 0 0 50px; display: flex; justify-content: center; align-items: center; } #jankenImage { background-size: cover; } #MyjankenImage { background-size: cover; } #jankenImage::before { content: "敵"; margin-top: 130px; } #MyjankenImage::before { content: "Me"; margin-top: 130px; } .jankenButton { border-radius: 50%; cursor: pointer; } .click-none { pointer-events: none; }JavaScript↓
let janken = { 0: "rock", 1: "paper", 2: "scissors" }; let img = { rock: "day54/rock.png", scissors: "day54/scissors.png", paper: "day54/paper.png" }; let jankenImage = document.getElementById("jankenImage"); let MyjankenImage = document.getElementById("MyjankenImage"); let jankenWord = document.getElementById("jankenWord"); let jankenButton = document.getElementsByClassName("jankenButton"); for (var i = 0; i < jankenButton.length; i++) { let jankenChoice = jankenButton[i]; jankenChoice.addEventListener("click", function() { let random = Math.floor(Math.random() * 3); jankenImage.style.backgroundImage = "url(" + img[janken[random]] + ")"; MyjankenImage.style.backgroundImage = "url(" + img[jankenChoice.id] + ")"; judge(random, jankenChoice.id); }); } //引数はtekidaは乱数、meは選択した要素のid function judge(tekida, me) { let teki = janken[tekida]; if (teki === me) { jankenWord.innerHTML = "ヒキワケ"; jankenWord.style.backgroundColor = "rgba(255,250,50, .5)"; } else if (me === "rock" && teki === "scissors") { jankenWord.innerHTML = "カチ"; jankenWord.style.backgroundColor = "rgba(255,50,50, .5)"; } else if (teki === "rock" && me === "scissors") { jankenWord.innerHTML = "マケ"; jankenWord.style.backgroundColor = "rgba(55,50,250, .5)"; } else if (me.length > teki.length) { jankenWord.innerHTML = "カチ"; jankenWord.style.backgroundColor = "rgba(255,50,50, .5)"; } else { jankenWord.innerHTML = "マケ"; jankenWord.style.backgroundColor = "rgba(55,50,250, .5)"; } }じゃんけんのアルゴリズム
重要なのはここですよね。
今回、僕はグーチョキパーをhashにしました。
let janken = {
0: "rock",
1: "paper",
2: "scissors"
};その時、文字数に着目しました。
すると、rock以外は文字数が大きいほど強い法則を見つけました。
scissors > paper
paper > rock
なので、以下のように書きました。if (teki === me) {
ヒキワケ
} else if (me === "rock" && teki === "scissors") {
カチ
}else if (teki === "rock" && me === "scissors") {
マケ
} else if (me.length > teki.length) {
カチ
} else {
マケ
}文字数じゃなく、数字を使っても良かっても良かったかもしれませんね。
ただ、まあ、これでじゃんけんは一応成立します。感想
ロジックを考えてちゃんと動いてくれると楽しかったりします。
ただ、あまり正確すぎたり最適を求めたりしすぎたりするのは自分の性に合わないということも分かりました。
これからもゆるく楽しく作れればいいな。
- 投稿日:2019-12-11T21:08:02+09:00
初心者によるプログラミング学習ログ 181日目
100日チャレンジの181日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
181日目は
おはようございます
— ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) December 10, 2019
181日目
webサイトコーディング課題
更新履歴のページ作成#100DaysOfCode #駆け出しエンジニアと繋がりたい #早起きチャレンジ
- 投稿日:2019-12-11T18:31:17+09:00
HTML・CSSでよく使う記述
初めに
よく使う記述で、毎度調べたりするのが面倒なので、ここに書き溜めていきます。
HTML編
HTML空の記述
<html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title></title> </head> <body> </body> </html>CSSの読み込み
<!-- cssの読み込み --> <link rel="stylesheet" href="./css/mobile.css"> <!-- メディアクエリーで条件付きのcssの読み込み --> <link rel="stylesheet" href="./css/xxx.css" media="screen and (min-width: 640px)">CSS編
メディアクエリ
@media screen and (min-width: 640px) { /* 横幅640pxより大きくなると適応 */ }親要素をはみ出す
.body { width: 640px; margin: 0 auto; } .title { margin-left: calc(((100vw - 100%) / 2) * -1); margin-right: calc(((100vw - 100%) / 2) * -1); background: #ccc; } .title span { width: 640px; }↓↓こういうやつ↓↓
対応ブラウザ https://caniuse.com/#search=calc
対応ブラウザ https://caniuse.com/#feat=viewport-units以上
- 投稿日:2019-12-11T17:56:47+09:00
Bootstrap 4 のGRID SYSTEMを使ってWebサイトのコラムをレスポンシブ化する
BootStrapでコラムをレスポンシブデザインにする
HTML, CSSだけだとレスポンシブ化って難しいけど、Bootstrapを使用すると簡単!
まず【前提】WEBサイトの横幅は12個のBOXでできている
←------------------WEBサイトの横幅-----------------→
1 2 3 4 5 6 7 8 9 10 11 12 BootstrapのGrid SystemではWidthが12個のBOXで敷き詰められている。
PC,タブレット, スマホによって、その12個のBOXのうちの何個を使用するかをそれぞれ指定できる。説明難しいからとりあえずコード。
column-responsive.html<div class="container"> <div class="row"> <div class="col-lg-2 col-md-3 col-sm-12" style="background-color:red; border: 1px solid;"> コンテンツ </div> </div> </div>まずdiv class="row(行)"の中にcolumn(列) divを作成する。
ここでポイントが
①col-lg-2 (PC表示の時は12個のBOXのうち2個のスペース使いますよ)
②col-md-3 (タブレット表示の時は12個のBOXのうち3個のスペース使いますよ)
③col-sm-12 (スマホ表示の時は12個のBOXのうち12個のスペース使いますよ)つまり
①2/12 = 6分割(6コラム)
②3/12 = 4分割(4コラム)
③12/12 = 1分割(1コラム)
となる。ちなみにlgはPC、mdはタブレット、smはスマホの表示コラムってしたけど、厳密には横幅のPixcel数で区切っているみたい。
レスポンシブ化、Bootstrapを使うとめちゃくちゃ簡単だからとてもおすすめ。
ちなみにコラムのレスポンシブ化するときは、基本的に最初にclass="container"のdivを使うから気をつけてね。ちなみにこちらが公式ドキュメント
https://getbootstrap.com/docs/4.4/layout/grid/
- 投稿日:2019-12-11T13:49:18+09:00
電車の発車案内板をHTMLとCSSだけで作ってみる~試行錯誤編その2~
この記事は
電車の発車案内板をHTMLとCSSだけで作ってみる~試行錯誤編その2~
の継続記事です。前回の反省点
・ドットの精度が低かった
・もう少しドットだけでフォントを生成する手法を勉強したほうがいいということでした。
ドットの研究
Photoshopで、700%まで拡大し、見てみると、画像のふちに原色より薄い領域があることに気が付きました。
やってみる
今回は「品」だけで。
CSS(Scss)
style2.scss$pixel:2px; $pixel2:2px; .guide{ width:400px; height: 50px; background:#000; &-inner{ width:280px; height: 40px; display:flex; } &-text-char1{ width:40px; height: 40px; display:grid; grid-template-columns:1fr repeat(16,$pixel) 1fr; grid-template-rows:repeat(25,$pixel2); grid-template-areas: "... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ..." "... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ..." "... ... ... w01 g01 g01 g01 g01 g01 g01 g01 g01 g01 w02 w02 ... ... ..." "... ... ... w03 g02 g02 w04 w04 w04 w04 w04 g03 g03 w05 w05 ... ... ..." "... ... ... w06 g04 g04 w07 ... ... ... ... w08 g05 g05 w09 ... ... ..." "... ... ... w10 g06 g06 w11 ... ... ... ... w12 g07 g07 w13 ... ... ..." "... ... ... w14 g08 g08 w15 ... ... ... ... w16 g09 g09 w17 ... ... ..." "... ... ... w18 g10 g10 w19 ... ... ... ... w20 g11 g11 w21 ... ... ..." "... ... ... w22 g12 g12 w24 ... ... ... ... w25 g13 g13 w26 ... ... ..." "... ... ... w27 g14 g14 g14 g14 g14 g14 g14 g14 g14 g14 w28 ... ... ..." "... ... ... w29 g15 g15 g15 g15 g15 g15 g15 g15 g15 g15 w30 ... ... ..." "... ... ... ... w31 w31 w31 w31 w31 w31 w31 w31 w31 w31 ... ... ... ..." "... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ..." "... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ..." "... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ..." "... ... w32 g16 g16 g16 g16 ... ... ... w33 g17 g17 g17 g17 w34 ... ..." "... ... w35 g18 w36 w36 g19 ... ... ... w37 g20 w38 w38 g21 w39 ... ..." "... ... w40 g22 ... ... g23 ... ... ... w41 g24 ... ... g25 w42 ... ..." "... ... w43 g26 ... ... g27 ... ... ... w44 g28 ... ... g29 w45 ... ..." "... ... w46 g30 ... ... g31 ... ... ... w47 g32 ... ... g33 w48 ... ..." "... ... w49 g34 ... ... g35 ... ... ... w50 g36 ... ... g37 w51 ... ..." "... ... w52 g38 g38 g38 g38 ... ... ... w53 g39 g39 g39 g39 w54 ... ..." "... ... w55 g40 g40 g40 g40 ... ... ... w56 g41 g41 g41 g41 w57 ... ..." "... ... w58 g42 ... ... g43 ... ... ... w59 g44 ... ... g45 w60 ... ..." ; } @for $i from 1 through 67 { .char1-guide__dotg#{$i}{ @if $i < 10 { grid-area:g0#{$i}; } @else { grid-area:g#{$i}; } background-color:#08eb0e; } .char1-guide__dotw#{$i}{ @if $i < 10 { grid-area:w0#{$i}; } @else { grid-area:w#{$i}; } background-color:#d8fad8; } } }薄い領域をw~にし、2色構成で、作ってみました。(並び作るの大変でした・・)
HTML(ejs)
dotsample.ejs<html> <head> <link rel="stylesheet" href="./css/style2.css"> </head> <body> <div class="guide"> <div class="guide-inner"> <div class="guide-text-char1"> <% pix1 = 1; %> <% pix2 = 1; %> <% for(i=0; i<=45; i++){ %> <% for(j=1; j<=25; j++){ %> <div class="char1-guide__dotg<%= pix1 %>"></div> <% } pix1++; } %> <% for(k=0; k<=60; k++){ %> <% for(l=1; l<=25; l++){ %> <div class="char1-guide__dotw<%= pix2 %>"></div> <% } pix2++; } %> </div> </div> </div> </body> </html>2種類あるので、変数やfor文もその数増えます。
※サーバーに負荷がかかりそうなので一旦削除しました。別な方法考えます。
やっぱり、精度が低いです・・
反省点
・ドットの文字の原理をもう少し勉強したほうがいい
・制度を上げる訓練をした方がいいこのあと
しばらく1週間置いて研究し続けてみたいと思います。
- 投稿日:2019-12-11T13:28:07+09:00
画像をドラッグ&ドロップで登録してプレビュー表示
備忘録
input:fileの画像登録時にドラッグ&ドッロップでinputに値を渡し、プレビューを出す記述。
(通常登録も対応)JSライブラリ依存せずに使用(してるはず)。
CODEPEN
See the Pen 画像をドラッグ&ドロップで登録してプレビュー表示 by manabu tanaka (@tonkatsu) on CodePen.
記述
html ドラッグ&ドロップするエリア<form method="post" enctype="multipart/form-data"> <div id="dragDropArea"> <div class="drag-drop-inside"> <p class="drag-drop-info">ここにファイルをドロップ</p> <p>または</p> <p class="drag-drop-buttons"> <input id="fileInput" type="file" accept="image/*" value="ファイルを選択" name="photo" onChange="photoPreview(event)"> </p> <div id="previewArea"></div> </div> </div> <button type="submit" name="submit" value="登録">登録<button> </form>css 簡単に整形#dragDropArea{ background-color: #f4f4f4; margin: 10px; padding: 10px; border: #ddd dashed 5px; min-height: 200px; text-align: center; } #dragDropArea p{ color: #999; font-weight: bold; font-size: 14px; font-size: 1.4em; } #dragDropArea .drag-drop-buttons{ margin-top: 20px; font-size: 12px; font-size: 1.2em; } .drag-drop-buttons input{ margin: auto; }JS ドラドロイベントでごにょごにょ&選択時にごにょごにょvar fileArea = document.getElementById('dragDropArea'); var fileInput = document.getElementById('fileInput'); fileArea.addEventListener('dragover', function(evt){ evt.preventDefault(); fileArea.classList.add('dragover'); }); fileArea.addEventListener('dragleave', function(evt){ evt.preventDefault(); fileArea.classList.remove('dragover'); }); fileArea.addEventListener('drop', function(evt){ evt.preventDefault(); fileArea.classList.remove('dragenter'); var files = evt.dataTransfer.files; console.log("DRAG & DROP"); console.table(files); fileInput.files = files; photoPreview('onChenge',files[0]); }); function photoPreview(event, f = null) { var file = f; if(file === null){ file = event.target.files[0]; } var reader = new FileReader(); var preview = document.getElementById("previewArea"); var previewImage = document.getElementById("previewImage"); if(previewImage != null) { preview.removeChild(previewImage); } reader.onload = function(event) { var img = document.createElement("img"); img.setAttribute("src", reader.result); img.setAttribute("id", "previewImage"); preview.appendChild(img); }; reader.readAsDataURL(file); }参考サイト
https://www.kabanoki.net/1552/
http://koheik.hatenablog.com/entry/2016/07/08/152936
https://qiita.com/sanapon1020/items/77d37fe1fd6f87740e1b
- 投稿日:2019-12-11T12:37:42+09:00
aタグをクリック後にボタンのカラーを変更しない処理
- 投稿日:2019-12-11T12:18:00+09:00
親要素の背景透過を子要素に適用したくない
備忘.
親要素のstyleで'opacity: 0.8;'とかを設定すると,その子要素にも自動的に同じだけの透過が効いてしまうので
opacityではなく'rgba(r, g, b, 0.8)'のようなを設定してやるとよい
- 投稿日:2019-12-11T12:17:36+09:00
レスポンシブルサイト作成の手順と注意点
はじめに
ここ最近にPCとモバイルのどちらにも対応できるレスポンシブルサイトについて学んだので、それについてここで復習がてらにアウトプットしようと思います。
レスポンシブルサイトについて
レスポンシブルサイトとは、上で軽く触れた様にPC対応とモバイル対応の両方ができるサイトです。
具体的に言うと、メディアクエリを使って各端末ごとのCSSを記載していき、CSSを切り替えることで様々な端末絵の対応が可能になります。
しかし、レスポンシブルサイトにはメリットもありデメリットもあります。それを軽くまとめます。メリット
PC対応とモバイル対応が両方できるため、サイトが一つだけですみ管理が簡単。デメリット
HTML構造を同じにしないといけないため、レイアウトに制限あり。
必要な技術力が専用サイトよりも高い。作成の流れ
1、スマホ版のレイアウトとPC版レイアウトのデザイン案を作成する。
この際に、レイアウトを先に考えるのではなく、必要コンテンツを先に出して、それを元にレイアウトを考える。2、デザインにセクションやHTML要素を割り当てていきHTML構造を作成する。
3、各要素にクラス名などのセレクタ名をつけていく。
この際、セレクタ名は複数開発に仕様が出ない様に一目でわかるものにする。4、CSSを割り当てていく。
- 投稿日:2019-12-11T11:44:41+09:00
2019年 スマホブラウザ対応で苦戦したこと
私は普段業務で、Webページの保守・運用を主にしております。
特にスマホブラウザメインのサイトを扱っているため、スマホでの表示崩れや仕様に対応しなければならないことが多いです。そのなかでも、今年1年の間で直すのにてこずったスマートフォン向けの対応について、今回は備忘録もかねて紹介してみようと思います。
1. iOS編
1-1. 横画面表示に切り替えると、文字の大きさがバラバラになる
文字サイズがバラバラになってしまったコード
まずは、実際に横画面にして崩れてしまっていた箇所を、最小限のコード量で再現してみます。
<p class="line-height-big">てすと</p> <p class="line-height-big">てすてす<span class="red">てすと</span></p> <style> *{ line-height: 1; } .line-height-big { line-height: 1.2; } .red { color: #ff0000; } </style>
- まずすべての要素(
*
セレクタ)にline-height:1
を指定。- 異なる値の
line-height
を指定したクラス(今回は.line-height-big
)を作成。- pタグを2つ用意し、片方に
.line-height-big
を指定.line-height-big
で囲った要素の子要素にただのテキストとspan
で囲ったテキストを配置横画面表示にすると、なぜか
.line-height-big
の中のspan
の中の文字だけ小さくなってしまいました。
ちなみにclass="red"
はみやすくするためにつけたので、文字を赤くしなくても同じことが起こります。原因
ブラウザを横画面にした時に、文字サイズを調整する機能がうまく動作せずにサイズがバラバラになってしまいます。
下記のコードのように-webkit-text-size-adjust: 100%;
を指定すれば、横画面にしても文字サイズが変わらず、大きさがバラバラになることもありません。body { -webkit-text-size-adjust: 100%; }だけど、横画面にした時、文字が大きくなってほしい
しかし今回は、横画面にした時に文字サイズが大きくなって欲しかったため、
-webkit-text-size-adjust: 100%;
は使わずに対応するために挙動について検証してみました。パターン1
<p class="line-height-big">てすと</p> <p class="line-height-big">てすてす<span class="red">てすと</span></p> <style> *{ line-height: 1; } .line-height-big { line-height: 1.2; } .red { color: #ff0000; } </style>
line-height
の値が異なる要素だけ小さくなってしまっているようでした。パターン2
<p>てすと</p> <p class="line-height-big">てすてす<span class="red">てすと</span></p> <style> *{ line-height: 1; } .line-height-big { line-height: 1.2; } .red { color: #ff0000; } </style>
この場合も同様、文字が小さくなってしまっている箇所はline-height
の値が他と異なっています。解決方法
ということで、
line-height
の値が一定になるように修正します。<p class="line-height-big">てすと</p> <p class="line-height-big">てすてす<span class="red line-height-big">てすと</span></p> <style> *{ line-height: 1; } .line-height-big { line-height: 1.2; } .red { color: #ff0000; } </style>上記のコードのように
line-height
の値を揃えれば、文字の大きさが一定になりました。でも、下記のようにpタグが1つだけの場合だと
<p class="line-height-big">てすてす<span class="red">てすと</span></p> <style> *{ line-height: 1; } .line-height-big { line-height: 1.2; } .red { color: #ff0000; } </style>
line-height
の値が異なるものが混じっていますが、文字サイズはバラバラになりません。
line-height
の値が異なる要素が3つ以上ある場合、バラバラになってしまう?ように思えますが
どの文字が小さくなってしまうのかなどは、規則性がわからずじまいでした、、、しかし今回のように、同じブロックの中に、さまざまな
line-height
が混在しないようにすれば、他の原因で文字サイズがバラバラになってしまう事象には遭遇していません。詳しい仕様などがわかる方がもしいらっしゃれば、コメントでぜひ教えていただけると助かります?
1-2. 入力フォームにカーソルを合わせたときにズームしないでほしい
iOS端末では、
input
要素のフォントサイズが16px以下だと、入力フォームびカーソルを合わせたときに拡大表示される機能があります。textarea { font-size: 10px; width: 60%; height: 50px; margin: 0 20%; padding: 10px; resize: none; }
font-size
を16px以上にすれば拡大されないようになります。textarea { font-size: 16px; width: 60%; height: 50px; margin: 0 20%; padding: 10px; resize: none; }
font-size
16px以下で、拡大しないように実装したい場合は、scale
を利用します。textarea { /* scale(0.5)で半分の大きさになってしまうので、全て2倍の値にする */ font-size: 20px; width: 120%; height: 100px; margin: 0 40%; padding: 20px; resize: none; transform: scale(.5); transform-origin: left top; }
scale
によって文字以外も縮小されてしまい、見た目が少し変わってしまうので、縮小率に合わせて大きい値を指定するか、入力フォームをdiv
などで括って、そこにcssを当てるなどで対応できると思います。こちらの方法使用する場合は、標準の機能を動作させないようにすることになるため、フォントサイズが小さくても操作性に問題がないか、要検証です?
2. Android編
2-1. Android4以下の一部ブラウザでFlexが崩れる
これは単純にブラウザが対応していないだけでした?
ベンダープレフィックス付与すれば、Android4以下でもFlexを使用できます。Flexコンテナ
.flex { display: -webkit-box; /* Android用 */ display: flex; }Flexカラム
.flx-column{ -webkit-box-flex: 1; /* Android用 */ flex: 1 1 0; }justify-contentプロパティ
.flex-start{ -webkit-box-pack: start; /* Android用 */ justify-content: flex-start; } .flex-end{ -webkit-box-pack: end; /* Android用 */ justify-content: flex-end; } .flex-center{ -webkit-box-pack: center; /* Android用 */ justify-content: center; } .flex-space-between{ -webkit-box-pack: justify; /* Android用 */ justify-content: space-between; }align-itemsプロパティ
.flex-start{ -webkit-box-align: start; /* Android用 */ align-items: flex-start; } .flex-end{ -webkit-box-align: end; /* Android用 */ align-items: flex-end; } .flex-center{ -webkit-box-align: center; /* Android用 */ align-items: flex-center; } .flex-baseline{ -webkit-box-align: baseline; /* Android用 */ align-items: baseline; } .flex-stretch{ -webkit-box-align: stretch; /* Android用 */ align-items: stretch; }
align-content
は使えません、、、?制作のときは、開発者ツールを使ってAndroid用のベンダープレフィックスが付いているcssのみを有効にして表示確認をすれば、Flexが未対応の実機でも崩れず表示できました。
まとめ
以上、対応に手こずったスマホブラウザ対応についてまとめてみました。
同様の現象で困っている人のヒントになれば幸いです。。。?♂️
- 投稿日:2019-12-11T02:05:45+09:00
CSSでパタパタ動くランキングボードを作った
はじめに
12月になると流行語大賞をはじめとする、様々な〇〇大賞が発表されます。
今回は、そんなときに使われるランキングボードをCSSで作りました。CSSで作ったらこうなった
オレンジの「PUSH」ボタンを押すとランキングがパタパタと動き出します。
今年の流行語大賞をランキングボードに出してみます。
(※ スマホでは上手く表示されないかもしれません。。)See the Pen CSS Ranking Board by saka212 (@saka212) on CodePen.
ソース
カスタマイズに必要な部分のHTMLとCSSを載せます。
全体はちょっと長いのでcodepenで。
https://codepen.io/saka212/pen/PowZppxランキングが動き出す仕組み
cssinput[type="checkbox"] { display: none; } label { display: inline-block; box-sizing: border-box; width: 80px; height: 50px; margin-right: 5px; line-height: 50px; background: #ffa500; border: solid 1px #ffa500; border-radius: 4px; border-bottom: 4px solid #d37800; text-shadow: 1px 1px 1px rgba(0,0,0,0.2); color: #fff; text-align: center; font-weight: bold; vertical-align: top; cursor: pointer; } .btn:checked + label + .frame .flip:nth-of-type(1) { /* animation: keyframe名 周期 開始タイミング 回数 アニメショーン終了後のスタイル指定 */ animation: frame-rotate var(--duration) calc(var(--delay) * 0) var(--count) forwards; } .btn:checked + label + .frame .flip:nth-of-type(2) { animation: frame-rotate var(--duration) calc(var(--delay) * 1) var(--count) forwards; } .btn:checked + label + .frame .flip:nth-of-type(3) { animation: frame-rotate var(--duration) calc(var(--delay) * 2) var(--count) forwards; } .btn:checked + label + .frame .flip:last-child { display: none; }チェックボックスを隠し、ボタン化したラベルを押すことで、ランキングがパタパタと動きます。
動きの流れを簡単に説明すると...1.チェックボックスとラベルタグを関連付ける。
↓
2.関連付けることで、ボタン化したラベルをクリックするとチェックが入る。
↓
3.チェックされたときに適用されるCSSに、animation
プロパティを書いておくことでアニメが動く。表示したいパタパタの数の合わせて、
.btn:checked + label + .frame .flip:nth-of-type(1) {...}
の部分は増やしておきます。animation
プロパティの値は、CSSカスタムプロパティで設定すると便利です。ランキング内容を変えて遊びたいとき
html<div class="row"> <input type="radio" id="btn1" class="btn"> <label for="btn1">PUSH ME</label> <div class="frame"> <div class="flip" data-txt="ONE TEAM" data-txt-next="令和"></div> <div class="flip" data-txt="令和" data-txt-next="タピる"></div> <!-- ↓↓ この 「data-txt-next」にパタパタが止まった止まったときに表示したいテキスト --> <div class="flip" data-txt="タピる" data-txt-next="ONE TEAM"></div> <!-- ↓↓ この「data-txt」にボタンを押す前に表示するテキスト --> <div class="flip open" data-txt="大賞"></div> </div> </div>ランキングひとつ分のhtmlです。
3行のランキングを表示しているので、このhtml部分を3つ用意しています。
ボタンを押す前に表示するテキストを、
<div class="flip open" data-txt="..."></div>
のdata-txt="..."
に書きます。
パタパタが止まったときに表示したいテキストは、そのひとつ上のdivのdata-txt-next="..."
に書きます。感想
rotateを使ったアニメーションはパズルですね。
よくよく整理しながら進めていかないと、何を作っているかわからなくなります。
リアリティーを出せるように、いろいろなやり方をためしているうちに、自分の頭の中もパタパタしてきたので「それっぽさ」が出る方向に転換しました。
もっとシンプルな作り方もあるかもしれません。おわりに
「2019年ティーンが選ぶトレンドランキング」は、ほとんどわかりませんでした...。
- 投稿日:2019-12-11T02:05:24+09:00
縦にたたむtransitionを頑張って再利用しやすい形で作る
tl;dr
- UIアニメーションはユーザに対して付属的な情報を効果的に伝えることができるので、ビシバシ使っていきたい
- 特に頑張ってプレーンなCSSでアプリケーションを作っている人は、transitionを作るのが結構辛かったりする
- transitionを気合い入れて再利用しやすい形で作ると、使うときの心理的障壁を下げることができて、アプリケーションの品質向上に寄与する
- アニメーションによってはDOMのラッパーが必要な場合とかもあるけど、最悪VNode触ることでシンプルな使い勝手を確保できる
前提
この記事では縦に折りたたむtransitionをプレーンなCSS(ここではCSSプリプロセッサを使うかどうかは問わず、CSSフレームワークやUIライブラリをベースに構築しない方針を指します)で実装することを通して、再利用しやすいtransitionコンポーネントの作り方について述べていきます。
toB向け管理画面やMVPを作る場合はCSSフレームワークやUIライブラリを主軸にして、CSSをなるべく自分で書かないでアプリケーションを作っていく選択肢もあります。その場合はよく使われるtransitionはあらかじめ用意されていたり、コンポーネントに実装されていたりすると思います。
しかし、
- アプリケーションのあしらいやビジュアル・ブランディングについての軸がある
- 少しリッチめなユーザインタラクションを作っている・作る予定がある
- 細かいインタラクションを調整する必要がある
- 特定のCSSライブラリにフル依存することで学習コストが増す
などプレーンCSSでイチから作る選択肢を選ぶ状況などもあり、その場合は自らの手でtransitionを実装していく必要があります。
とはいえ、プレーンCSSではない技術スタックであっても、必要に応じて独自でtransitionを用意することはありえますし、再利用しやすいtransitionコンポーネントをきちんと作れることはどの環境でも有用なのではないかと思います。UIアニメーションを実装することで提供できる価値
Apple Human Interface Guidelines先輩は
Beautiful, subtle animation throughout iOS builds a visual sense of connection between people and content onscreen. When used appropriately, animation can convey status, provide feedback, enhance the sense of direct manipulation, and help users visualize the results of their actions.
Animation - Visual Design - iOS - Human Interface Guidelines - Apple Developer
(意訳)
iOSのすみずみにある美しく控えめなアニメーションは画面上のコンテンツとユーザの間に視覚的な繋がりを構築するんやで。適切にアニメーションを使うと 状態を伝えたり、フィードバックを与えたり、インタラクティブUIの操作感覚を強化したり、ユーザインタラクションの結果を伝えるための補助ができるんやなあ。
とおっしゃっていますし、Material Design先輩はMotionのUsageに関する項で
- コンテンツの階層関係の説明
- ユーザ操作のフィードバックやユーザ操作に対する状態の表示
- 操作方法を示し、ユーザの学習を助ける
など、使いみちについてかなり具体的に例示しています。
実際、小難しい話をこねくり回す必要もなく、UIアニメーションを利用することで様々な情報を付加してユーザがアプリケーションを利用する手助けになることはとても理解しやすい話です。適切なUIアニメーションが適切に情報を画面表示することができれば、 ユーザの離脱を防いだり、アプリケーションに対するポジティブな感情を醸成して継続率を上げたりと、密かに数字につながっていたりということもあると思います。
それ以外にも特定のイージングやdurationを頻繁に利用することでアプリケーションのVisual Identityを構築する手助けをできれば、認知を強めたり、競合アプリケーションとの差別化を行う一助になるかもしれません。
UIアニメーションを実装するのは辛いし面倒くさい
とはいえUI実装者の皆様は思うところがあるのではないかと存じますが、UIアニメーションを作り込むのは非常に気だるい作業になることが多いと思います。
CSS TransitionやCSS Animationを利用して実装する際は、この書き方で動くだろう!と思って動かしたら、アニメーションが効いてなかったり、行きの動作はするが戻りの動作がしなかったり(なんか思たんとちゃう…)といった気持ちになる経験はありませんか?
そういったツラミな状態になったとしても、CSSではデバッグをするのも難しく、一度悩み始めると無限に時間が溶ける原因になりがちです。(console.log
するとなぜか動くのに、消すと動かなくなったりすると終業意欲がMAXになったりしますよね)また、せっかくUIアニメーションをコンポーネント志向にパッケージングしたのに、使う際に特定のスタイルを付与する必要があったり、逆に特定のスタイルをつけてはならない、などの使い方の制約があると、忘れたり知らなかったりしたときにドツボにハマりがちです。
UIアニメーションを実装するときは再利用性が重要
こうしてUIアニメーション実装に対する心理的障壁が高くなると、
- 部分的にUIからアニメーションが消失していく
- 機能実装の見積もりや実績が膨らんでしまい、逆にアプリケーションのイテレーション計画を阻害する
など、UIアニメーションを実装するメリットを打ち消して有り余るデメリットが発生します。
UIアニメーションを実装する際に(おもたんとちゃう…)という気持ちになる状況は開発ツール側の進化がないと当分解決出来ないと思うので(いい方法あるよという方コメントで教えて下さい!)一旦あきらめるとして、いざ作ったアニメーションを再度使うときに(使い方わからん…)となるのは時間の無駄ですし、逆に再利用しやすいUIアニメーションのコンポーネントを用意できれば、効率的に各所でUIアニメーションを実装できますし、効率よく価値を提供することに繋がります。
なので、UIアニメーションを実装するときは実装されたアニメーションがイケてるかだけではなく、再利用するときに悩まずに使えるか・想像した通りに使えるかも重視すべきです。
Vueでは公式に<transition>
や<transition-group>
が提供されており、これらを使ってうまくパッケージングすることでこれを実現することができます。
次の項から具体的にtransitionコンポーネントを作っていきます。本題
よくペラペラ説教をするおじさんみたいなことばかり喋ってしまってごめんなさい。作ります。
縦にたたむとはどういうことか
そもそもcss transitionで縦にたたむ動作をするためには、たたむ対象となるコンポーネントのstyleに
.target { overflow: hidden; transition: height; }を当てることでできそうだというのはすぐに思い浮かぶと思います1。
しかし、たたむ対象のコンポーネントのoverflowを直接いじると、overflowを自身で設定しているコンポーネントで表示は壊れることが容易に想像できますし、heightをいじるとなれば、レイアウトを高さに対する相対指定で行っていたり、縦flex・gridを利用している場合に崩れるでしょう。
transitionを作ることに関しては、なるべく使うときに考えたり悩んだりしないで使えるものを作るという上記の指針があるので、今回は下図のように
overflow: hidden; transition: height;
だけの表示領域を区切るためだけのラッパーを用意し、縦にたたむスタイルを実装していきます。どういうものを作るか
Vueのtransitionはslotの中に入るコンポーネントが
v-if
orv-show
が切り替わったときにtransitionが発生するというインターフェースになっています。今回作るtransitionもこのインターフェースに沿った形で、<template> <vertical-collapse-transition> <p v-if="show">lorem ipsum...</p> </vertical-collapse-transition> </template> <!-- OR --> <template> <vertical-collapse-transition> <p v-show="show">lorem ipsum...</p> </vertical-collapse-transition> </template>上記のような使い方ができるものを作ります。
内部的なラッパーをどうするか
疑似コードですが、
<template> <transition name="vertical-collapse"> <div style="overflow: hidden; transition: height;"> <slot /> </div> </transition> </template>のようなtransitionコンポーネントを作ってしまうと、
slot
のv-if
やv-show
を変更しても、transition
から見て子コンポーネントの表示が変わっていないように見えるので、transitionが発火しません。こういうときどうすればよいかというと、VNodeを直接触って
slot
の表示状態をラッパーにプロキシしてあげればよいです。実際に表示状態で取りうるパターンとしては4種類あり、
v-if="true"
v-if="false"
v-show="true"
v-show="false"
のどれかになります。
これらの場合にどういったVNodeがslotsに入ってくるかの明確な仕様はドキュメントに特に明記されてなかったので、ぼんやりしたイメージはありましたが実際にconsole.log
して中身を見ていきました。1.
v-if="true"
v-ifはそもそもVNodeを仮想DOMツリーに入れるか入れないかを制御するディレクティブなので、
v-if="true"
の場合はシンプルにslotのVNodeが入ってきます。{ render(h) { const child = this.$slots.default && this.$slots.default[0]; console.log(child); // VNode { tag: "div", ...} } }2.
v-if="false"
一を聞いて十を知る皆さんであれば、仮想DOMツリーに入れないので
undefined
とかnull
的なやつが来るのではないかと想像がついていると思います。正解です。{ render(h) { const child = this.$slots.default && this.$slots.default[0]; console.log(child); // undefined } }ですが、template compiler次第なのか、下記のようなパターンもありました。2
{ render(h) { const child = this.$slots.default && this.$slots.default[0]; console.log(child); // VNode { tag: undefined, ...} } }2019/12/12 追記
空白しかないtext nodeの可能性が高いです。3.
v-show="true"
ディレクティブに関する情報
vnode.data.directives
に入ってきます。{ render(h) { const child = this.$slots.default && this.$slots.default[0]; console.log(child); // VNode { tag: "div", data: { directives: [{ // name: 'show', // value: true, // ... // }] }, ...} } }4.
v-show="false"
もちろん3と同じ構造で、valueが
false
になっているだけです。{ render(h) { const child = this.$slots.default && this.$slots.default[0]; console.log(child); // VNode { tag: "div", data: { directives: [{ // name: 'show', // value: false, // ... // }] }, ...} } }条件分岐
以上のVNodeの状態をそれぞれ区別して条件分岐しつつ、適切なラッパーを返してあげるとなると、下記のような感じになります。
{ render(h) { // transitionはもともとdefault slotの一個目の要素しか見ないインターフェースなので、ほかは捨ててよい const child = this.$slots.default && this.$slots.default[0]; // TODO: あとで中を実装する const generateTransitionComponent = (children) => h('transition', {}, children); const isEmpty = !child || child.tag === undefined; if (isEmpty) { // -------------- // v-if="false" // -------------- return generateTransitionComponent([]); // transitionの中を空で返す } const vShowDirective = child.data.directives && child.data.directives.find(directive => directive.name === 'show'); const isHidden = vShowDirective && !vShowDirective.value; if (isHidden) { // -------------- // v-show="false" // -------------- child.data.directives = [ // 子のv-showディレクティブを消す ...child.data.directives.filter( directive => directive.name !== 'show' ), ]; return generateTransitionComponent([ h( 'div', // h('div') でラッパーを作る { // ラッパーにv-showディレクティブを移植する directives: [ { name: 'show', value: false, }, ], }, [child] ), ]); } if (vShowDirective && !isHidden) { // -------------- // v-show="true" // -------------- return generateTransitionComponent([ h( 'div', { // ラッパーにv-show="true"をプロキシする directives: [ { name: 'show', value: true, }, ], }, [child] ), ]); } // -------------- // v-if="true" // -------------- // 特に何もせず、ラッパーに子をそのまま入れて返す return generateTransitionComponent([h('div', {}, [child])]); } }縦にたたむ
jsを使ってtransitionを作る場合は、cssのトランジションクラス(
v-enter
などのスタイルを定義するやり方)を利用するよりも、jsフックを使ったほうが圧倒的に自由度が高くておすすめです。とくに、使いやすいtransitionを作るにはtiming function
やduration
もpropsで渡せたほうが汎用的でベターですが、その場合はjsフックだとなおさら書きやすいです。transitionおよびjsフックの詳しい仕様はドキュメントを参照してください。
(宣伝:Vue.jsのドキュメントは有志のメンバーがとてもマメに翻訳を更新しているのでぜひ公式ドキュメントを読んでください!)
https://jp.vuejs.org/v2/guide/transitions.html方針としては
- 非表示 → 表示
beforeEnter
フックでラッパーのheight
を0
にするenter
フックでラッパーのheight
を子のscrollHeight
にする- 表示 → 非表示
beforeLeave
フックでラッパーのheight
を子のscrollHeight
にするenter
フックでラッパーのheight
を0
にするというシンプルなものです。
完成形
実際に上記を実装するとこんな感じになるかと思います。
components/transitions/VerticalCollapseTransition.vue<script> import Vue, { VNode } from 'vue'; export default { props: { duration: { type: Number, default: 100, }, easing: { type: String, default: 'ease-out', }, }, render(h) { // transitionはもともとdefault slotの一個目の要素しか見ないインターフェースなので、ほかは捨ててよい const child = this.$slots.default && this.$slots.default[0]; // transition要素を作る関数 const generateTransitionComponent = childrenOfTransition => h( 'transition', { on: { beforeEnter(el) { el.style.height = '0'; }, enter(el) { el.style.height = `${el.scrollHeight}px`; }, beforeLeave(el) { el.style.height = `${el.scrollHeight}px`; }, leave(el) { // このif文がないと初回の非表示にtransitionがかからない(謎) // タイミング問題だと思われる if (el.scrollHeight !== 0) { el.style.height = '0'; } }, }, }, childrenOfTransition ); const wrapperData = { // ラッパーに常時ついているスタイル style: { overflow: 'hidden', transition: `height ${this.easing} ${this.duration}ms`, }, }; const isEmpty = !child || child.tag === undefined; if (isEmpty) { // -------------- // v-if="false" // -------------- return generateTransitionComponent([]); // transitionの中を空で返す } const vShowDirective = child.data.directives && child.data.directives.find(directive => directive.name === 'show'); const isHidden = vShowDirective && !vShowDirective.value; if (isHidden) { // -------------- // v-show="false" // -------------- child.data.directives = [ // 子のv-showディレクティブを消す ...child.data.directives.filter( directive => directive.name !== 'show' ), ]; return generateTransitionComponent([ h( 'div', // h('div') でラッパーを作る { ...wrapperData, // ラッパーにv-showディレクティブを移植する directives: [ { name: 'show', value: false, }, ], }, [child] ), ]); } if (vShowDirective && !isHidden) { // -------------- // v-show="true" // -------------- return generateTransitionComponent([ h( 'div', { ...wrapperData, // ラッパーにv-show="true"をプロキシする directives: [ { name: 'show', value: true, }, ], }, [child] ), ]); } // -------------- // v-if="true" // -------------- // 特に何もせず、ラッパーに子をそのまま入れて返す return generateTransitionComponent([h('div', wrapperData, [child])]); }, }; </script>エッジケースの処理はまだ足りていないかもしれませんが、自分のプロジェクトではこの実装が活躍してくれています。
まとめ
今回は弊リポジトリの中でも一番複雑なトランジションコンポーネントを開陳してみました。他にもフェードしたりスライドしたりと多種多様なコンポーネントがありますが、どれももっとシンプルな実装になっています。
皆様もトランジションコンポーネントを美しく共通化して、きれいなソースコードのまま、素敵なアニメーションのアプリケーションを実装していけることをお祈り申し上げます。
ぼやき
transition-group
のコンポーネント化はマジでつらい
- 投稿日:2019-12-11T01:47:31+09:00
立方体を描画してみよう!CSSだけで3D表現【フロントエンド】
はじめに
今回は,WebGL等を使わないで,単純な3DオブジェクトをCSSだけで描画する方法についてご紹介しようと思います.
CSSでの3D表現の特徴
確かに複雑なオブジェクトを作るのであれば,WebGLを使うのが好ましいでしょう.
しかし,CSSでやる良さもあるので,主なメリットとデメリットを以下に記述します.
CSSで3Dをやるメリット
- 直感的に作れる.
- イベントなどを設定しやすい.
- 見た目をCSSで簡単に変更できる.
CSSで3Dをやるデメリット
- 複雑な立体は作るのが大変.
- 曲線のある立体は作るのが難しい.
- 複雑なものを作ると時間が溶ける.
立方体のサンプル
See the Pen 3D Box by AO2324 (@AO2324) on CodePen.
円柱のサンプル
See the Pen 3D Cylinder by AO2324 (@AO2324) on CodePen.
クリックイベントをつけた立体のサンプル
See the Pen 3D Box has event by AO2324 (@AO2324) on CodePen.
使用するCSSプロパティ
transform-style
transform
perspective
transform-style (描画形式)
子要素の変形を立体的に描画するか平面的に描画するかを指定します.
平面的(初期設定)transform-style:flat;立体的transform-style:preserve-3d;See the Pen 3D Box (Flat / 3d ) by AO2324 (@AO2324) on CodePen.
transform (要素の移動や回転)
transform
プロパティを使用することで,要素を平行移動や回転,拡大など,変形させることができます.指定方法は,
transform
の後にどう変形させるかを続けて記述します.
例transform: 変形1 変形2;
変形の書き方
変形の種類+基本とする軸(値)
- 変形の種類
translate
: 平行移動rotate
: 回転scale
: 大きさskew
: 傾斜- 基本とする軸
X
: x軸Y
: y軸Z
: z軸- なし : ()の中にx軸とy軸をカンマ(,)で区切って表記
3d
: ()の中にx軸とy軸とz軸をカンマ(,)で区切って表記サンプルtransform: translateX(50px) translateY(100px) rotateZ(90deg); /* x軸方向に50px,y軸方向に100px平行移動したのち,z軸を中心に90度回転 */ transform: translate(50vw, 50vh); /* x軸方向に50vw,y軸方向に50vh平行移動 */perspective (遠近感)
3Dのオブジェクトに遠近感をもたせます.
数値が小さいほど魚眼レンズのようになり,大きければ大きいほど全ての幅が均等になります.
perspective:200px;
perspective:10000px;
数値が小さい(200px)と上のような見え方に,数値が大きい(10000px)と下のような見え方になります.
個人的には 800px ~ 1000px くらいがちょうどいい気がします.
perspective:1000px;
実際に立方体を作ってみよう!
Step1
まず,HTMLで立体の面となる要素を定義してあげます.
html<div id="scene"> <div class="boxBase"> <div class="top"></div> <div class="bottom"></div> <div class="front"></div> <div class="back"></div> <div class="left"></div> <div class="right"></div> </div> </div>ここで,
scene
は3Dオブジェクトを表示する場所,boxBase
は立方体,その中の要素は立方体のそれぞれの面を表しています.
これをCSSのtransform
を使って変形することで,ペーパークラフトのように立体を作ることができます.Step2
何も指定しないと平面的に描画してしまうので,
transform-style:preserve-3d;
をboxBaseに設定して,子要素を立体的に表示するようにしてあげましょう.
ここで,一辺の長さも決めてしまいましょう.css(1/4).boxBase { transform-style:preserve-3d; width:200px; height:200px; }Step3
立方体の面となる要素の設定を行い,ついでに色や縁にもスタイルを適応させましょう.
css(2/4).boxBase > div { position:absolute; width:100%; height:100%; background-color:rgba(100, 100, 100, 0.7); /* 面の色 */ border:0.5px solid black; /* 縁 */ }Step4
それぞれの面を変形して,立方体を組み立てていきましょう.
css(3/4).boxBase > .top { transform:translateY(100px) rotateX(-90deg); } .boxBase > .bottom { transform:translateY(-100px) rotateX(90deg); } .boxBase > .front { transform:translateZ(100px); } .boxBase > .back { transform:translateZ(-100px) rotateX(180deg); } .boxBase > .left { transform:translateX(-100px) rotateY(-90deg); } .boxBase > .right { transform:translateX(100px) rotateY(90deg); }Step5
perspective
で遠近感を調整しましょう.css(4/4)#scene { perspective: 1000px; }立方体の完成
立方体(htmlファイル)<div id="scene"> <div class="boxBase"> <div class="top"></div> <div class="bottom"></div> <div class="front"></div> <div class="back"></div> <div class="left"></div> <div class="right"></div> </div> </div> <style> #scene { perspective: 1000px; } .boxBase { transform-style:preserve-3d; width:200px; height:200px; } .boxBase > div { position:absolute; background-color:rgba(100, 100, 100, 0.7); border:0.5px solid black; width:100%; height:100%; } .boxBase > .top { transform:translateY(100px) rotateX(-90deg); } .boxBase > .bottom { transform:translateY(-100px) rotateX(90deg); } .boxBase > .front { transform:translateZ(100px); } .boxBase > .back { transform:translateZ(-100px) rotateX(180deg); } .boxBase > .left { transform:translateX(-100px) rotateY(-90deg); } .boxBase > .right { transform:translateX(100px) rotateY(90deg); } </style>アニメーションをつけてあげると立体になっている事がよくわかるので,ぜひ試してみてください.
立方体のアニメーション#scene { perspective: 1000px; width:200px; height:200px; position:relative; top:50vh; left:50vw; transform:translateX(-50%) translateY(-50%); } .boxBase { transform-style:preserve-3d; width:200px; height:200px; animation: turnAround 30s linear 0s infinite normal none running; } @keyframes turnAround { 0%{ transform:rotateX(0deg) rotateY(0deg); } 100%{ transform:rotateX(360deg) rotateY(360deg); } }See the Pen 3D Box by AO2324 (@AO2324) on CodePen.
最後に
今回はCSSでの3D表現のざっくりとした説明と,簡単な立体の作り方を書かせていただきました.
これだけだと,実際のWebページやアプリ開発でどのように活かせるかわからないかもしれません.
ですが,発想次第ではいろいろな事ができるので,ぜひCSSでもっともっと遊んでみてください.
↑人型の立体物 ↓Webサイトのナビゲーション
参考
- 投稿日:2019-12-11T00:18:53+09:00
大人数の時使うオーバーレイのカスタムCSS
大人数の時使うオーバーレイのカスタムCSS
大規模コラボ用のカスタムCSSを作ってみました
手っ取り早くほしい人は一番下の方の使い方まで飛んでくださいね元のCSSがあるのでURL貼りますね
順風満帆丸さんの萬巓堂本店の
「DISCORDで喋ってる人を分かり易くするカスタムCSS」http://manten-do.net/contents/dsk01
をヒントに作りましたDiscord STREAMKIT Overlayを使ってカスタムCSSで変更を加えているんですね
なのでCSSを変えれば色々変えれるんです実は 100人記念コラボしたときに自分含めて5人でお話ししたときに思ったのは
「IDと立ち絵登録面倒・・・」
凸に入る時に
「まって、今登録してるから」っていって待ってもらわなきゃいけなかったのでテンポが悪かったです
オーバレイの内容をCSSで変えて見やすくできる他の方法がないか考えてみますまず目標を定めます
1 上のカスタムCSSみたいに光ってぴょこぴょこはそのまま
2 ID登録とかちょっと今回はやらないようにする
3 いつもの小さい縦じゃなくて大きく横に並べるようにする
4 名前もできれば表示1ぴょこぴょこはそのまま
ぴょこぴょことかは前回買い換えたものがあるのでそれをそのままコピペします
どういう動きをするかというと
しゃべると光る(正確には暗かったものが普通になる)しゃべると5秒間ぴょこぴょこ動く2ID登録とか今回はやらない
今回は個人を特定することはしないのでユーザーID(#と数字のタグとは別)と画像を登録しないのでごっそり省きます
3大きく横に並べる
今回はアイコンを200×200で表示しますのでavatarの縦と横を変えます
線とか明るさは変えないです
そして!ここ重要!
リストの li.voice-state のCSSに display:inline-block; を追加します
これは簡単に言うと 「リストを縦から横に変える」 ってことです
やったよ・・・これで横に並ぶよ・・・4名前を表示する
普通に表示させるとなんかごちゃごちゃしちゃいます
もう、大変だった
ずっとコレジャナイあれじゃないトライ&エラーです
分かったと思ったら違って違うと思ったら近づいて・・・目がしょぼしょぼするよ
面倒ですので結論と専門的なのは簡潔にだけできました
display: inline-block;で横に並べて
position: relativeで移動させて・・・出来たつまり何がいいたいかというと
一日かけて恐ろしく大変で疲れた!!!!
その結晶をここに乗せます
もし名前を消したいときは
span.nameの{}の中身を
{display:none;}
に変えてくださいね
none;で消すって意味です使い方
1 DiscordSTREAMKITOverlayのURLをOBSのブラウザに入れる
2 ここの下のカスタムCSSをOBSのブラウザのカスタムCSS の欄にコピー&ペーストで入れる
3 ブラウザの大きさは縦を200に設定する。横はどこまでもOK
4 参加者はアイコンを透過されているバストアップの立ち絵に変えてもらう
5 通話参加者は名前付きでぴょこぴょこできるよ!というわけで完成したカスタムCSSです
大人数の雑談コラボや 大規模コラボゲーム配信などでどうぞ/*アバターの大きさと明るさを決めるよ あと線を消してるよ*/ .avatar { height:200px !important; width:200px !important; border-radius:0 !important; filter: brightness(70%); } /*しゃべったときの状態の設定してるよ*/ .speaking { border-color:rgba(0,0,0,0) !important; position:relative; animation-name: speak-now; animation-duration: 5000ms; animation-fill-mode:forwards; filter: brightness(100%) ; } /*しゃべってるときのアニメーションの設定だよ*/ @keyframes speak-now { 0% { bottom:0px; } 5% { bottom:10px; } 10% { bottom:0px; } 15% { bottom:10px; } 20% { bottom:0px; } 25% { bottom:10px; } 30% { bottom:0px; } 35% { bottom:10px; } 40% { bottom:0px; } 45% { bottom:10px; } 50% { bottom:0px; } 55% { bottom:10px; } 60% { bottom:0px; } 65% { bottom:10px; } 70% { bottom:0px; } 75% { bottom:10px; } 80% { bottom:0px; } 85% { bottom:10px; } 90% { bottom:0px; } 95% { bottom:10px; } 100% { bottom:0px; } } /* アバター及びネームタグ表示位置調整だよ*/ li.voice-state{ position: static; display: inline-block; width: 200px; height: 200px; } .user{ display: inline-block; } span.name{ display: inline-block; position: relative; bottom: 70px; } /* 色々消すヤツ */ body { background-color: rgba(0, 0, 0, 0); overflow: hidden; } /******カスタムCSS終わり******/```
- 投稿日:2019-12-11T00:18:53+09:00
大人数の配信時使うDiscordStreamKitOverlayのカスタムCSS
大人数の時使うオーバーレイのカスタムCSS
大規模コラボ用のカスタムCSSを作ってみました
手っ取り早くほしい人は一番下の方の使い方まで飛んでくださいね元の記事
あるCSSがあってそれを使っていました
順風満帆丸さんの萬巓堂本店の
「DISCORDで喋ってる人を分かり易くするカスタムCSS」
http://manten-do.net/contents/dsk01
です。
Discord STREAMKIT Overlayを使ってカスタムCSSで変更を加えているんですね
なのでCSSを変えれば色々変えれるんです経緯
実は、自分のチャンネルで100人記念で配信した時に自分含めて5人でお話しする機会がありました。その時に思ったのは
「IDと立ち絵登録面倒・・・」
凸に入る時に
「まって、今登録してるから」っていって待ってもらわなきゃいけなかったのでテンポが悪かったです上のCSSは
・出演者が決まっている
・画面のいろんなところに配置する必要がある
・立ち絵全部見せたい
時に真価を発揮するものだと思うのですなので今回の雑談みたいに
・通話チャンネルに出たり入ったりする
・別にバラバラじゃなくて横並びでいい
・顔だけ出しておけばいい
っていうときは使い勝手が悪いわけですなので
カスタムCSSの内容を変えて見やすくできる他の方法がないか考えてみますまず目標を定めます
1 上のカスタムCSSみたいに光ってぴょこぴょこはそのまま
2 ID登録とかちょっと今回はやらないようにする
3 いつもの小さい縦じゃなくて大きく横に並べるようにする
4 名前もできれば表示1ぴょこぴょこはそのまま
ぴょこぴょことかは前回買い換えたものがあるのでそれをそのままコピペします
どういう動きをするかというと
しゃべると光る(正確には暗かったものが普通になる)しゃべると5秒間ぴょこぴょこ動く2ID登録とか今回はやらない
今回は個人を特定することはしないのでユーザーID(#と数字のタグとは別)と画像を登録しないのでごっそり省きます
3大きく横に並べる
今回はアイコンを200×200で表示しますのでavatarの縦と横を変えます
線とか明るさは変えないです
そして!ここ重要!
リストの li.voice-state のCSSに display:inline-block; を追加します
これは簡単に言うと 「リストを縦から横に変える」 ってことです
やったよ・・・これで横に並ぶよ・・・4名前を表示する
普通に表示させるとなんかごちゃごちゃしちゃいます
もう、大変だった
ずっとコレジャナイあれじゃないトライ&エラーです
分かったと思ったら違って違うと思ったら近づいて・・・目がしょぼしょぼするよ
面倒ですので結論と専門的なのは簡潔にだけできました
display: inline-block;で横に並べて
position: relativeで移動させて・・・出来たつまり何がいいたいかというと
一日かけて恐ろしく大変で疲れた!!!!
その結晶をここに乗せます
もし名前を消したいときは
span.nameの{}の中身を
{display:none;}
に変えてくださいね
none;で消すって意味です使い方
1 DiscordSTREAMKITOverlayのURLをOBSのブラウザに入れる
2 ここの下のカスタムCSSをOBSのブラウザのカスタムCSS の欄にコピー&ペーストで入れる
3 ブラウザの大きさは縦を200に設定する。横はどこまでもOK
4 参加者はアイコンをグリーンバックされているバストアップの立ち絵に変えてもらう
5 通話参加者は名前付きでぴょこぴょこできるよ!というわけで完成したカスタムCSSです
大人数の雑談コラボや 大規模コラボゲーム配信などでどうぞおすすめしたい方々
・オンラインで通話をつなげながらする大人数のゲーム配信をする方
・ボイスチャンネルに人が出たり入ったりしながらする大人数の雑談配信の方
・少人数配信だけど立ち絵の用意・配置が面倒な方
ぜひ/*アバターの大きさと明るさを決めるよ あと線を消してるよ*/ .avatar { height:200px !important; width:200px !important; border-radius:0 !important; filter: brightness(70%); } /*しゃべったときの状態の設定してるよ*/ .speaking { border-color:rgba(0,0,0,0) !important; position:relative; animation-name: speak-now; animation-duration: 5000ms; animation-fill-mode:forwards; filter: brightness(100%) ; } /*しゃべってるときのアニメーションの設定だよ*/ @keyframes speak-now { 0% { bottom:0px; } 5% { bottom:10px; } 10% { bottom:0px; } 15% { bottom:10px; } 20% { bottom:0px; } 25% { bottom:10px; } 30% { bottom:0px; } 35% { bottom:10px; } 40% { bottom:0px; } 45% { bottom:10px; } 50% { bottom:0px; } 55% { bottom:10px; } 60% { bottom:0px; } 65% { bottom:10px; } 70% { bottom:0px; } 75% { bottom:10px; } 80% { bottom:0px; } 85% { bottom:10px; } 90% { bottom:0px; } 95% { bottom:10px; } 100% { bottom:0px; } } /* アバター及びネームタグ表示位置調整だよ*/ li.voice-state{ position: static; display: inline-block; width: 200px; height: 200px; } .user{ display: inline-block; } span.name{ display: inline-block; position: relative; bottom: 70px; } /* 色々消すヤツ */ body { background-color: rgba(0, 0, 0, 0); overflow: hidden; } /******カスタムCSS終わり******/19/12/11追記
「配信の時自分はFacerigとかで動いてるからオーバーレイに自分が居たら困る・・・」
と言われたのです
ID使うから最初のコンセプトとは外れますが
もし自分のことを消したい方は/* 選択したユーザの画像を非表示にする */ li.voice-state[data-reactid$="ここにじぶんのID"] { display:none; }を先頭に追加してください
そして「ここにじぶんのID」のところをDiscrdの自分のIDにしてくださいちなみに
IDの出し方は
歯車マークの「ユーザー設定」→「テーマ」→「詳細設定」にある「開発者モード」をオンにしてIDを取得したいユーザーを右クリック
「IDをコピー」でIDとなる数字の羅列をコピーできます
(技術者さんは当たり前にわかるかもですが 私の場合、技術者さん以外も見る可能性がありますのでご容赦ください)