tag:crieit.net,2005:https://crieit.net/tags/HTML/feed 「HTML」の記事 - Crieit Crieitでタグ「HTML」に投稿された最近の記事 2024-02-08T01:37:05+09:00 https://crieit.net/tags/HTML/feed tag:crieit.net,2005:PublicArticle/18734 2024-02-08T01:37:05+09:00 2024-02-08T01:37:05+09:00 https://crieit.net/posts/D-D-QR D&DしたQRコード画像をブラウザ上でデコードする <p>ブラウザ上にドラッグ&ドロップ (D&D) されたQRコードの画像を、読み込んでデコードするUIを作りたい。</p> <p>Pure JavaScript で動作する、QR コードデコーダー(パーサー) <a target="_blank" rel="nofollow noopener" href="https://github.com/cozmo/jsQR">cozmo/jsQR</a> が有名なので、これを使ってみよう。</p> <p>jsQR は、 png や jpg といった画像コンテナの解凍機能も、 HTML や DOM, Web 周りに特化した機能も一切無いため、読み込ませた画像は何らかの方法で <code>Uint8ClampedArray</code> な RAW 画像に変換して渡す必要がある。</p> <p>ちょっと遠回りにはなるが、</p> <ol> <li>D&D されたファイルの <a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/en-US/docs/Web/API/File_API">File API</a> を読み取る</li> <li><a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/API/FileReader">FileReader API</a> を使って、ファイルを DataURI として読み込ませ、 img タグに表示させる</li> <li><a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas">OffscreenCanvas</a> と <a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvasRenderingContext2D">OffscreenCanvasRenderingContext2D</a> を経由して <a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/en-US/docs/Web/API/ImageData">ImageData</a> を作成する</li> <li>jsQR に処理を投げる</li> </ol> <p>といった処理になるだろうか。</p> <p>早速実装してみよう。</p> <h2 id="実装"><a href="#%E5%AE%9F%E8%A3%85">実装</a></h2> <pre><code class="html"><div id="divDrop" style="margin: 10px; padding: 10px; background-color: lightgray; border: 4px dashed gray; border-radius: 12px;"> <div>Drag and drop an image file here</div> <div>or <input id="iptFile" type="file" accept="image/*"></div> <div id="divPreviewContainer"></div> </div> <div style="margin: 10px; padding: 10px;"> <input type="text" id="iptResult" style="width: 600px"> <div id="divErrorOut" style="display: none; margin: 4px; padding: 4px; background-color: pink; border: 1px solid red; border-radius: 4px;"></div> </div> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jsQR.min.js"></script> <script type="text/javascript"> // @ts-check (() => { "use strict"; const divDrop = /** @type {HTMLDivElement} */(document.getElementById("divDrop")); const divPreviewContainer = /** @type {HTMLDivElement} */(document.getElementById("divPreviewContainer")); const divErrorOut = /** @type {HTMLDivElement} */(document.getElementById("divErrorOut")); const iptFile = /** @type {HTMLInputElement} */(document.getElementById("iptFile")); const iptResult = /** @type {HTMLInputElement} */(document.getElementById("iptResult")); /** @type { (file: File) => Promise<any> } */ async function decodeQrCode(file) { divErrorOut.style.display = "none"; try { // read ile const fileReader = new FileReader(); const fileReadAsync = new Promise((resolve, reject) => { fileReader.onload = ev => resolve(ev.target?.result); fileReader.onerror = ev => reject(ev); }); fileReader.readAsDataURL(file); /** @type {string} */ const dataUrl = await fileReadAsync; // load as image divPreviewContainer.innerHTML = ""; const imgPreview = document.createElement("img"); const imgLoadAsync = new Promise(resolve => imgPreview.onload = ev => resolve(ev)) imgPreview.setAttribute("src", dataUrl); divPreviewContainer.append(imgPreview); await imgLoadAsync; const { naturalWidth, naturalHeight } = imgPreview; // convert image to raw binary var canvas = new OffscreenCanvas(naturalWidth, naturalHeight); var ctx = canvas.getContext("2d"); if (!ctx) throw "failure to getContext"; ctx.drawImage(imgPreview, 0, 0); const imageData = ctx.getImageData(0, 0, naturalWidth, naturalHeight); // decode with jsQR const code = jsQR(imageData.data, naturalWidth, naturalHeight); if (code) { iptResult.value = code.data; } else { iptResult.value = ""; throw "decode QR error"; } } catch (err) { divErrorOut.style.display = "block"; divErrorOut.textContent = `${err}`; } } // Handling D&D divDrop.addEventListener("dragover", ev => { ev.preventDefault(); }); divDrop.addEventListener("drop", ev => { ev.preventDefault(); let imageFiles; if (ev.dataTransfer && 0 < (imageFiles = [...ev.dataTransfer.files].filter(f => f.type.startsWith("image/"))).length) { const dt = new DataTransfer(); imageFiles.forEach(f => dt.items.add(f)); iptFile.files = dt.files; decodeQrCode(imageFiles[0]); } }); iptFile.addEventListener("change", ev => iptFile.files && 0 < iptFile.files.length ? decodeQrCode(iptFile.files[0]) : undefined) })(); </script> </code></pre> <p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="GReBXOM" data-user="advanceboy" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;"> <span>See the Pen <a target="_blank" rel="nofollow noopener" href="https://codepen.io/advanceboy/pen/GReBXOM"> decode D&Ded QR images</a> by advanceboy (<a target="_blank" rel="nofollow noopener" href="https://codepen.io/advanceboy">@advanceboy</a>) on <a target="_blank" rel="nofollow noopener" href="https://codepen.io">CodePen</a>.</span> </p> <p>いったん img タグで画像を表示させるワンクッションを置いているおかげで、 png, jpg のみならず svg 等の画像もデコードできるようになっている。</p> <p>Edge や Chrome ブラウザであれば、表示されている画像をそのまま D&D してきてのデコードもできるぞ。</p> <p><a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2024/02/decode-drag-and-droped-qr-image-01.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2024/02/decode-drag-and-droped-qr-image-01-1024x564.png" alt="" /></a></p> <p>jsQR の処理は、 JavaScript のスレッドで行われるので、処理が重くなるとブラウザが固まってしまう。<br /> このため、理想的には Web Worker に処理を渡してしまうほうがよさそうではある。</p> <p>ただ、1000x1000ピクセル程度の画像であれば、近年のデバイスなら一瞬でデコードできるので、実際のところはメインスレッド側で処理してしまって問題ないだろう。</p> advanceboy tag:crieit.net,2005:PublicArticle/18733 2024-02-08T01:34:00+09:00 2024-02-08T01:35:45+09:00 https://crieit.net/posts/URL-65c3b0f86a9e2 ブラウザのタイトルや URL をコピーするブックマークレット【スマホ&阿部寛対応】 <p>ブラウザで表示しているページのタイトルと URL を一括でコピーしたり、 markdown などのマークアップ言語でフォーマットされたものを、クリップボードにコピーしたくなることは無いだろうか?</p> <p>意外にも、主要なブラウザには表示ページのタイトル名すら簡単にコピーする方法がない。</p> <p>いくつかのブラウザ拡張機能(アドオン)には、上述の機能を提供しているものがいくつもある。<br /> しかし、これだけのために拡張機能を入れるのもなんだかなと。<br /> 場合によっては、ポリシー等様々な理由で拡張機能を入れることを制限されている場合もあるだろうし。</p> <p>そこで、表示中ページのタイトルと URL を任意の種類にフォーマットしてクリップボードへコピーしてくれるブックマークレットを作ってみた。</p> <p>ブックマークレットとした事により、拡張機能の使えないスマートフォンの Chrome や Safari といった、とても不便なブラウザでも利用できる。</p> <h2 id="使い方"><a href="#%E4%BD%BF%E3%81%84%E6%96%B9">使い方</a></h2> <p><a target="_blank" rel="nofollow noopener" href='javascript:(()=>{let e="FRAMESET"===top.document.body.tagName?top.frames[0].document:document,t=t=>e.getElementById(t),i=e.createElement("div"),l="modalBMId_key";i.innerHTML=%60<div id=${l}m style="position:fixed;width:100%;height:100%;top:0;text-align:center;background:rgba(0,0,0,.5);padding:16px 20px;z-index:999"><div style="display:inline-block;background:#fff"><div style="padding:8px"><div id=${l}b></div><div><label for=${l}i style="color:#000">copied:</label><input id=${l}i style="width:400px" readonly/></div></div></div></div>%60;let r=t(l+"m");r||(e.body.prepend(i.firstChild),Object.entries({TitleOnly:"<span>{</span><span>{</span>title<span>}</span><span>}</span>",Text:"<span>{</span><span>{</span>title<span>}</span><span>}</span>\n<span>{</span><span>{</span>url<span>}</span><span>}</span>",Markdown:String.raw%60[<span>{</span><span>{</span>title/\\/\\/(?=[\[\]])/\<span>}</span><span>}</span>](<span>{</span><span>{</span>url/\)/%2529<span>}</span><span>}</span>)%60,HTML:String.raw%60<a href="<span>{</span><span>{</span>url/&/&amp;/"/&quot;<span>}</span><span>}</span>"><span>{</span><span>{</span>title/</&lt;<span>}</span><span>}</span></a>%60,Textile:String.raw%60"<span>{</span><span>{</span>title/&/&amp;/"/&quot;/\]/&#93;<span>}</span><span>}</span>":<span>{</span><span>{</span>url/\]/%255D<span>}</span><span>}</span>%60,AsciiDoc:String.raw%60link:++<span>{</span><span>{</span>url<span>}</span><span>}</span>++[<span>{</span><span>{</span>title/\[/&#91;/\]/&#93;<span>}</span><span>}</span>]%60,Jira:String.raw%60[<span>{</span><span>{</span>title/&/&amp;/\[/&#91;/\]/&#93;/\|/&#124;<span>}</span><span>}</span>|<span>{</span><span>{</span>url/\[/%255B/\]/%255D/\|/%257C<span>}</span><span>}</span>]%60,LaTeX:String.raw%60\href<span>{</span><span>{</span>{url/\\/\backslash/(?=[&%$#_{}])/\<span>}</span><span>}</span>}<span>{</span><span>{</span>{title/\\/\backslash/(?=[&%$#_{}])/\<span>}</span><span>}</span>}%60}).map(([i,r])=>{let a=e.createElement("button");a.style.color="#000",a.textContent="copy - "+i,a.onclick=()=>{let i=r.replace(/<span>{</span><span>{</span>((title|url)(?:\/(.*?)\/(.*?))?(?:\/(.*?)\/(.*?))?(?:\/(.*?)\/(.*?))?(?:\/(.*?)\/(.*?))?)<span>}</span><span>}</span>/ig,function(t,i,l){let r="title"==l.toLowerCase()?e.title:location.href;for(let a=3;a<10;a+=2){let d=arguments[a];if(d&&"string"==typeof d)r=r.replace(RegExp(d,"g"),arguments[a+1]??"");else break}return r});navigator.clipboard.writeText(i),t(l+"i").value=i},t(l+"b").append(a)}),r=t(l+"m"),e.addEventListener("click",e=>{e.target==r&&r.remove()}))})();'>ブラウザのタイトルや URL をコピーするブックマークレット </a></p> <p>上記のリンクを(Firefox なら右クリックから直接、 Edge や Chrome なら ブックマークバーに D&D する等の方法で)ブックマークとして保存し、任意のページで呼び出すと、下記のようなダイアログが表示される。<br /> お好きなボタンをクリックすれば、クリップボードにフォーマット済みのリンクが格納されるという算段だ。</p> <p><a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2024/01/copy-formatted-link-bookmarklet-01.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2024/01/copy-formatted-link-bookmarklet-01-1024x82.png" alt="" /></a></p> <p>暗転したところをクリックすれば、ダイアログはクローズされる。</p> <p>最低限のコードにするため、 CSS は表示中のページのものを使っており、開いたページによってダイアログのデザインが変わるのは仕様となっている。</p> <p>Firefox, Chrome, Edge いずれでも動作することは確認している。<br /> Edge の場合ツールバーの「お気に入り☆」ボタンからではブックマークレットが動かないようなので、ブックマークバーから実行する必要があるようだ。(v121 現在)</p> <p>もちろん、「阿部 寛のホームページ」にも対応している。<br /> このようにフレームセットを使っている場合は、最初のフレームにダイアログを表示させる形で、対応している。</p> <p><a target="_blank" rel="nofollow noopener" href="https://aquasoftware.net/blog/wp-content/uploads/2024/01/copy-formatted-link-bookmarklet-02.png"><img src="https://aquasoftware.net/blog/wp-content/uploads/2024/01/copy-formatted-link-bookmarklet-02-1024x180.png" alt="" /></a></p> <h2 id="カスタマイズ方法"><a href="#%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA%E6%96%B9%E6%B3%95">カスタマイズ方法</a></h2> <p>既定で markdown, textile, LaTeX などいくつかのテンプレートを用意している。</p> <p>もし追加したいものがあれば、後述のソースコードの <code>Object.entries({</code>の後ろに、 JSON キーにボタンのタイトルを、 JSON 値に変換のテンプレートを指定したものを追加し、 各自 minify して使ってもらえれば OK だ。(ライセンスは CC-0)</p> <p>ソースコード中に <code>%5B</code>, <code>%5D</code> などといった URL エンコードと解釈できてしまう部分があるため、ブックマークの編集画面の URL に直接貼り付ける場合は、 <code>%255B</code>, <code>%255D</code> などとエスケープしておこう。</p> <p>なお、テンプレートの定義方法だが、 <code><span>{</span><span>{</span><span>}</span><span>}</span></code> で括った部分に <code>title</code> (ページタイトル) もしくは <code>url</code> と、 0~8 の偶数個の <code>/</code> を記述し、置換対象を表す正規表現と、置換後の文字列を交互に記述する。</p> <p>例えば、</p> <pre><code class="js">String.raw`<span>{</span><span>{</span>url/\[/%5B/\]/%5D/\|/%7C<span>}</span><span>}</span>` </code></pre> <p>なら、以下と等価となる。</p> <pre><code class="js">url.replace(RegExp(String.raw`\[`, "g"), "%5B") .replace(RegExp(String.raw`\]`, "g"), "%5D") .replace(RegExp(String.raw`\|`, "g"), "%7C"); </code></pre> <p>雑な説明だがわかって。</p> <gist src="https://gist.github.com/advanceboy/a960ec38442165a7df93408d775b03eb.js"></gist> advanceboy tag:crieit.net,2005:PublicArticle/18242 2022-07-16T15:21:02+09:00 2022-07-16T15:21:02+09:00 https://crieit.net/posts/HTML-JavaScript HTML + JavaScript: 見出しやボタンなどの表示文字列を統一させたいとき <p>とあるシステムに登場する複数のWEB画面のあいだで、見出しやボタンの表示文字列を統一させたい場合に、私が使う手法のひとつがこれです。<br /> いろんな方が、これと同じような手法をとられていると思います。かな?</p> <h2 id="サンプル"><a href="#%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB">サンプル</a></h2> <p>JavaScript側からです。これを各HTMLにインクルードして使います。</p> <pre><code>// JavaScript function label_print () { var arrVar = { label_lastname: "姓", label_firstname: "名", label_birthday: "生年月日", }; var arrVarButton = { button_save: "保存", button_cancel: "キャンセル", }; for (let key in arrVar) { if(document.getElementById(key) != null) { $('#' + key).html(arrVar[key]); } } for (let key in arrVarButton) { if(document.getElementById(key) != null) { $('#' + key).val(arrVarButton[key]); } } } </code></pre> <p>HTML側です。</p> <pre><code><!-- HTML --> ... <body class="" onload="label_print();"> ... <td class="label" style="white-space: nowrap;"> <div id="label_lastname"></div> </td> ... </code></pre> <p>サーバ・サイドで、データベースなどを用いて処理する手法もあったり、いろんな手法があっていずれも賛否両論だと思います。上記はレガシーで単純、必要なパーツも少なく取り回しが楽ですね。Simple is best.</p> COOL MAGIC PRODUCTS tag:crieit.net,2005:PublicArticle/17795 2021-11-29T20:59:12+09:00 2021-11-29T20:59:12+09:00 https://crieit.net/posts/input-checkbox-double-bracket-post-failed-20211129 input type="checkbox" の二重ブラケットについて <p>WordPress の自作プラグインで挙動不審なところが見付かり、そういえば……と思って input type="checkbox" の二重ブラケットについて調べてみました。</p> <p>調査した結果としては、自作プラグインのコードの書き方が悪かったので修正しました。</p> <h2 id="経緯・現象"><a href="#%E7%B5%8C%E7%B7%AF%E3%83%BB%E7%8F%BE%E8%B1%A1">経緯・現象</a></h2> <p>WordPress の自作プラグインでカスタムタクソノミーをチェックボックスで選択できる設定画面を作ってあったのですが、そこにチェックを入れてもデータが保存されない現象に遭遇。</p> <h3 id="コード"><a href="#%E3%82%B3%E3%83%BC%E3%83%89">コード</a></h3> <pre><code class="php"><?php require_once( ABSPATH . '/wp-admin/includes/template.php' ); class MyCategoryChecklistWalker extends \Walker_Category_Checklist { /** * var */ protected $c; protected $hidden_ids; /** * コンストラクタ */ function __construct( $c, $arrayTaxonomies ) { $this->c = $c; $this->hidden_ids = $arrayTaxonomies['id']; } /** * Start the element output. * * @see Walker::start_el() * * @since 2.5.1 * * @param string $output Used to append additional content (passed by reference). * @param object $category The current term object. * @param int $depth Depth of the term in reference to parents. Default 0. * @param array $args An array of arguments. @see wp_terms_checklist() * @param int $id ID of the current term. */ function start_el( &$output, $category, $depth = 0, $args = Array(), $id = 0 ) { extract( $args ); if( empty( $taxonomy )) { $taxonomy = 'category'; } if( $taxonomy == 'category' ) { $name = 'post_category'; } else { $name = 'tax_input[' . $taxonomy . ']'; } $class = in_array( $category->term_id, $popular_cats ) ? ' class="popular-category"' : ''; // 処理 $id = esc_attr( $name ) . '___term---' . esc_attr( $category->term_id ); $nameAttr = "name=\"{$i( 'myplugin_checkboxes' )}[{$id}]\""; // 処理 } } </code></pre> <p>設定画面は WordPress の Walker_Category_Checklist を継承したクラスで、チェックボックスの設定画面を作成していました。</p> <p>特に今回気になったのは次の部分。</p> <pre><code class="php"> else { $name = 'tax_input[' . $taxonomy . ']'; } </code></pre> <p>もう一つ。</p> <pre><code class="php"> $id = esc_attr( $name ) . '___term---' . esc_attr( $category->term_id ); $nameAttr = "name=\"{$i( 'myplugin_checkboxes' )}[{$id}]\""; </code></pre> <p>デフォルトのカテゴリーならば <code>post_category</code> という文字列を付与していますが、カスタムタクソノミーの場合は <code>tax_input[TAXONOMY_NAME]</code> とブラケットを使ってオブジェクトの記述にしていました。これをチェックボックスの <code>name</code> 属性に使用しています。その際に、複数選択可能なチェックボックスなのでさらに外側にブラケットが付くようにしていました。</p> <pre><code>name="myplugin_checkboxes[tax_input[TAXONOMY_NAME]___term---TERMID]" </code></pre> <p>こんな感じですね。ところが、このチェックボックスにチェックを入れても反映されない、となったわけです。</p> <p>いかにも二重にブラケットで括っているのが挙動不審の原因になっていそうな気がしたので、調査しました。</p> <h2 id="調査"><a href="#%E8%AA%BF%E6%9F%BB">調査</a></h2> <pre><code>a:XX:{s:26:"post_category___term---154";i:1;s:26:"post_category___term---165";i:1;s:26: /* 略 */ i:1;s:32:"tax_input[TAXONOMY_NAME";i:1;} </code></pre> <p>データベースで該当するキーを確認すると……やはり、二重ブラケットになった値を入れるところでシリアライズされたデータのフォーマットが崩れています。</p> <h2 id="検証"><a href="#%E6%A4%9C%E8%A8%BC">検証</a></h2> <p>そこで簡単なコードを作成。</p> <pre><code class="html"><!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>input</title> </head> <body> <form action="./test.php" method="post"> <label for="input"> <input type="checkbox" name="input[hoge[fuga]]" id="input" value="1"> インプット </label> <button type="submit">送信</button> </form> </body> </html> </code></pre> <p>二重ブラケットのチェックボックスを用意して POST するだけの簡単なフォームです。</p> <pre><code class="php"><!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>result</title> </head> <body> <pre><code> <?php var_dump($_SERVER); ?> </code></pre> <pre><code> <?php var_dump($_REQUEST); ?> </code></pre> </body> </html> </code></pre> <p>テストなのでエスケープとか一切していないですが、これで出力を確認。</p> <pre><code>array (size=1) 'input' => array (size=1) 'hoge[fuga' => string '1' (length=1) </code></pre> <p>思った通り、二重ブラケットのキーが途中で壊れてしまっています。 DB の中でシリアライズが崩れたデータと同じ状態です。</p> <p>これで二重ブラケットがNGであることが分かったのでコードを修正します。</p> <h2 id="修正"><a href="#%E4%BF%AE%E6%AD%A3">修正</a></h2> <pre><code class="php"> else { // $name = 'tax_input[' . $taxonomy . ']'; $name = $taxonomy; } </code></pre> <p>今回は独自のパース処理でタームのチェックを判断しているので、 <code>tax_input</code> の配列名は不要でした。そこで、タクソノミー名をそのまま <code>$name</code> に渡すように修正を加えました。</p> <pre><code class="php"> $id = esc_attr( $name ) . '___term---' . esc_attr( $category->term_id ); $nameAttr = "name=\"{$i( 'myplugin_checkboxes' )}[{$id}]\""; </code></pre> <p>それを使ってチェックボックスを出力する部分や他の部分は一切触らず。これで動作OKを確認しました。</p> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://developer.wordpress.org/reference/classes/walker_category_checklist/">Walker_Category_Checklist | Class | WordPress Developer Resources</a></li> </ul> arm-band tag:crieit.net,2005:PublicArticle/17380 2021-06-09T23:40:35+09:00 2021-06-09T23:54:06+09:00 https://crieit.net/posts/CSS-60c0d2e3d02be CSSの基礎勉強 <h2 id="CSSの基礎文法"><a href="#CSS%E3%81%AE%E5%9F%BA%E7%A4%8E%E6%96%87%E6%B3%95">CSSの基礎文法</a></h2> <ul> <li>HTMLにstyleタグを記述する</li> </ul> <pre><code class="HTML"><style> h1 { color: red; } </style> </code></pre> <ul> <li>HTMLのタグの中にstyle属性を記述する</li> </ul> <pre><code class="HTML"> <p style="color: green;">あいうえお</p> </code></pre> <ul> <li>styleの継承:HTMLタグの親要素を指定してスタイルを記述した場合、子要素にもそのスタイルが受け継がれる。</li> </ul> <pre><code class="HTML"> <body> <h1>あいうえお</h1> <p>aiueo</p> </body> </code></pre> <pre><code class="CSS"> body {color:green; font-size:20px;} </code></pre> <p>bodyのスタイルが、その子要素(h1, p)に継承される。</p> <pre><code>あいうえお <p style="color: green; font-size:20px;">aiueo</p> </code></pre> <ul> <li>デフォルトでは、継承されないスタイルを継承されるようにするには、子要素のスタイルにinheritを指定する。</li> </ul> <pre><code class="CSS"> h1 { border: inherit; } </code></pre> <ul> <li>class属性を使ったスタイリング。CSSのセレクターで、.class名とする。</li> </ul> <pre><code class="HTML"> <p class="hoge"> こんにちは</p> </code></pre> <pre><code class="CSS"> .hoge { color:green; } </code></pre> <h3 id="ボックスモデル"><a href="#%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9%E3%83%A2%E3%83%87%E3%83%AB">ボックスモデル</a></h3> <p>HTMLの要素は全て<strong>ボックス</strong>という四角い領域を生成する。ボックスは大きくわけて、<strong>インライン</strong>と<strong>ブロック</strong>に分けられる。</p> <ul> <li><p><strong>インラインボックス</strong>:span,a,em,strong,imgといったタグで指定した要素は、インラインボックスを生成する。要素は、上下に並んでいく。インラインボックスでは、<code>width</code>や<code>height</code>を指定できない(置換要素と呼ばれるimg,input,textareaは指定できる)、上下の<code>margin</code>を指定できないという特徴がある。</p></li> <li><p><strong>ブロックボックス</strong>:table,h1,p,div,ul,liなどのタグで指定した要素はブロックボックスを生成する。要素は左に詰めて並んでいく。ブロックボックスでは、<code>width</code>や<code>height</code>を指定できる。また、<code>margin</code>や<code>padding</code>を指定できる。<strong>display</strong>プロパティを<strong>inline-block</strong>に変更することで、サイズの変更が可能となる。</p></li> </ul> <p>CSSでは、ボックスモデルという概念を理解する必要がある。これは、4つの領域で構成され、外側から順に、<strong>margin</strong>,<strong>border</strong>,<strong>padding</strong>,<strong>content</strong>となる。ボックスのサイズはこの4つの領域のサイズを足し合わせて算出される。</p> <p><a href="https://crieit.now.sh/upload_images/54fbca013a0511b1f854dacc392b359d60c0d42c48c5b.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/54fbca013a0511b1f854dacc392b359d60c0d42c48c5b.jpg?mw=700" alt="image" /></a></p> <ul> <li><strong>margin</strong>:ボックスの一番外側にある余白。<code>margin</code>でサイズを指定できる。垂直方向のmarginは相殺が起こる。<br /> <a href="https://crieit.now.sh/upload_images/54fbca013a0511b1f854dacc392b359d60c0d3e1b2a03.jpg" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/54fbca013a0511b1f854dacc392b359d60c0d3e1b2a03.jpg?mw=700" alt="image" /></a></li> <li><p><strong>border</strong>:marginの内側にある枠線。<code>border-width</code>でサイズを指定できる。</p></li> <li><p><strong>padding</strong>:contentとborderの間にある余白。枠線とコンテンツの余白となる。<code>padding</code>でサイズを指定できる。</p></li> <li><p><strong>content</strong>:要素そのものの内容が表示される領域。<code>width</code>と<code>height</code>でサイズを指定できる。</p></li> </ul> <h3 id="よく使うスタイル集"><a href="#%E3%82%88%E3%81%8F%E4%BD%BF%E3%81%86%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E9%9B%86">よく使うスタイル集</a></h3> <ul> <li><code>color</code>:色を変更する</li> </ul> <pre><code class="CSS"> h1{color: green;} </code></pre> <ul> <li><code>font-size</code>:フォントの大きさを変更する</li> </ul> <pre><code class="CSS"> h1{font-size:12px;} </code></pre> <ul> <li><code>font-weight</code>:フォントの太さを変更する</li> </ul> <pre><code class="CSS"> h1{font-weight:bold;} </code></pre> <ul> <li><code>text-align</code>:ブロック要素の位置を変更する</li> </ul> <pre><code class="CSS"> h1{text-align:center;} </code></pre> <ul> <li><code>text-decoration</code>:テキストに装飾線を表示する</li> </ul> <pre><code class="CSS"> h1{text-decoration:underline;} </code></pre> <ul> <li><code>font-family</code>:フォントを変更する。左から順に適用される。ユーザーのブラウザに指定したフォントが存在しない場合、一つ右のフォントを適用する。</li> </ul> <pre><code class="CSS"> h1{font-family:Verdana, 'Arial Black', メイリオ, sans-serif;} </code></pre> <ul> <li><code>line-height</code>:行ボックスの高さを指定する。指定の単位を<strong>em</strong>とした場合、font-sizeを係数倍した高さになる。また、単位を指定した場合は、子要素にも親要素で計算した高さが継承されるが、単位を指定しなかった場合は、子要素で高さは再計算される。</li> </ul> <pre><code class="CSS"> h1{line-height: 2em;} </code></pre> <ul> <li><code>vertical-align</code>: 行ボックス内のベースラインを基準に、テキストと同じボックス内の画像の上下位置を変更する。数値を指定した場合は、ベースラインから数値分離れた位置となる。</li> </ul> <pre><code class="CSS"> .img_a {vertical-align: top;} </code></pre> <ul> <li>リストのスタイル指定。<code>list-style-type</code>でリストの点を変更する。<code>list-style-position</code>でリストの点の位置を変更する。<code>list-style-image</code>でリストの点に画像を使用することができる。</li> </ul> <pre><code class="CSS"> ul { list-style-type: circle; list-style-position: inside; list-style-image: url(./img/icon.png); } </code></pre> <ul> <li><code>list-style</code>:リストのスタイルを一括指定する。imageとtypeの両方が指定された場合は、画像が優先される。list-styleの前に個別の指定をしていた場合、list-styleのデフォルトで上書きされる。</li> </ul> <pre><code class="CSS"> ul{list-style: circle inside url(../img/icon.png);} </code></pre> <ul> <li>ボックスを中央揃えにする。</li> </ul> <pre><code class="CSS"> .box { margin-left: auto; margin-right: auto; } </code></pre> <p>* <code>display</code>:ブロックの切り替えや、非表示化。</p> <pre><code class="CSS"> .box {display:none;} /*非表示*/ .box {display:inline-block;} /*インラインブロック化*/ </code></pre> <ul> <li><code>z-index</code>:要素の重なり順を制御。</li> </ul> <pre><code class="CSS"> .box {z-index: 1;} .box2 {z-index: 2;} </code></pre> <ul> <li><code>box-sizing</code>:width,heightの指定範囲を拡大する。</li> </ul> <pre><code class="CSS"> .box { box-sizing: border-box; /*borderを含む*/ width: 100px; height: 100px; } </code></pre> <ul> <li><code>calc()</code>:サイズの計算を行う。</li> </ul> <pre><code class="CSS"> .box{width: calc((100% - 20px) / 5);} </code></pre> k-s-p tag:crieit.net,2005:PublicArticle/17041 2021-04-30T14:10:13+09:00 2021-04-30T14:10:13+09:00 https://crieit.net/posts/f7bdabfbfedccccc4376c1e4a593ad8f 続・コードを書いてステータス画面を表示する <h1 id="続・コードを書いてステータス画面を表示する"><a href="#%E7%B6%9A%E3%83%BB%E3%82%B3%E3%83%BC%E3%83%89%E3%82%92%E6%9B%B8%E3%81%84%E3%81%A6%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E7%94%BB%E9%9D%A2%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B">続・コードを書いてステータス画面を表示する</a></h1> <p>※この内容は、2021年5月1日・2日の二日間、Maker Faire Kyoto 2021に併せてオンライン開催される「<a target="_blank" rel="nofollow noopener" href="https://makezine.jp/blog/2021/04/kidsprogramingpark.html">子どもプログラミングパーク</a>」の展示作品の一つとして書かれました。</p> <p><img src="https://lh3.googleusercontent.com/pw/ACtC-3d4dByDutes1oinJ9l-X0PCXCdWFkOQIpi8dXojJzUyH-Aql_SlRjX_eb763AqprsXeozc2xQ-8LX0CPeXRwuPHIecWDyxna470CkUE2qRsXBzZvuAy443D0XVQRxtaExo0puazG56j746v7Kj6UBy75w=w1247-h627-no?authuser=0" alt="完成図" /></p> <h2 id="総説"><a href="#%E7%B7%8F%E8%AA%AC">総説</a></h2> <p>これは、Webブラウザに表示されたステータス画面の値を操作する、小さなサンプルコードです。<br /> このガイドテキストに沿ってコードを書き進めていくことで、ステータス画面を作成し、コンフィグ画面でステータスの値を操作することが出来るようになります。</p> <p><strong>サンプルコード:</strong><a target="_blank" rel="nofollow noopener" href="https://codesandbox.io/s/objective-volhard-ktrfs?file=/App.svelte">objective-volhard-ktrfs - CodeSandbox</a></p> <p>このガイドテキストを全て終えたプログラムは下記のようになります。</p> <p><strong>サンプルプログラム:</strong><a target="_blank" rel="nofollow noopener" href="https://svelte.dev/repl/2ad1f0ae67b7406e8beee9a2efbceda3?version=3.37.0">IamStronger • REPL • Svelte</a></p> <h2 id="ガイドテキスト"><a href="#%E3%82%AC%E3%82%A4%E3%83%89%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88">ガイドテキスト</a></h2> <p>このガイドテキストは次の3つのステップの順でコードを書き進めていきます。<br /> - Step.1 ステータス画面を作る<br /> - Step.2 スタイルシートを書く<br /> - Step.3 コンフィグ画面を作る</p> <p>各ステップごとのサンプルコードは、コピーして貼り付けても構いません。コードの内容をよく観察して、それぞれの関係について考えてみてください。</p> <h3 id="準備"><a href="#%E6%BA%96%E5%82%99">準備</a></h3> <p>サンプルコードを開いて、App.svelteファイルが表示されていることを確認します。</p> <p><strong>サンプルコード:</strong><a target="_blank" rel="nofollow noopener" href="https://codesandbox.io/s/objective-volhard-ktrfs?file=/App.svelte">objective-volhard-ktrfs - CodeSandbox</a></p> <p><img src="https://lh3.googleusercontent.com/pw/ACtC-3eMPk7dFEqofdBKktGcLdBM0TjU0IAOG6F0EroSWh7mj14dOwT6iQTrTrsRvTybFs20gt4Oj84hizsSJGn-5uemIY3td8aKGyJfIC3_K9VW-Kh45jhKVRsC0ySI0WW1UtXDpx0thm3lUF8jJC-AoqNrPA=w1587-h484-no?authuser=0" alt="サンプルコードを開いた様子" /></p> <p>今回はこのApp.svelteファイルの25行目から下に書かれている内容を編集します。</p> <pre><code class="html"><!-- Step.1 ここにステータス画面を作ります --> <div class="status-view"> Step.1 ここにステータス画面を作ります </div> <!-- Step.3 スタイルシートを書いたら、ここにコンフィグ画面を作ります --> <div class="status-config"> Step.3 スタイルシートを書いたら、ここにコンフィグ画面を作ります </div> <!-- Step.2 ステータス画面を作ったら、ここにスタイルシートを書きます --> Step.2 ステータス画面を作ったら、ここにスタイルシートを書きます </code></pre> <p><strong>編集したファイルを保存するには、コントロールキーを押しながらSキーを押す【Ctrl+S】か、メニューバーから【File】を選択して【Save】をクリックします。</strong></p> <p><img src="https://lh3.googleusercontent.com/pw/ACtC-3d12KVt26TRFGZAfX6CLsv1hQ6uTXtoSo3hfLTflbRf4y5x-VHu31pqSe8-MnxrTBRPUZq3j5L-C8y03R9bAI7CNCBQRGi2Dsxwj4WdkOSU6rzxN4kqsnxwyIRaXv_-1eZHXhX0bgmA4VnDKbeZliYTuw=w455-h152-no?authuser=0" alt="File Save" /></p> <p><strong>このサンプルコードは自由に編集しても大丈夫です。ページを再読込すると、元の内容に戻ります。</strong></p> <h3 id="Step.1 ステータス画面を作る"><a href="#Step.1+%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E7%94%BB%E9%9D%A2%E3%82%92%E4%BD%9C%E3%82%8B">Step.1 ステータス画面を作る</a></h3> <p>今回の目標はステータス画面を表示して、値を操作することです。</p> <p>まずは、ステータス画面に表示される内容を、HTMLで書きます。</p> <pre><code class="html"><!-- Step.1 ここにステータス画面を作ります --> <div class="status-view"> <div class="status-image"> {name}<br> <img src="/alienYellow.png" alt="character" /> </div> <div class="status-data"> Lv: {lv}<br> HP: {hp}/ {max_hp}<br> MP: {mp}/ {max_mp}<br> <br> AGI: {agi} STR: {str}<br> TEC: {tec} LUC: {luc} </div> <div class="status-text"> {text} </div> </div> </code></pre> <p>もし、ホームページを作ったことがあるなら、このコードを書きながら少し奇妙におもうかもしれません。bodyタグもhtmlタグも無いところに、突然divタグが始まっています。<br /> でも心配はありません。今回はWebアプリケーションを作っています。そして、ここではこういった書き方ができます。</p> <p>サンプルコードを書き終えると、このような画面になります。</p> <p><img src="https://lh3.googleusercontent.com/pw/ACtC-3eKQjVuaUlGV9OP9RKP9Lg-d4BFmRsAn8xCVjRrM4GINKUWitlpD84zU6EpRCftwtDUxAyxxURcHNmQaDAkktCLwBX0Js0qMILyEV0d58mmVUd3DjhabemQKIoqL20REmwTudx9ow5uP2cLaU_tLArBTQ=w815-h440-no?authuser=0" alt="Step.1の確認" /></p> <h3 id="Step.2 スタイルシートを書く"><a href="#Step.2+%E3%82%B9%E3%82%BF%E3%82%A4%E3%83%AB%E3%82%B7%E3%83%BC%E3%83%88%E3%82%92%E6%9B%B8%E3%81%8F">Step.2 スタイルシートを書く</a></h3> <p>今回の目標はステータス画面を表示して、値を操作することです。</p> <p>ステータス画面が、ステータス画面として見やすくなるように、スタイルシートで見た目を整える事ができます。</p> <p>次のコードを、ファイルの一番下に書きます。</p> <pre><code class="css"><!-- Step.2 ステータス画面を作ったら、ここにスタイルシートを書きます --> <style> .status-view { width: 320px; height: 240px; margin: 2em auto; padding: 1em; background-color: blue; color: white; display: flex; flex-wrap: wrap; text-shadow: 1px 1px black; font-family: monospace; font-size: 16px; } .status-image { width: 128px; } .status-data { flex-grow: 1; padding-left: 1em; } .status-text { width: 100%; padding: 0.5em; border: 2px ridge white; overflow: hidden; } img { display: block; margin: auto; } .status-config { width: 320px; margin: 1em auto 2em; padding: 1em; border: 1px solid black; line-height: 2em; } </style> </code></pre> <p>もし、ホームページを作ったことがあるなら、このコードを書きながら少し奇妙におもうかもしれません。ファイルの一番下に突然スタイルシートを書き始めて、cssファイルも読み込みません。</p> <p>でも心配はありません。今回はWebアプリケーションを作っています。そして、ここではこういった書き方ができます。</p> <p>サンプルコードを書き終えると、このような画面になります。</p> <p><img src="https://lh3.googleusercontent.com/pw/ACtC-3eoR1XuNMbhWKQ2VqmRc9SDAUwNkgACF1e5aAvelgtTwfD6Q1s7WCInLFy-6E6RnNwak5uiXB7PDl4UPC6TWefO5gYM5E3LkchmC8nAv-oYuYWgY2ie1dilhsVSRtqpezh7s2QCWqUFT3jHO0bzwwTWRQ=w1100-h440-no?authuser=0" alt="Step.2の確認" /></p> <h3 id="Step.3 コンフィグ画面を作る"><a href="#Step.3+%E3%82%B3%E3%83%B3%E3%83%95%E3%82%A3%E3%82%B0%E7%94%BB%E9%9D%A2%E3%82%92%E4%BD%9C%E3%82%8B">Step.3 コンフィグ画面を作る</a></h3> <p>今回の目標はステータス画面を表示して、値を操作することです。</p> <p>作成したステータス画面の値を操作するために、コンフィグ画面を作ります。</p> <pre><code class="html"><!-- Step.3 スタイルシートを書いたら、ここにコンフィグ画面を作ります --> <div class="status-config"> config<br> name : <input type="text" maxlength="16" bind:value="{name}" /> <br> Lv : <input type="number" min="1" max="99" bind:value="{lv}" /> <br> hp: <input type="number" min="0" max="{max_hp}" bind:value={hp} /> mp: <input type="number" min="0" max="{max_mp}" bind:value={mp} /> <br> AGI: <input type="number" min="1" max="99" bind:value={agi} /> STR: <input type="number" min="1" max="99" bind:value={str} /> <br> TEC: <input type="number" min="1" max="99" bind:value={tec} /> LUC: <input type="number" min="1" max="99" bind:value={luc} /> <br> text : <br> <textarea bind:value="{text}"></textarea> </div> </code></pre> <p>もし、ホームページを作ったことがあるなら、このコードを書きながら少し奇妙におもうかもしれません。formタグもbuttonタグも無いし、valueの内容と画面に表示されている内容もぜんぜん違います。</p> <p>でも心配はありません。今回はWebアプリケーションを作っています。そして、ここではこういった書き方ができます。</p> <p>サンプルコードを書き終えると、このような画面になります。</p> <p><img src="https://lh3.googleusercontent.com/pw/ACtC-3euAKSF1AWjs9Y6JtzQ8-8a0g7nwpUY6KIce6UP7hGjMJFsqWHDGTXl-irup3qiw5TJZIwOJ5CNEU_z3Rxu2HyHNfjEuu6rmarBx28D2XH-uDFy-4R-YARzp65ULouny3zGScoSgD1QYnPPmj7kHzP8CA=w1100-h451-no?authuser=0" alt="Step.3の確認" /></p> <h3 id="レッツプレイ 観察タイム"><a href="#%E3%83%AC%E3%83%83%E3%83%84%E3%83%97%E3%83%AC%E3%82%A4+%E8%A6%B3%E5%AF%9F%E3%82%BF%E3%82%A4%E3%83%A0">レッツプレイ 観察タイム</a></h3> <p>今回の目標はステータス画面を表示して、値を操作することです。</p> <p>そして、これまでの3つのステップで、この目標は達成されました。</p> <p>コンフィグ画面の値を操作して、ステータス画面の変化を確認してみてください。</p> <h3 id="ドキドキ 改造タイム"><a href="#%E3%83%89%E3%82%AD%E3%83%89%E3%82%AD+%E6%94%B9%E9%80%A0%E3%82%BF%E3%82%A4%E3%83%A0">ドキドキ 改造タイム</a></h3> <p>今回書いたコードをおさらいします。</p> <pre><code class="html"><!-- Step.1 ここにステータス画面を作ります --> <div class="status-view"> <div class="status-image"> {name}<br> <img src="/alienYellow.png" alt="character" /> </div> <div class="status-data"> Lv: {lv}<br> HP: {hp}/ {max_hp}<br> MP: {mp}/ {max_mp}<br> <br> AGI: {agi} STR: {str}<br> TEC: {tec} LUC: {luc} </div> <div class="status-text"> {text} </div> </div> <!-- Step.3 スタイルシートを書いたら、ここにコンフィグ画面を作ります --> <div class="status-config"> config<br> name : <input type="text" maxlength="16" bind:value="{name}" /> <br> Lv : <input type="number" min="1" max="99" bind:value="{lv}" /> <br> hp: <input type="number" min="0" max="{max_hp}" bind:value={hp} /> mp: <input type="number" min="0" max="{max_mp}" bind:value={mp} /> <br> AGI: <input type="number" min="1" max="99" bind:value={agi} /> STR: <input type="number" min="1" max="99" bind:value={str} /> <br> TEC: <input type="number" min="1" max="99" bind:value={tec} /> LUC: <input type="number" min="1" max="99" bind:value={luc} /> <br> text : <br> <textarea bind:value="{text}"></textarea> </div> <!-- Step.2 ステータス画面を作ったら、ここにスタイルシートを書きます --> <style> .status-view { width: 320px; height: 240px; margin: 2em auto; padding: 1em; background-color: blue; color: white; display: flex; flex-wrap: wrap; text-shadow: 1px 1px black; font-family: monospace; font-size: 16px; } .status-image { width: 128px; } .status-data { flex-grow: 1; padding-left: 1em; } .status-text { width: 100%; padding: 0.5em; border: 2px ridge white; overflow: hidden; } img { display: block; margin: auto; } .status-config { width: 320px; margin: 1em auto 2em; padding: 1em; border: 1px solid black; line-height: 2em; } </style> </code></pre> <p>思いつく限り、自由に改造してみてください。</p> <p><img src="https://lh3.googleusercontent.com/pw/ACtC-3cmelku4N_7I29oP7zHRqHVEvKU11H0ZY-TAcx_gueIzuQf3fiGDUe-Lb6Wp8TzBDo6aBhzyBUpDAgQB8e5XjWV1p0O8OyZr_10JvrDlnvRcggRj-BNKUJiWNfpOlXsjbDgbnu1VEG5aQ2vBjlbcF0TzA=w412-h660-no?authuser=0" alt="完成図" /></p> <h2 id="解説 Webアプリケーション フレームワーク"><a href="#%E8%A7%A3%E8%AA%AC+Web%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3+%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF">解説 Webアプリケーション フレームワーク</a></h2> <p>このサンプルコードはHTMLとCSSで書かれていますが、プログラム全体ではWebアプリケーションフレームワーク「Svelte」を使用しています。</p> <p>App.svelteファイルの構成は、上から順に、JavaScript、HTML、CSSとなっており、一つのファイルの中に必要な機能と要素そしてスタイルをまとめて書くことが出来ます。</p> <p>今回使用したSvelteには、実際に入力した内容を確かめながら学ぶことができるチュートリアルが用意されています。説明は英語ですが、短文で簡潔にまとめられているのでGoogle翻訳などで読んでも理解しやすい内容になっています。<br /> このサンプルプログラムで興味をもったら、ぜひ試してみて下さい。</p> <p>Hello world から始まります。</p> <p><a target="_blank" rel="nofollow noopener" href="https://svelte.dev/tutorial/basics">Introduction / Basics • Svelte Tutorial</a></p> <p><img src="https://lh3.googleusercontent.com/pw/ACtC-3dyxjVh-Mt7ctmOAcQSv8CUTp31Fi-UkyfKzez43eCdm-VPHxMQsvZg4ffNQghE4fglG0cYYxuFC4DZLzLCnBeoeu0_xCrjmE6lH6L8TFkRXzSHNdJ3e-TPJYmKy12wINkNYiXE-fJ-sKpe5ZJJLIHbXg=w1231-h604-no?authuser=0" alt="Svelte Tutorial" /></p> <p>今回使用したSvelteの他にも、世界では様々なWebアプリケーションフレームワークが日々改良を重ねています。</p> <p>いますぐ自由に使えるものもいくつかありますので、実際に触って試してみて、自分にあったWebアプリケーションフレームワークを見つけてみてください。</p> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://svelte.dev/">Svelte • Cybernetically enhanced web apps</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://ja.reactjs.org/">React – ユーザインターフェース構築のための JavaScript ライブラリ</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://v3.ja.vuejs.org/">Vue.js</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://angular.jp/">Angular 日本語ドキュメンテーション</a></li> </ul> <p><img src="https://lh3.googleusercontent.com/pw/ACtC-3eQgVossbbmqlIJh0rqXIiiiQJan15IMIu2qv2x3LtCSRyIjIbYK6iAHtzXkxeXPqDNMT0gWt-KBRppybfCGyg5EYXCEku6TAEhRCr3gBDcBOlb5IQwysfCfjEKvpi3U4OfqPpkWeJX95CwRLVeZ-vj8Q=w1260-h685-no?authuser=0" alt="Svelte Web site" /></p> <p><img src="https://lh3.googleusercontent.com/pw/ACtC-3djcsyBB1wYWzQL1wIi2ZtJYrC0Dz_BcvFGSXFWgdR5euxoI7tJSwhdS4BrU2tIQeHCl1b5bECB8Zn0jcJ_p_xPiKyvMlLMdJ41jT_nSZ7qXge6vejsqkA-CE_U84aALjXUkoYNGJgNEHuvPRWjBDjH-w=w1260-h685-no?authuser=0" alt="React Web site" /></p> <p><img src="https://lh3.googleusercontent.com/pw/ACtC-3eaKq3uLZ1w7Id0_EbtmcdzpT9SKHCmg6i38oKY4z7ooq74zC5MMyzkiJJfuGg3T3sbfAiPYTwGByDbmJk7CXj55-PQUMtojmWC6suHVMoIHxQjUpw6PFys3SLoqLjBWPZlYrqtOwRj7gDmmr8C91N98Q=w1260-h685-no?authuser=0" alt="Vue.js Web site" /></p> <p><img src="https://lh3.googleusercontent.com/pw/ACtC-3da_cge23AaD0w54ecV-Y45UAWFAPBNuCOXOxBsVNkpZjVdyOxLCQQhcMdfsb6GiIWMZF9ESbB36gWm1xPLWs67aD1kKBiPABY1KGT6dXSD-TIxOA-frjVrjebO-QNm1suIRKEdDKijrylWuSGZAC3NMg=w1260-h685-no?authuser=0" alt="Angular Web site" /></p> fkuMnk tag:crieit.net,2005:PublicArticle/16786 2021-03-28T18:20:44+09:00 2021-08-08T16:13:11+09:00 https://crieit.net/posts/VSCode-Web 【VSCode】拡張機能一覧(主にWeb系システム開発用) <p>個人用メモ。<br /> 主にPHPを使用して開発する環境で使用している拡張機能一覧。<br /> (他のも混じっているけど)<br /> (後で追加・変更・削除するかも)</p> <h1 id="VSCode"><a href="#VSCode">VSCode</a></h1> <ul> <li><p>Bookmarks<br />  あらかじめソースコード中にブックマークを設定しておくと、他の場所からブックマークまで一瞬で移動することが出来る。</p></li> <li><p>indent-rainbow<br />  インデントを色付きで表示してくれる。</p></li> <li><p>Japanese Language Pack for Visual Studio Code<br />  VSCodeの日本語化。</p></li> </ul> <h1 id="HTML"><a href="#HTML">HTML</a></h1> <ul> <li><p>Auto Close Tag<br />  自動的に閉じタグを追記してくれる。</p></li> <li><p>Auto Rename Tag<br />  タグを変更すると、対応する閉じタグを自動的に変更してくれる。</p></li> <li><p>HTML Snippets<br />  HTMLの予測変換を表示してくれる。</p></li> <li><p>HTMLHint<br />  HTMLの文法チェックをしてくれる。</p></li> </ul> <h1 id="PHP(Laravel)"><a href="#PHP%28Laravel%29">PHP(Laravel)</a></h1> <ul> <li><p>Bracket Pair Colorizer 2<br />  メソッドやArrayなどで、対となるカッコを色付きで表示してくれる。</p></li> <li><p>php cs fixer<br />  PHPソースを自動整形してくれる。<br />  ※別途、「php-cf-fixer.phar」のインストールが必要。</p></li> <li><p>PHP Debug<br />  PHPをステップ実行してデバッグできるようになる。</p></li> <li><p>PHP IntelliSense<br />  PHPの予測変換を表示してくれる。</p></li> </ul> <p>【2021.8.8 追加】<br /> * Laravel Blade Snippets<br />  Laravelのbladeファイル内のタグやディレクティブを色付きで表示してくれる。</p> <ul> <li>Laravel Blade formatter<br />  Laravelのbladeファイル用のフォーマッタ。<br />  blade独自のディレクティブもインデントしてくれる(これ重要)。</li> </ul> <h1 id="JavaScript(Node.js,Vue.js)"><a href="#JavaScript%28Node.js%2CVue.js%29">JavaScript(Node.js,Vue.js)</a></h1> <ul> <li><p>ESLint<br />  JavaScriptの構文チェックをリアルタイムで実行してくれる。<br />  ※Vue.jsで使用するには設定が必要。</p></li> <li><p>JavaScript (ES6) code snippets<br />  JavaScriptの予測変換を表示してくれる。</p></li> <li><p>Vetur<br />  Vue.jsコードのシンタックスハイライトやコード補完、リント、フォーマットを行ってくれる。</p></li> </ul> <h1 id="CSS(Sass,SCSS)"><a href="#CSS%28Sass%2CSCSS%29">CSS(Sass,SCSS)</a></h1> <ul> <li><p>IntelliSense for CSS class names in HTML<br />  CSSクラス名を入力するときに、入力補完してくれる。</p></li> <li><p>SCSS Formatter<br />  SCSSコードを自動整形してくれる。</p></li> </ul> <h1 id="その他"><a href="#%E3%81%9D%E3%81%AE%E4%BB%96">その他</a></h1> <ul> <li><p>Log File Highlighter<br />  ログファイルの内容を色付きで表示してくれる。</p></li> <li><p>MySQL<br />  VSCodeでMySQLを使用可能にする。</p></li> <li><p>Rainbow CSV<br />  CSVファイルをカラムごとに色分けして表示してくれる。</p></li> <li><p>Regex Previewer<br />  正規表現の実行結果をプレビュー表示してくれる。</p></li> <li><p>SFTP<br />  サーバへ自動的にソースファイルをアップロードしてくれる。</p></li> </ul> <h1 id="【参考】"><a href="#%E3%80%90%E5%8F%82%E8%80%83%E3%80%91">【参考】</a></h1> <p>「Visual Studio Code」をインストールしてPHPコードのデバッグ環境を設定する方法<br /> <a target="_blank" rel="nofollow noopener" href="https://incloop.com/visualstudiocodeのデバッグ設定/">https://incloop.com/visualstudiocodeのデバッグ設定/</a></p> <p>Visual Studio Codeで作るPHP開発環境のおすすめ拡張機能17選<br /> <a target="_blank" rel="nofollow noopener" href="https://wonwon-eater.com/vscode-php-plugin/">https://wonwon-eater.com/vscode-php-plugin/</a></p> <p>VScodeの日本語化ができない 変わらない時の対処法[Visual Studio Code]<br /> <a target="_blank" rel="nofollow noopener" href="https://rabotiku-sato.com/vscode-japanese-setting">https://rabotiku-sato.com/vscode-japanese-setting</a></p> <p>vscodeでVue.jsを書くときに使っているプラグインとか<br /> <a target="_blank" rel="nofollow noopener" href="https://qiita.com/dayoshix/items/c61a75a971331418c348">https://qiita.com/dayoshix/items/c61a75a971331418c348</a></p> <p>【HTML編】Visual Studio Code おすすめプラグイン紹介 #02<br /> <a target="_blank" rel="nofollow noopener" href="https://so-da.tech/tech/vscode/vscd3/">https://so-da.tech/tech/vscode/vscd3/</a></p> <p>VSCodeのAuto Rename Tagで閉じタグも自動変更<br /> <a target="_blank" rel="nofollow noopener" href="https://tech.pjin.jp/blog/2020/04/27/vscode_extension_auto_rename_tag/">https://tech.pjin.jp/blog/2020/04/27/vscode_extension_auto_rename_tag/</a></p> <p>VSCode で HTML の文法チェックを行う拡張機能 HTMLHint<br /> <a target="_blank" rel="nofollow noopener" href="https://loumo.jp/archives/26229">https://loumo.jp/archives/26229</a></p> <p>VSCode拡張機能『indent-rainbow』でインデントを虹色にする方法<br /> <a target="_blank" rel="nofollow noopener" href="https://onedarling.site/programming/tool/vscode-indent-rainbow/">https://onedarling.site/programming/tool/vscode-indent-rainbow/</a></p> <p>【2020年版】VSCodeでhtml/css/jsの拡張機能おすすめ<br /> <a target="_blank" rel="nofollow noopener" href="https://uetani33.net/vscode-web-extensions/#toc_id_3_2">https://uetani33.net/vscode-web-extensions/#toc_id_3_2</a></p> <p>VSCode使い必見!?使って便利な Visual Studio Code 拡張機能10選<br /> <a target="_blank" rel="nofollow noopener" href="https://www.geekfeed.co.jp/geekblog/vscode_extension">https://www.geekfeed.co.jp/geekblog/vscode_extension</a></p> <p>【超便利】VSCodeでMySQLを利用する方法<br /> <a target="_blank" rel="nofollow noopener" href="https://newmtube07.com/vscode-mysql/">https://newmtube07.com/vscode-mysql/</a></p> <p>[Visual Studio Code] PHPのコードを整形する「php cs fixer」の設定<br /> <a target="_blank" rel="nofollow noopener" href="https://www.searchlight8.com/visual-studio-code-php/">https://www.searchlight8.com/visual-studio-code-php/</a></p> <p>VSCode(Visual Studio Code)でSFTP・FTP経由でファイルを自動アップロードや同期できる拡張機能「SFTP」が超便利<br /> <a target="_blank" rel="nofollow noopener" href="https://www.karelie.net/vscode-sftp/">https://www.karelie.net/vscode-sftp/</a></p> <p>Windows10でVisual Studio Code + vue-cliの開発環境構築メモ<br /> <a target="_blank" rel="nofollow noopener" href="https://belhb.hateblo.jp/entry/2020/08/08/142540">https://belhb.hateblo.jp/entry/2020/08/08/142540</a></p> <p>【2021.8.8 追加】<br /> LaravelでVisual Studio Codeを使う時に入れておきたい拡張機能3選<br /> <a target="_blank" rel="nofollow noopener" href="https://biz.addisteria.com/laravel-vscode/">https://biz.addisteria.com/laravel-vscode/</a></p> <p>Laravel blade formatter VSCode Extensionを作った<br /> <a target="_blank" rel="nofollow noopener" href="https://shufo.dev/2020/10/03/published-vscode-blade-formatter/">https://shufo.dev/2020/10/03/published-vscode-blade-formatter/</a></p> <p>VSCodeでBladeテンプレートを整形する<br /> <a target="_blank" rel="nofollow noopener" href="https://blog.nplpl.com/310">https://blog.nplpl.com/310</a></p> acmz tag:crieit.net,2005:PublicArticle/16417 2020-12-24T00:53:23+09:00 2020-12-24T00:53:23+09:00 https://crieit.net/posts/HTML-CSS-JS-DOM ライブラリを使わず、HTML,CSS,JSのDOM操作でブロック崩しゲームを作る <p>・アドベントカレンダー<a href="https://crieit.net/advent-calendars/2020/crieit">なんでも</a> 12/24に投稿します。<br /> 記事内容は自分のブログに書いたのでこちらをご覧ください。<br /> (このアドベントカレンダー、crieitでしか記事公開できないと思わなかったので自分のブログに書いてしまいました!すみません!)</p> <p><strong><a target="_blank" rel="nofollow noopener" href="https://hothukurou.com/blog/?p=2286">ライブラリを使わず、HTML,CSS,JSのDOM操作でブロック崩しゲームを作る</a></strong></p> ほっとフクロウ(作っちゃうおじさん) tag:crieit.net,2005:PublicArticle/16171 2020-10-25T10:42:27+09:00 2020-10-25T10:58:23+09:00 https://crieit.net/posts/feature ポートフォリオのテンプレートのfeature部分 <h1 id="テキストが下に表示されてしまう"><a href="#%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%81%8C%E4%B8%8B%E3%81%AB%E8%A1%A8%E7%A4%BA%E3%81%95%E3%82%8C%E3%81%A6%E3%81%97%E3%81%BE%E3%81%86">テキストが下に表示されてしまう</a></h1> <p><a href="https://crieit.now.sh/upload_images/c6e8bbfab42a5ea14894897287ae96bf5f94dae11802f.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/c6e8bbfab42a5ea14894897287ae96bf5f94dae11802f.png?mw=700" alt="image" /></a></p> <h1 id="index.html"><a href="#index.html">index.html</a></h1> <pre><code class="html"> <!-- FEATUREセクション --> <section id="feature-section"> <div class="inner"> <div class="section-heading"> <h2 class="heading-primary">FEATURE</h2> </div> <div class="section-lead"> <p>1サイトの解説</p> </div> <div class="feature-item"> <div class="feature-img-wrapper"> <a href="https://www.yahoo.co.jp" target="_blank"> <img src="img/feature/feature.jpg" alt=""> </a> </div> <div class="feature-body"> <p><span class="text-bold">サイト名:</span> <br>サイト名が入る<br> <a href="#" target="_blank">https://●●●.com</a> </p> <p><span class="text-bold">担当:</span><br>Design / Coding (Responsive) / WordPress / Writing</p> <p><span class="text-bold">コメント:</span><br>テキストテキストテキストテキストテキストテキストテキストテキストテキスト<br>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト </p> <p> テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</p> <p>テキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキストテキスト</p> <div class="clearfix"></div> </div><!-- ./feature-body --> </div><!-- ./feature-item --> </div><!-- ./inner --> </section> </code></pre> <h1 id="CSS"><a href="#CSS">CSS</a></h1> <p>floatを使ったパターンです。</p> <pre><code class="css">@charset "utf-8"; /* リセットCSS ----------------------------- */ html,body,h1,h2,ul,li{ margin: 0; padding: 0; line-height: 1; } img{ max-width: 100%; height: auto; vertical-align: bottom; border-style: none; } ul,li{ list-style: none; } a{ text-decoration: none; color: #1ca9e3; } /* body ----------------------------- */ body{ font-family: "Quicksand","Hiragino Kaku Gothic Pro","Meiryo",sans-serif; font-size: 15px; line-height: 1.8; letter-spacing: .8px; word-break: break-all; color: #333333; } /* 文字 ----------------------------- */ .heading-primary{ font-family: 'Josefin Sans',sans-serif; font-size: 40px; letter-spacing: .05em; } .section-heading{ text-align: center; margin-bottom: 20px; } .section-lead{ margin-bottom: 30px; text-align: center; } /* レイアウト ----------------------------- */ .inner{ max-width: 1380px; margin: 0 auto; padding: 0 40px; } /* header ----------------------------- */ header{ display: flex; align-items: center; justify-content: center; height: 86vh; } .logo{ position: relative; margin-bottom: 30px; padding: 0 20px; text-align: center; } .logo-title{ font-family: 'Nunito',sans-serif; font-size: 76px; letter-spacing: .1em; } .logo-subtitle{ font-size: 22px; margin-top: 5px; text-align: center; letter-spacing: .2em; } /* グローバルナビ ----------------------------- */ .gnav{ position: fixed; top: 0; left: 0; z-index: 100; width: 100%; background: #ffffff; -webkit-box-shadow: 0 3px 3px -3px rgba(0, 0, 0, .2); -moz-box-shadow: 0 3px 3px -3px rgba(0, 0, 0, .2); box-shadow: 0 3px 3px -3px rgba(0, 0, 0, .2); } .gnav-list{ display: flex; flex-wrap: wrap; justify-content: center; } .gnav-item{ font-family: 'Josefin Sans',sans-serif; font-size: 16px; padding: 0 24px; letter-spacing: .05em; } .gnav-link{ position: relative; display: inline-block; padding: 20px 0; /* -webkit-transition: .3s; transition: .3s; */ color: #333333; } .gnav-link:hover{ opacity: .5; } /* WORKSセクション ----------------------------- */ .works-list{ display: flex; flex-wrap: wrap; margin-bottom: 80px; } .works-item{ flex-basis: 32.31552%; margin: 0 auto 40px; text-align: center; } .works-body{ text-align: center; } .works-title{ font-size: 12px; font-weight: bold; margin-top: 8px; } .works-text, .works-url{ font-size: 10px; } /* FEATUREセクション ----------------------------- */ .feature-item{ /* display: flex; */ flex-wrap: wrap; } .feature-img-wrapper{ /* flex-basis: 45%; */ width: 45%; margin-right: 40px; float: left; } .feature-body{ flex-grow: 1; } .clearfix::after{ content: ""; display: block; clear: both; } </code></pre> <h2 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://webdesigner-go.com/template/portfolio-02/#comment-799">ポートフォリオHTMLテンプレート(ベーシック)</a></p> manabu aratani tag:crieit.net,2005:PublicArticle/16037 2020-08-24T18:47:06+09:00 2020-08-24T19:08:15+09:00 https://crieit.net/posts/JavaScript-postMessage-DOM-Xpath JavaScriptのpostMessageでDOMツリーのノード参照を渡す方法[Xpath] <p>ポップアップしたウィンドウに要素の参照(DOMノード)を送りたかったので、この記事を書いた。</p> <h1 id="Web MessagingはDOMノードを送れない"><a href="#Web+Messaging%E3%81%AFDOM%E3%83%8E%E3%83%BC%E3%83%89%E3%82%92%E9%80%81%E3%82%8C%E3%81%AA%E3%81%84">Web MessagingはDOMノードを送れない</a></h1> <p>JavaScriptでは、<a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/API/Window/postMessage">window.postMessage</a>を使うことで、ポップアップやiframeなどの別ウィンドウとWeb Messaging(HTML5)を介して通信することができる。</p> <p>子ウィンドウ、親ウィンドウへの参照はそれぞれ<code>window.open()</code>と<code>window.opener</code>で持つことができるから、<code>window.postMessage</code>と併せてあらゆるデータのやり取りが自由にできそうなものである。</p> <p>しかし、<code>window.postMessage</code>では送ることができないデータがある。</p> <p>MDN web docsには、<code>message</code>について</p> <blockquote> <p>他のウィンドウに送られるデータ。データは <a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm">the structured clone algorithm</a> に従ってシリアル化されます。つまり、手動でシリアル化することなく様々なデータオブジェクトを渡すことができます。<br /> <a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/API/Window/postMessage">(window.postMessage - Web API | MDN</a>)</p> </blockquote> <p>と書かれている。</p> <p>この「<a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm">the structured clone algorithm</a>」(日本語「<a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/API/Web_Workers_API/Structured_clone_algorithm">構造化複製アルゴリズム</a>」)という部分が重要で、この中で「<a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#%E6%A7%8B%E9%80%A0%E5%8C%96%E8%A4%87%E8%A3%BD%E3%81%A7%E5%8B%95%E4%BD%9C%E3%81%97%E3%81%AA%E3%81%84%E3%82%82%E3%81%AE">構造化複製で動作しないもの</a>」というのが示されいる。</p> <blockquote> <ul> <li>Function オブジェクトは構造化複製アルゴリズムでは複製されません。複製しようとすると DATA_CLONE_ERR 例外が送出されます。</li> <li>DOM ノードを複製しようとしても同様に DATA_CLONE_ERR 例外が送出されます。</li> </ul> </blockquote> <p>つまり、例えば<code>document.querySelector()</code>などを使えば要素の参照を取得できるが、このような参照はWeb Messagingで送ることができない。<br /> 実際に<code>window.postMessage</code>でDOMノードを送ろうとすると、</p> <blockquote> <p>Uncaught DOMException: Failed to execute 'postMessage' on 'Window': HTMLButtonElement object could not be cloned.</p> </blockquote> <p>のようなエラーが発生する。</p> <p>ウィンドウ間で互いのDOMの参照はできるのだから、DOMノードも送れるべきである。<br /> そこで、住所のように、テキストでDOMツリーにおけるノードの位置を表現できる方法を探していると、「Xpath」という言語構文を見つけた。</p> <h1 id="Xpathとは"><a href="#Xpath%E3%81%A8%E3%81%AF">Xpathとは</a></h1> <p>Xpathとは、XMLやHTMLのようなツリー状の階層構造を持つ文書で、様々なノードの位置や情報を表すことができる記法のことである。URLのようなパス表記ができることが特徴。</p> <p><a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Introduction_to_using_XPath_in_JavaScript">Introduction to using XPath in JavaScript | MDN</a></p> <p>記法については<a target="_blank" rel="nofollow noopener" href="https://qiita.com/rllllho/items/cb1187cec0fb17fc650a">こちらの記事</a>が詳しいが、ざっくり言うと、例えばbody直下の<code><h1></code>にアクセスするためのXpathは</p> <pre><code>/html/body/h1 </code></pre> <p>となる。</p> <p>また、2番目の<code><div></code>の3番目の<code><span></code>にアクセスするためのXpathは</p> <pre><code>/html/body/div[2]/span[3] </code></pre> <p>といったように表すことができる。</p> <h1 id="要素のXpathを取得して送信する"><a href="#%E8%A6%81%E7%B4%A0%E3%81%AEXpath%E3%82%92%E5%8F%96%E5%BE%97%E3%81%97%E3%81%A6%E9%80%81%E4%BF%A1%E3%81%99%E3%82%8B">要素のXpathを取得して送信する</a></h1> <p>まず、送るためにはDOMノードのXpathを取得する必要がある。<br /> 以下の記事のコードを使用して送信側のスクリプトを書いた。</p> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/narikei/items/fb62b543ca386fcee211">ブラウザ上のクリックした要素のXpathを取得する - Qiita</a></p> <p><strong>parent.htmlのjs</strong></p> <pre><code class="JavaScript"><br />let childWindow = window.open('child.html', 'child', 'width=300,height=400,scrollbars'); // クリックされたらその要素のXpathを子ウィンドウにpostMessageする window.addEventListener('click', (e) => { childWindow.postMessage(getXpath(e.target), 'http://localhost'); }); /* https://qiita.com/narikei/items/fb62b543ca386fcee211 */ function getXpath(element) { if(element && element.parentNode) { var xpath = getXpath(element.parentNode) + '/' + element.tagName; var s = []; for(var i = 0; i < element.parentNode.childNodes.length; i++) { var e = element.parentNode.childNodes[i]; if(e.tagName == element.tagName) { s.push(e); } } if(1 < s.length) { for(var i = 0; i < s.length; i++) { if(s[i] === element) { xpath += '[' + (i+1) + ']'; break; } } } return xpath.toLowerCase(); } else { return ''; } } </code></pre> <h1 id="要素のXpathを受け取って参照する"><a href="#%E8%A6%81%E7%B4%A0%E3%81%AEXpath%E3%82%92%E5%8F%97%E3%81%91%E5%8F%96%E3%81%A3%E3%81%A6%E5%8F%82%E7%85%A7%E3%81%99%E3%82%8B">要素のXpathを受け取って参照する</a></h1> <p>受信側は以下のようになる。</p> <p><strong>child.htmlのjs</strong></p> <pre><code class="JavaScript">let parent = window.opener.document; function receiveMessage(e) { if (e.origin !== "http://localhost") {return} parent.evaluate(e.data, parent, null, XPathResult.FIRST_ORDERED_NODE_TYPE).singleNodeValue.innerHTML = 'ok!'; } window.addEventListener("message", receiveMessage); </code></pre> <p><a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Introduction_to_using_XPath_in_JavaScript">Introduction to using XPath in JavaScript | MDN</a></p> <p>成功すると、親ウィンドウでクリックした要素に「ok!」と表示されるはず。<br /> これで、親ウィンドウから子ウィンドウに送られたXpathを使って、子ウィンドウが親ウィンドウのDOMを参照し、当該要素にアクセスすることが可能になった。もちろんその逆も可能である。</p> ウラル tag:crieit.net,2005:PublicArticle/15907 2020-05-22T10:17:55+09:00 2020-05-22T10:17:55+09:00 https://crieit.net/posts/XPath-2-XPath XPath基礎編(2) ー XPathの書き方 <p>前回の記事では、<a href="https://crieit.net/posts/XPath-1-XPath">XPathの基本概念</a>を簡単に紹介しました。今回はXPathによるWebページ(HTML)からデータを指定・取得する方法、つまりXPathの書き方を紹介します。</p> <h1 id="1.タグ(要素)で指定する"><a href="#1.%E3%82%BF%E3%82%B0%EF%BC%88%E8%A6%81%E7%B4%A0%EF%BC%89%E3%81%A7%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B">1.タグ(要素)で指定する</a></h1> <p>下記のHTMLサンプルで、文章が のように、といった記号で囲まれているのが分かります。このようなといった記号を、タグと言います。</p> <pre><code><タグ名>ここにコンテンツが入ります... </タグ名> </code></pre> <p>最初のタグを「開始タグ」、終わりのタグを「終了タグ」といいます。そしてこの開始タグから終了タグまでの全体を、要素と呼びます。</p> <p>下記のHTMLの中で赤色で表示された部分はタグです。(Firefoxで青色、Chromeでは紫色で表示されます。)<br /> <a href="https://crieit.now.sh/upload_images/ac2152aaa3a20ce773412b967f786c335ec5f9c9b9231.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ac2152aaa3a20ce773412b967f786c335ec5f9c9b9231.png?mw=700" alt="image" /></a></p> <p>下記はHTMLでよく見かけるタグのまとめです。詳しくのは<a target="_blank" rel="nofollow noopener" href="https://www.tagindex.com/html5/elements/">この記事</a>を合わせてご覧ください!<br /> <a href="https://crieit.now.sh/upload_images/3b23cd0e54eb80bd11f5914238779f8b5ec5fa2b21fb0.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/3b23cd0e54eb80bd11f5914238779f8b5ec5fa2b21fb0.png?mw=700" alt="image" /></a></p> <p><strong>XPathの最も一般的な書き方は、スラッシュ “/” で区切りながらタグを記述します。</strong></p> <p>例えば、このHTMLから『Harry Potter』を取得したい場合は、ツリー構造の上から順に『htmlタグ→bodyタグ→h1タグ』と指定できます。次のように書きます。</p> <pre><code>/html/body/h1 </code></pre> <p>また、『//』を用いて、途中までのパスを省略することができます。</p> <pre><code>//h1 </code></pre> <p><a href="https://crieit.now.sh/upload_images/73909d4648ca098024e571d5d2c90ada5ec5fa7109dbf.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/73909d4648ca098024e571d5d2c90ada5ec5fa7109dbf.png?mw=700" alt="image" /></a></p> <p>タグを複数に合致する場合に、N番目のタグを指定することができます。この例では、『7,631円』を取得する場合、「div」の行から2行目の「span」であるため、次のように書きます。</p> <pre><code>//div/span[2] </code></pre> <p>抽象化にすると、タグ(要素)で書くXPath構文はこうなります。</p> <pre><code>//タグ名 //タグ名/タグ名 </code></pre> <h1 id="2.属性で指定する"><a href="#2.%E5%B1%9E%E6%80%A7%E3%81%A7%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B">2.属性で指定する</a></h1> <p>属性とはタグの中に記載されていて、タグの情報を細かく表すものです。タグに属性をつけることで、要素の効果を指定したり、具体的な指示を付け加えることが出来ます。属性は通常、「id="booksTitle"」のように表示されます。なお、属性は複数指定する事も可能です。</p> <pre><code><タグ名 属性名="属性値"> </code></pre> <p>最も一般的な属性には、href、title、style、src、id、classなどがあります。詳しくはこの記事を合わせてご覧ください!</p> <p><strong>XPathでは属性を『@』の関数で表します。</strong></p> <p>例えば、『Harry Potter』を取得したい場合、XPathは次のように書きます。</p> <pre><code>//h1[@id="booksTitle"] </code></pre> <p><a href="https://crieit.now.sh/upload_images/74f53e19cdd3d7db9d3aaa665416865e5ec5fa9fbdc81.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/74f53e19cdd3d7db9d3aaa665416865e5ec5fa9fbdc81.png?mw=700" alt="image" /></a></p> <p>抽象化にすると、属性で書くXPath構文はこうなります。</p> <pre><code>//タグ名[@属性名="属性値"] </code></pre> <p>もし同じ属性を持つすべての要素を取得する場合、次のように書きます。</p> <pre><code>//*[@属性名="属性値"] </code></pre> <h1 id="3.テキストで指定する"><a href="#3.%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%81%A7%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B">3.テキストで指定する</a></h1> <p>下記のようにタグで囲まれているのはテキストです。</p> <pre><code><タグ名>ここにテキストが入ります... </タグ名> </code></pre> <p>Webページからデータを取得するのは、通常ページ内のコンテンツまたはテキストを取得することです。ですから、取得したいテキストを直接指定することができます。</p> <p><strong>XPathではテキストを『text()』の関数で表します。</strong></p> <p>例えば、『Harry Potter』を取得したい場合、テキストで指定すると、次のように書きます。</p> <pre><code>//h1[text()="Harry Potter"] </code></pre> <p><a href="https://crieit.now.sh/upload_images/606ad984d03cb33dbcf324b48fe3ef3a5ec5fae570088.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/606ad984d03cb33dbcf324b48fe3ef3a5ec5fae570088.png?mw=700" alt="image" /></a></p> <p>抽象化にすると、属性で書くXPath構文はこうなります。</p> <pre><code>//タグ名[text()="取得するテキスト"] </code></pre> <p>もし同じテキストを持つすべての要素を取得する場合、次のように書きます。</p> <pre><code>//*[text()="取得するテキスト"] </code></pre> <h1 id="4.タグ関係で指定する"><a href="#4.%E3%82%BF%E3%82%B0%E9%96%A2%E4%BF%82%E3%81%A7%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B">4.タグ関係で指定する</a></h1> <p>HTMLのツリー構造において、すべての要素が親子/兄弟関係を持っています。</p> <p>1つまたは複数の要素を含む要素は親要素と呼ばれ、含まれる要素は子要素です。子要素は1つのみの親があり、親の開始タグと終了タグの間にあります。同じ親を持つ要素は兄弟要素と呼ばれます。</p> <p>具体的な例も見てみましょう。</p> <p>以下のサンプルは、[body]要素を基点に、[body]要素は[h1]要素と[div]要素の親で、[h1]要素と[div]要素は、[body]要素の子です。親子/兄弟関係にある要素を取得し、それぞれにスタイルを変更する例です。</p> <p>[h1]要素と[div]要素は、同じ親[body]要素を持つため、兄弟要素です。</p> <p>また、[div]要素は2つの[span]要素の親ですから、2つの[span]要素は[body]要素の子孫要素です。</p> <p><a href="https://crieit.now.sh/upload_images/ac2152aaa3a20ce773412b967f786c335ec5fb00d4eb2.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ac2152aaa3a20ce773412b967f786c335ec5fb00d4eb2.png?mw=700" alt="image" /></a></p> <p>カレント要素を基点として、親子、もしくは兄弟関係にある要素を取得することができます。例えば、『7,631円』を取得したい場合、タグの関係で指定すると、下記のように書くことができます。</p> <ul> <li><strong>[div]要素の子要素とする場合</strong></li> </ul> <pre><code>//div/span[2] </code></pre> <ul> <li><strong>[body]要素の子孫要素とする場合</strong></li> </ul> <pre><code>//body//span[2] </code></pre> <ul> <li><strong>[span class="author notFaded"]要素の兄弟要素とする場合</strong></li> </ul> <pre><code>//span[@class="author notFaded"]/following-sibling::span[1] </code></pre> <ul> <li><strong>[span class="tax_postage"]要素の兄弟要素とする場合</strong></li> </ul> <pre><code>//span[@class="tax_postage"]/preceding-sibling::span[1] </code></pre> <p>兄弟関係のあるタグを指定するには『following-sibling::』と『preceding-sibling::』という2つの関数をよく使います。</p> <p><strong>『following-sibling::』は、指定された要素より後の兄弟要素を指定する<br /> 『preceding-sibling::』は、指定された要素より前の兄弟要素を指定する</strong></p> <p>『following-sibling::』は、テーブル要素を指定する時に大活躍します。例えば、下記のHTMLサンプルがあります。<br /> <a href="https://crieit.now.sh/upload_images/47e4d5aa57d6e1622c851c7ab7d081235ec5fb78228ea.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/47e4d5aa57d6e1622c851c7ab7d081235ec5fb78228ea.png?mw=700" alt="image" /></a></p> <p>このHTMLはページに変更すると、以下のようなテーブルの形になります。<br /> <a href="https://crieit.now.sh/upload_images/d31f11d0dc981223209a01066480dfcd5ec5fb8c89537.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d31f11d0dc981223209a01066480dfcd5ec5fb8c89537.png?mw=700" alt="image" /></a></p> <p>この例では、店名の『12345』取得します。ただし、[td]要素が複数あり、<strong>//td[1]</strong> で対応できなくなります。また、もし複数のページから、同じ構造のテーブルを一括取得する場合、固定的な値「店名」を基点として、『following-sibling::』を使うほうが薦めです。次のように書きます。</p> <pre><code>//th[text()="店名"]/following-sibling::td[1] </code></pre> <p><a href="https://crieit.now.sh/upload_images/bf91fbab825806d55d50077a1188024a5ec5fb9c4b147.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/bf91fbab825806d55d50077a1188024a5ec5fb9c4b147.png?mw=700" alt="image" /></a></p> <p>抽象化にすると、タグ関係で書くXPath構文はこうなります。<br /> <a href="https://crieit.now.sh/upload_images/79fa6ebb0e474fa3720643700236f4145ec5fbb4e1ce5.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/79fa6ebb0e474fa3720643700236f4145ec5fbb4e1ce5.png?mw=700" alt="image" /></a><br /> もし上記の構文で複数に合致する場合に、<strong>[N]</strong> を付けてN番目のタグを指定することができます。</p> <p>いかがでしょうか?以上は最も使われるXPath書き方です。さっそくお試してみてください。次回はXPathによく使われる関数を紹介します。お楽しみに!</p> <p>元記事:<a target="_blank" rel="nofollow noopener" href="https://helpcenter.octoparse.jp/hc/ja/articles/360013122059">https://helpcenter.octoparse.jp/hc/ja/articles/360013122059</a></p> Octoparse Japan tag:crieit.net,2005:PublicArticle/15905 2020-05-21T12:08:13+09:00 2020-05-21T12:08:13+09:00 https://crieit.net/posts/XPath-1-XPath XPath基礎編(1)ー XPathの基本概念 <p>Webサイト上からデータを自動的に取得するには2つの方法があります。1つはPythonなどのプログラミング言語でWebクローラーを作る、もう1つは<a target="_blank" rel="nofollow noopener" href="https://www.octoparse.jp/">Octoparse</a>のような<a target="_blank" rel="nofollow noopener" href="https://www.octoparse.jp/blog/top-30-free-web-scraping-software/">Webスクレイピングツール</a>でデータを取得するのです。しかし、どれにしても、XPathは重要な役割を果たしています。XPathの書き方が分かれば、データをより正しくて効率的に取得できます。</p> <p>それでXPathのシリーズではXPathの基本概念からXPathの書き方、応用まで詳しく紹介したいと思います。</p> <p>この記事では、XPathの基本概念を簡単に紹介します。</p> <h1 id="1. XPathとは?"><a href="#1.+XPath%E3%81%A8%E3%81%AF%EF%BC%9F">1. XPathとは?</a></h1> <p><a target="_blank" rel="nofollow noopener" href="https://www.octoparse.jp/blog/essential-for-web-scraping-xpath-introduction/">XPath</a> (XML Path Language)とは、ツリー構造となっているXML/HTMLドキュメントからの要素や属性値などを指定するための簡潔な構文(言語)です。<br /> Webページは通常HTMLで記述されるから、XPathはWebページの情報を取得する時によく利用します。ブラウザ(Chrome、Firefoxなど)でWebページのHTMLを表示するする場合、F12キーを押すことで、対応するHTMLドキュメントに簡単にアクセスできます。<br /> <a href="https://crieit.now.sh/upload_images/9df9699255a9f1dfaaa6c977dbd9c7f85ec5ef58a99b5.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/9df9699255a9f1dfaaa6c977dbd9c7f85ec5ef58a99b5.png?mw=700" alt="image" /></a></p> <h1 id="2. XPathの仕組み"><a href="#2.+XPath%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF">2. XPathの仕組み</a></h1> <p>XPathは具体的にはどのように動作するのかを見てみましょう。下記の画像はHTMLドキュメントの一部です。<br /> <a href="https://crieit.now.sh/upload_images/adab33ab3d7b51a493bb3cfb063f098b5ec5efa851b61.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/adab33ab3d7b51a493bb3cfb063f098b5ec5efa851b61.png?mw=700" alt="image" /></a></p> <p>HTMLは、ツリー構造のように、異なるレベルのがあります。この例では、レベル1は<strong>bookstore</strong>で、レベル2は<br /> <strong>book</strong>です。<strong>Title、author、year、price</strong>はすべてレベル3です。</p> <p>山括弧(など)を含むテキストはタグと呼ばれます。HTMLの要素は通常、開始タグと終了タグで構成され、その間にコンテンツが挿入されます。以下の形になります。</p> <pre><code><○○>(開始タグ)ここにコンテンツが入ります... </○○>(終了タグ) </code></pre> <p>XPathはスラッシュ “/” で区切りながら階層を記述し、基準となるノードから別のノードを指定できます。URLと似ています。この例では、要素「author」を検索する場合、XPathは次のようになります。</p> <pre><code>/bookstore/book/author </code></pre> <p>それがどのように機能するかをよりよく理解するには、コンピューター上の特定のファイルを見つける方法を参照してください。<br /> <a href="https://crieit.now.sh/upload_images/0620d07afe9f4535ee22c558c2a575fb5ec5ef88cc427.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/0620d07afe9f4535ee22c558c2a575fb5ec5ef88cc427.png?mw=700" alt="image" /></a></p> <p>「author」という名前のファイルを見つけるには、正しいファイルパスは <strong>\ bookstore \ book \ author</strong>です。</p> <p>コンピューター上のすべてのファイルには独自のパスがあるように、Webページ上の要素もパスがあります。そのパスはXPathで記述されています。</p> <p>ルート要素(ドキュメントの一番上の要素)から始まり、中にあるすべての要素を経由して目標要素に至るXPathは、絶対XPathと呼ばれます。</p> <pre><code>例: /html/body/div/div/div/div/div/div/div/div/div/span/span/span… </code></pre> <p>絶対XPathは長くて混乱する可能性があるため、絶対XPathを単純化するために、「//」を使用して途中までのパスを省略することができます(短いXPathとも呼ばれる)。</p> <p>たとえば、</p> <pre><code>絶対XPath:  /bookstore/book/author 短いXPath:  //author </code></pre> <h1 id="3. XPathを表示・書くには"><a href="#3.+XPath%E3%82%92%E8%A1%A8%E7%A4%BA%E3%83%BB%E6%9B%B8%E3%81%8F%E3%81%AB%E3%81%AF">3. XPathを表示・書くには</a></h1> <h2 id="【Google Chromeの場合】"><a href="#%E3%80%90Google+Chrome%E3%81%AE%E5%A0%B4%E5%90%88%E3%80%91">【Google Chromeの場合】</a></h2> <p>Chromeでこのページを表示し、右クリックメニューの[検証]から開発者ツールを表示します。Elementタブのhtmlで、要素を右クリックします。メニューの[Copy] → [Copy XPath ] でその要素を取得するためのXPathがクリップボードにコピーされます。<br /> <a href="https://crieit.now.sh/upload_images/7abc7bfcf22757417e5d1de2508ecd645ec5efc5ddd9d.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/7abc7bfcf22757417e5d1de2508ecd645ec5efc5ddd9d.png?mw=700" alt="image" /></a></p> <p>表示されているElementタブのhtmlから “Ctrl + F” で検索欄を表示します。XPathを入力すると、得られる要素が選択されるはずです。<br /> <a href="https://crieit.now.sh/upload_images/26083b025f9b75340b4e0133bc0d3c885ec5efd93cb43.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/26083b025f9b75340b4e0133bc0d3c885ec5efd93cb43.png?mw=700" alt="image" /></a></p> <p>また、「XPath Helper」という拡張機能を追加することもできます。XPathを入力すると、一致する結果が表示されます。(<a target="_blank" rel="nofollow noopener" href="https://chrome.google.com/webstore/detail/xpath-helper/hgimnogjllphhhkhlmebbmlgjoejdpjl?hl=zh-CN">XPath Helperをインストールする</a>)<br /> <a href="https://crieit.now.sh/upload_images/2a1ec783d7eb286b630a0cec3a3a6a0f5ec5efeb6a203.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/2a1ec783d7eb286b630a0cec3a3a6a0f5ec5efeb6a203.png?mw=700" alt="image" /></a></p> <p>​</p> <h2 id="【Firefoxの場合】 "><a href="#%E3%80%90Firefox%E3%81%AE%E5%A0%B4%E5%90%88%E3%80%91%E3%80%80">【Firefoxの場合】 </a></h2> <p>Firefoxの旧バージョンに搭載されている拡張機能「Firebug」が利用できます。(<a target="_blank" rel="nofollow noopener" href="https://helpcenter.octoparse.jp/hc/ja/articles/360015765193-Firebug-FireXPath%E6%8B%A1%E5%BC%B5%E6%A9%9F%E8%83%BD%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95">Firebug&FireXPath拡張機能をインストールする方法</a>)</p> <p>FirefoxでWebページを開く➡Firebugボタンをクリック➡ページ内の要素をクリック➡その要素のXPathが表示されます。<br /> <a href="https://crieit.now.sh/upload_images/f00ff934aa298fe710ed30ead91c5db95ec5f00a607c0.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/f00ff934aa298fe710ed30ead91c5db95ec5f00a607c0.png?mw=700" alt="image" /></a></p> <p>以上はXPathの基本概念でした。次回はXPathの書き方を紹介しますので、お楽しみにしてください!</p> <p>元記事:<a target="_blank" rel="nofollow noopener" href="https://helpcenter.octoparse.jp/hc/ja/articles/360015765513">https://helpcenter.octoparse.jp/hc/ja/articles/360015765513</a></p> Octoparse Japan tag:crieit.net,2005:PublicArticle/15536 2019-11-10T10:05:13+09:00 2019-11-10T10:05:13+09:00 https://crieit.net/posts/img imgタグで画像が読み取れなかったときになにも表示しないようにしたい <p><code><img></code>タグを使って画像を表示したときに、読み込めないとこんな感じになる。</p> <pre><code class="html"><img src="https://example.com/noimage.png" alt="プロフィール" /> </code></pre> <p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/4febffe9-ff83-0f72-9a60-c1e159f1a078.png" alt="スクリーンショット 2019-11-10 9.20.29.png" /></p> <p>読み込めない場合に、こんな感じで、なにも表示しないようにしたかったときの備忘録。</p> <p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/6b308bea-be92-c356-a8f2-14ffb4f03988.png" alt="スクリーンショット 2019-11-10 9.25.20.png" /></p> <h3 id="やり方はこんな感じ。"><a href="#%E3%82%84%E3%82%8A%E6%96%B9%E3%81%AF%E3%81%93%E3%82%93%E3%81%AA%E6%84%9F%E3%81%98%E3%80%82">やり方はこんな感じ。</a></h3> <pre><code class="html"><img src="https://example.com/noimage.png" alt /> </code></pre> <p>ポイントは以下の2点</p> <ol> <li><code>alt</code>を空文字で設定</li> <li><code>onerror</code>で<strong>srcを空にして</strong>、<strong>onerrorをnullにする</strong></li> </ol> <h5>1. 「<code>alt</code>を空文字で設定」について</h5> <p>画像が表示されなかった場合に、代わりにalt属性のテキストが表示してくれる<br /> このalt属性がなかった場合、読み取り不可の画像が表示されてしまう。</p> <p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/6022bae1-1d80-bd08-a97a-9fd659e34787.png" alt="スクリーンショット 2019-11-10 9.33.44.png" /></p> <p>なので、alt属性に空文字を指定しておくことで、<br /> 「<strong>画像が表示されなかった場合に、代わりに空文字を表示する</strong>」ようにしている。</p> <h5>2. 「<code>onerror</code>で<strong>srcを空にして</strong>」について</h5> <p><code>onerror</code>属性を設定しておくと、画像の読み取りに失敗した場合に、<br /> 何らかの処理をすることができる。</p> <p><a target="_blank" rel="nofollow noopener" href="https://qiita.com/yuji38kwmt/items/ff3e6faf19760366a787#%E8%80%83%E5%AF%9F">この記事</a>によると、srcとaltがともに空文字だと、読み取り不可の画像が表示されないよう。</p> <blockquote> <p>Firefox, Chrome, IEで、バツ印を非表示にするには、以下のいずれかの状態にする必要があります。<br /> ・src属性が空文字 AND alt属性があり/空文字<br /> ・src属性がなし</p> </blockquote> <p>なので、onerrorを使って、画像が読み取れなかったときに<code>src</code>を空にしている。</p> <h5>3. 「<strong>onerrorをnullにする</strong>」について</h5> <p>また、srcを空文字にすると依然として、画像が読み取れない状態が続くため、<br /> <code>onerror</code>が繰り返し呼び出されるため、<code>onerror</code>が無限に呼ばれ続けることになる。</p> <p>そのため、srcを空にするのとあわせ、<code>onerror</code>を初期化して呼ばれないようにしている。</p> <h1 id="おわりに"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB">おわりに</a></h1> <p>とりあえず、目的は達成できたので、良い感じ。</p> <p>ただ、</p> <ul> <li>srcが空なのでエラーのまま</li> <li>altが空文字</li> </ul> <p>など、よくなさそうなところがあるので、</p> <ul> <li>エラー画像に差し替えたり、</li> <li>JavaScriptで<code><img></code>自体を表示しないようにする</li> </ul> <p>などのほうがお行儀の良いHTMLになりそう。</p> <h2 id="こんなのつくってます!!"><a href="#%E3%81%93%E3%82%93%E3%81%AA%E3%81%AE%E3%81%A4%E3%81%8F%E3%81%A3%E3%81%A6%E3%81%BE%E3%81%99%21%21">こんなのつくってます!!</a></h2> <p>積読用の読書管理アプリ 『積読ハウマッチ』をリリースしました!<br /> <a target="_blank" rel="nofollow noopener" href="https://tsundoku.site">積読ハウマッチ</a>は、Nuxt.js+Firebaseで開発してます!</p> <p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/572d4947-f40b-e4dc-1c9c-bc584cd2a66c.png" width="200"/></p> <p>もしよかったら、遊んでみてくださいヽ(=´▽`=)ノ</p> <p>要望・感想・アドバイスなどあれば、<br /> 公式アカウント(<a target="_blank" rel="nofollow noopener" href="https://twitter.com/MemoryLoverz">@MemoryLoverz</a>)や開発者(<a target="_blank" rel="nofollow noopener" href="https://twitter.com/kira_puka">@kira_puka</a>)まで♪</p> <h1 id="参考にしたサイト"><a href="#%E5%8F%82%E8%80%83%E3%81%AB%E3%81%97%E3%81%9F%E3%82%B5%E3%82%A4%E3%83%88">参考にしたサイト</a></h1> <ul> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/yamaguchi_takashi/items/7019e2e8074bf094333c">imgタグでエラー時の画像をonerror属性で設定する方法 - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://qiita.com/yuji38kwmt/items/ff3e6faf19760366a787">img要素の「画像がないことを表すマーク」の表示/非表示 - Qiita</a></li> <li><a target="_blank" rel="nofollow noopener" href="https://teratail.com/questions/15682">JavaScript - HTMLの画像読み込み時にonerrorを使用した際の無限ループを回避したい。|teratail</a></li> </ul> きらぷか@積読ハウマッチ/SSSAPIなど tag:crieit.net,2005:PublicArticle/15419 2019-09-24T04:49:33+09:00 2019-09-24T04:52:06+09:00 https://crieit.net/posts/3196986630826e80e694cf840dd8f493 意外と簡単!自分のサイトをダークモード対応してみた【技術編】 <p><a href="https://crieit.now.sh/upload_images/ab7fe98314e669b78bed589d5154e4b05d89099d3d9f8.PNG" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ab7fe98314e669b78bed589d5154e4b05d89099d3d9f8.PNG?mw=700" alt="IMG_8789.PNG" /></a></p> <p>スプランプ(<a target="_blank" rel="nofollow noopener" href="https://splamp.info">splamp.info</a>)というサイトの管理人をしているウラルです。</p> <p>来ましたよ、ダークモードの時代が。2019年はダークモード元年です。</p> <h1 id="ダークモードの時代が来た"><a href="#%E3%83%80%E3%83%BC%E3%82%AF%E3%83%A2%E3%83%BC%E3%83%89%E3%81%AE%E6%99%82%E4%BB%A3%E3%81%8C%E6%9D%A5%E3%81%9F">ダークモードの時代が来た</a></h1> <p>何を言っているかお分かりでしょうか。<br /> 実は、2019年はWindows・iOS・Androidという三大OSがダークモード対応をするという、大きな時代の節目なのです。</p> <h2 id="OSの更新日とダークモード設定方法"><a href="#OS%E3%81%AE%E6%9B%B4%E6%96%B0%E6%97%A5%E3%81%A8%E3%83%80%E3%83%BC%E3%82%AF%E3%83%A2%E3%83%BC%E3%83%89%E8%A8%AD%E5%AE%9A%E6%96%B9%E6%B3%95">OSの更新日とダークモード設定方法</a></h2> <p><strong>2019年5月22日</strong><br /> Windows 10 May 2019 Update配信開始。「個人用設定 > 色」から「既定のアプリモード」を「黒」にする。</p> <p><strong>2019年9月4日</strong><br /> Android10配信開始。「設定 > ディスプレイ」から「ダークテーマ」をオンにする。</p> <p><strong>2019年9月20日</strong><br /> iOS13配信開始。「設定 > 画面表示と明るさ」から「外観モード」を「ダーク」にする。</p> <h1 id="Webが対応しないでどうする"><a href="#Web%E3%81%8C%E5%AF%BE%E5%BF%9C%E3%81%97%E3%81%AA%E3%81%84%E3%81%A7%E3%81%A9%E3%81%86%E3%81%99%E3%82%8B">Webが対応しないでどうする</a></h1> <p>個人的な所感ですが、開発者の中でダークモード対応は興味としては薄いように感じます。</p> <p>しかし、Webこそダークモードの流れに乗るべきなのです。なぜなら、ほとんどのWebサイトの背景は真っ白じゃないですか!目が眩むし、夜眠れなくなりそうです。</p> <p>私は、以前からWebサイトでダークモードの対応をしたかったのですが、OSレベルでのダークモード対応が普及していなかったため、ずっと待っていました。サイト内にダークモードボタンを設置しても、ブラウザが真っ白では意味がありませんからね。</p> <p>三大OSが対応した今、もう何も遮るものはありません。</p> <h1 id="CSSだけで実装できる"><a href="#CSS%E3%81%A0%E3%81%91%E3%81%A7%E5%AE%9F%E8%A3%85%E3%81%A7%E3%81%8D%E3%82%8B">CSSだけで実装できる</a></h1> <p>ダークモード対応は、難しい技術が必要なのでしょうか。いいえ、CSSだけでいいんです。</p> <p>CSSのメディアクエリの1つである、<code>prefers-color-scheme</code>を使います。</p> <blockquote> <p><code>prefers-color-scheme</code> は CSS のメディア特性で、ユーザーがシステムに要求したカラーテーマが明色か暗色かを検出するために使用します。<br /> <a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/CSS/@media/prefers-color-scheme">prefers-color-scheme - CSS: カスケーディングスタイルシート | MDN</a></p> </blockquote> <p>構文によると、ダークモードがオンになると<code>prefers-color-scheme</code>が<code>dark</code>になり、オフだと<code>light</code>、そもそも機能を持ち合わせていない場合は<code>no-preference</code>という値になります。</p> <p>実際に利用する場合はどう使うのでしょうか。<br /> おすすめは、CSS変数との併用です。既存の構造を崩さずに、ダークモード用の色彩設定を追加することができます。</p> <p><em>例</em></p> <pre><code class="css">:root { --header-bg: white; --body-bg: white; --body-color: black; } @media (prefers-color-scheme: dark) { :root { --header-bg: hsl(212, 38%, 12%); --wrapper-bg: hsl(212, 40%, 17%); --body-color: #e4e4e4; } } header { background: var(--header-bg); } body { background: var(--body-bg); color: var(--body-color); } </code></pre> <p>CSS変数を参照させることで、ダークモードに切り替わると一斉に色が変わります。</p> <p><img src="https://splamp.info/shed/assets/IMG_8788.GIF" alt="gif" /></p> <p>imgタグの画像の切り替えは若干面倒ですが、私はライト用とダーク用の2つを連続で並べて、CSSで<code>display: none</code>と<code>display: inline</code>を入れ替えるようにしました。</p> <h1 id="大変だけど"><a href="#%E5%A4%A7%E5%A4%89%E3%81%A0%E3%81%91%E3%81%A9">大変だけど</a></h1> <p>これまで白ベースで作ってきたサイトにとっては、ダークモードの対応は破壊的な修正にあたります。角丸で四隅が白い画像だとか、色でごまかしていた要素の境目などを、見直さなければいけません。</p> <p>しかし、それはデメリットばかりではありません。それは、負の遺産になりかけていたCSSを直すチャンスかもしれません。(少なくともうちのサイトは構造から改善しました)</p> <p>三大OSがダークモードに対応した今、時代の流れはダークモード対応です。<br /> 実装自体は簡単ではあるものの、色使いの検討や構造の見直しに割と時間がかかるので、早め早めに手を付けたいものです。<br /> アクセシビリティとか言って、やがて対応に迫られてくるのは間違いありません。</p> <p>次回は【デザイン編】として、ダークモードデザインについて記事にしようと思います。</p> ウラル tag:crieit.net,2005:PublicArticle/15418 2019-09-24T00:05:17+09:00 2019-09-24T00:20:41+09:00 https://crieit.net/posts/Chrome-placeholder-757575 Chromeのplaceholderの色は#757575 <p>HTMLの<code><input></code>や<code><textarea></code>に使われる<code>placeholder</code>属性の文字色は、CSSでは疑似要素<code>::placeholder</code>の中で設定できますが、デフォルトの色が分からなかったので調べました。</p> <p><a href="https://crieit.now.sh/upload_images/f37dd84b36bcbac2749ed7d9d5d7127f5d88e29c1b118.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/f37dd84b36bcbac2749ed7d9d5d7127f5d88e29c1b118.png?mw=700" alt="image.png" /></a><br /> ▲これのことね</p> <h1 id="結果"><a href="#%E7%B5%90%E6%9E%9C">結果</a></h1> <p>Chromeでスポイトで色を取って確認したところ、<code><input></code>も<code><textarea></code>も<code>#757575</code>=<code>rgb(117, 117, 117)</code>=<code>hsl(0, 0%, 46%)</code>でした。</p> <h1 id="感想"><a href="#%E6%84%9F%E6%83%B3">感想</a></h1> <p>デフォルトがCSSでは定義されておらず開発者ツールではわからないので、スポイト使うしかありませんでした(´・ω・`)</p> <p><a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/CSS/::placeholder">https://developer.mozilla.org/ja/docs/Web/CSS/::placeholder</a></p> ウラル tag:crieit.net,2005:PublicArticle/15345 2019-08-23T18:16:09+09:00 2019-08-23T18:16:09+09:00 https://crieit.net/posts/form-input-submit-Enter form inputタグでsubmitボタンが無いとEnterしても送信されない現象の原因 <h1 id="現象"><a href="#%E7%8F%BE%E8%B1%A1">現象</a></h1> <p><a href="https://crieit.now.sh/upload_images/f37dd84b36bcbac2749ed7d9d5d7127f5d5ec894c9348.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/f37dd84b36bcbac2749ed7d9d5d7127f5d5ec894c9348.png?mw=700" alt="image.png" /></a></p> <ul> <li>HTMLで入力フォームを作成する際、<code><input type="submit"></code>(送信ボタン)を使わずに記述したところ、Enterを押してもページが遷移せず、送信されなかった。</li> <li><code><input type="submit"></code>のスタイルに<code>display:none</code>を設定したところ、Chromeでは送信できるようになったがSafariでは送信できないままだった。</li> </ul> <h2 id="該当のコード"><a href="#%E8%A9%B2%E5%BD%93%E3%81%AE%E3%82%B3%E3%83%BC%E3%83%89">該当のコード</a></h2> <pre><code class="html"><form accept-charset="UTF-8" method="post" action=""> <input name="name"> <input name="name2"> </form> </code></pre> <p>実際の動作は<a target="_blank" rel="nofollow noopener" href="https://splamp.info/tests/crieit/form_input.php">用意したこちらのページ</a>で確認してほしい。「項目が複数でsubmitなし」の部分です。</p> <h1 id="原因"><a href="#%E5%8E%9F%E5%9B%A0">原因</a></h1> <p><strong>仕様でした。</strong></p> <p>WHATWGの仕様書を見てみます。<br /> <a target="_blank" rel="nofollow noopener" href="https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#implicit-submission">https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#implicit-submission</a></p> <p>4.10.21 Form submission(以下和訳)</p> <blockquote> <p><strong>4.10.21.2 暗黙的送信</strong></p> <p>form要素の<strong>デフォルトボタン</strong>は、そのform要素に登場する最初のsubmitボタンです。</p> <p>もしブラウザがユーザーの暗黙的送信(例えば、いくつかのプラットフォームではテキスト項目でEnterキーを押すとフォームが送信される)をサポートするのであれば、そのデフォルトボタンが有効であるフォームに対して、デフォルトボタンでclickイベントが発火したように振舞わなければいけません。</p> <blockquote> <p>注:暗黙的送信しか使えないような(submitボタンの無い)ページがWebにはあるので、ブラウザはこれをサポートすることを強く推奨します。</p> </blockquote> <p>フォームにsubmitボタンがない場合、そのフォームが複数の <em>暗黙的送信を妨げるフィールド</em> を持つならば、暗黙的送信メカニズムは何もしてはいけません。そうでないならば、form要素はフォームの内容を送信しなければなりません。</p> <p>form要素を親に持つinput要素で、属性が以下のどれかであれば、それはform要素の暗黙的送信を妨げるフィールドです。 Text, Search, URL, Telephone, E-mail, Password, Date, Month, Week, Time, Local Date and Time, Number</p> </blockquote> <p><strong>暗黙的送信</strong>(Implicit submission)とは、text属性などのinput要素の中でEnterを押すと送信できるように、submitボタンを押さなくても送信できる補助機能のことを指します。</p> <p>ざっくり言うと、フォームが複数のinput要素を持っている場合、submitボタンが無い限り暗黙的送信は行ってはならないと定義されているのです。</p> <p>逆に言えば、submitボタンは無いがフォームのinput要素が1つだけの場合や、フォームのinput要素が複数あるが有効なsubmitボタンが存在する場合は、暗黙的送信ができるということです。</p> <h1 id="対策"><a href="#%E5%AF%BE%E7%AD%96">対策</a></h1> <p>もしあなたが複数のinput要素を送信しようとしているのなら、できる限りsubmitボタンを用意すべきでしょう。submitボタンの書き方は2通りあります。</p> <h3 id="input要素を使う場合"><a href="#input%E8%A6%81%E7%B4%A0%E3%82%92%E4%BD%BF%E3%81%86%E5%A0%B4%E5%90%88">input要素を使う場合</a></h3> <pre><code class="html"><input type="submit"> </code></pre> <p>value属性でボタンに表示されるテキストを編集できます。デフォルトでは「送信」が表示されます。</p> <h3 id="button要素を使う場合"><a href="#button%E8%A6%81%E7%B4%A0%E3%82%92%E4%BD%BF%E3%81%86%E5%A0%B4%E5%90%88">button要素を使う場合</a></h3> <pre><code class="html"><button type="submit">送信</button> </code></pre> <p>input要素と異なり、ボタンの中身はHTMLで記述できます。</p> <p>それでもsubmitボタンを表示したくない場合は、次のようにCSSで消すのが良いでしょう。</p> <pre><code class="html"><button type="submit" style="padding:0;border:0"></button> </code></pre> <p>以上</p> ウラル tag:crieit.net,2005:PublicArticle/15338 2019-08-20T17:41:42+09:00 2019-08-20T17:41:42+09:00 https://crieit.net/posts/HTML-JSX HTMLのノードを直接生成するJSXファクトリを簡単に書いてみた <p>JSXって知っていますか? JSXとは、Reactなどに使われているXML(HTML)とjavascriptの混在記法です。<br /> そして、JSXを内部的に処理する関数をJSXファクトリといいます。<br /> これは、BabelやTypeScriptコンパイラの設定で自由に変更可能です。<br /> ところでWeb Componentsという、新しいHTMLエレメントを自由に作れるjavascriptのAPIが存在するのはご存じでしょうか。</p> <p>これを使えば、Reactのようなことがネイティブのjavascriptでできるのではないだろうか?そう考えたのでやってみることにしました。</p> <p>まずはJSXファクトリの仕様から説明します。<br /> JSXファクトリは以下のようなシグネチャを持つ関数であれば何でも構いません。</p> <pre><code class="javascript">/** * @param element 文字列または関数またはクラス。文字列の場合はタグの名前、クラス・関数の場合はタグが表すコンポーネント。 * @param props 要素の属性。オブジェクトで渡す。存在しない場合はnull。 * @param children 可変長引数で、現在の要素の子要素を渡す。 */ function JSXFactory(element, props, ...children) {} </code></pre> <p>そしてこれは重要なことなのですが、この関数が返す値や動作は何でもよいのです。<br /> JSXとは、単なる糖衣構文でしかありません。つまり、その動作は実装した人にゆだねられます。<br /> 以下に、JSXの変換例を示します。</p> <pre><code class="jsx">import React from 'react'; let node = <div className="hoge">This is child text.</div>; </code></pre> <p>これは以下のようなjavascriptに変換されます。</p> <pre><code class="javascript">import React from 'react'; let node = React.createElement('div', {'className': 'hoge'}, 'This is child text'); </code></pre> <p>そしてこの、React.createElementにあたる関数はtsconfig.json内で以下のように設定できます。</p> <pre><code class="json">{ "compilerOptions": { "jsx": "react", "jsxFactory": "myCreateElement" } } </code></pre> <p>この場合はjsxFactoryにmyCreateElementを設定しているため、React.createElement関数の代わりにmyCreateElementが使われます。<br /> さて、これらの仕様を使って、普通のHTMLノードを生成するJSXファクトリを作ってみたいと思います。<br /> まずは型の宣言から。</p> <pre><code class="typescript">declare namespace JSX { export interface JSXElement<P = {}> {} export interface IntrinsicElements { [elemName: string]: any; } export type GlobalAttributes = EventAttributes | ElementAttributes; export type ElementAttributes = /* HTMLノードのグローバル属性(略) */ export type EventAttributes = /* イベント属性(略) */ } </code></pre> <p>シンプルに行きましょう。<br /> 組み込みの要素の型をいちいち定義していたら日が暮れます。<br /> なのでanyで誤魔化しました。</p> <p>続いては本題のJSXファクトリの実装です。</p> <pre><code class="typescript">import './types'; type PropType<K> = { [P in JSX.GlobalAttributes | keyof K]: any }; export function createElement<K, E extends JSX.JSXElement<K>>( element: E | string, props: PropType<K>, ...children: any[] ): Element { let elem: Element; if (typeof element === 'string') { elem = document.createElement(element); } else { elem = document.createElement( (element as any).name.replace(/(?!^)([A-Z0-9])/g, '-$1').toLowerCase() ); } Object.keys(props || {}) .filter(it => props.hasOwnProperty(it)) .forEach(it => elem.setAttribute(convertPropName(it), props[it as keyof PropType<K>]) ); children.forEach(it => !(it instanceof Element) ? it.hasOwnProperty('render') && typeof it.render === 'function' ? elem.appendChild(it.render()) : elem.append(it.toString()) : elem.appendChild(it) ); return elem; } function convertPropName(name: string): string { switch (name) { case 'className': return 'class'; case 'htmlFor': return 'for'; default: return name; } } </code></pre> <p>やってること自体はきわめて単純。<br /> <code>document.createElement</code>関数でノードを作り、引数に従って属性や子要素を追加しているだけです。<br /> JSXではclassとforがそれぞれclassNameとhtmlForになるため、convertPropName関数はそれを変換します。</p> <p>にしてもJSXファクトリ、かなり面白いですね。<br /> これ使えばいろいろできそうな予感。<br /> React以外でも活用の目はありそうです。</p> frodo821 tag:crieit.net,2005:PublicArticle/15327 2019-08-16T15:05:02+09:00 2019-08-16T15:06:16+09:00 https://crieit.net/posts/CSS-Property-Value-Selector-50 俺的CSS便利Property・Value・Selector 50連発! <p>最近すごくHTMLやCSSを書いている気がするので、ここらでCSSのよく使うプロパティや知っていると便利なプロパティをまとめてみることにしました。早速行ってみましょう!</p> <h1 id="よく使うもの"><a href="#%E3%82%88%E3%81%8F%E4%BD%BF%E3%81%86%E3%82%82%E3%81%AE">よく使うもの</a></h1> <h2 id="1. ::before, ::after"><a href="#1.+%3A%3Abefore%2C+%3A%3Aafter">1. ::before, ::after</a></h2> <p>これを指定した要素の子要素として挿入される疑似要素。子要素を持てない要素(img, inputなど)には指定不可能。<code>content</code>プロパティを指定しない限り挿入されない。なにも入れるcontentがない場合は<code>content: ""</code>を指定する。</p> <h2 id="2. min-height, min-width"><a href="#2.+min-height%2C+min-width">2. min-height, min-width</a></h2> <p>高さや幅の最小値を指定する。mainコンテナのように、必ずある大きさ以上の大きさが必要な要素に指定すると、コンテンツの大きさにかかわらず設定した大きさより小さくならない。</p> <h2 id="3. max-height, max-width"><a href="#3.+max-height%2C+max-width">3. max-height, max-width</a></h2> <p>上の<code>min-</code>系とは逆に、高さや幅の最大値を設定する。指定すると、コンテンツの大きさにかかわらず、設定した大きさより大きくならない。</p> <h2 id="4. order"><a href="#4.+order">4. order</a></h2> <p>HTMLの要素の兄弟順をオーバーライドする。これを指定すると、強制的に兄弟要素の中でその順番になるように表示される。<code>nth-</code>系には影響しない。</p> <h2 id="5. visibility"><a href="#5.+visibility">5. visibility</a></h2> <p><code>display: none</code>と違って、表示したくないけれど領域は確保したいという場合に使える。</p> <h2 id="6. z-index"><a href="#6.+z-index">6. z-index</a></h2> <p>要素の描画順を設定するプロパティ。<code>position: fixed;</code>と使うことが多い。</p> <h2 id="7. clip-path"><a href="#7.+clip-path">7. clip-path</a></h2> <p>要素の見かけの外形を設定するプロパティ。うまく使えばCSSだけでいろんな表現が可能に。</p> <h2 id="8. will-change"><a href="#8.+will-change">8. will-change</a></h2> <p>要素のCSSプロパティがアニメーションで変化することをあらかじめブラウザに知らせる。パフォーマンス爆上がり。</p> <h2 id="9. transform"><a href="#9.+transform">9. transform</a></h2> <p>要素を移動、回転、拡縮、変形させるプロパティ。ちょっと場所がずれるときとか、アニメーションで動かしたいときに便利。</p> <h2 id="10. :root"><a href="#10.+%3Aroot">10. :root</a></h2> <p>root疑似クラス。document.documentElementを指し示すセレクタ。カスタムプロパティと組み合わせると応用範囲は無限大。メディアクエリと組み合わせるとモバイルビュー判定にも使える。</p> <pre><code class="css">@media screen and (max-width: 960px) { :root { --is-mobile: yes; } } @media screen and (min-width: 961px) { :root { --is-mobile: no; } } </code></pre> <h2 id="11. transform-origin"><a href="#11.+transform-origin">11. transform-origin</a></h2> <p>transformプロパティの基準になる点を指定するプロパティ。ローディング画面のスピナなどを作るときなど、意外と使える場面が多い。</p> <h2 id="12. position: relative"><a href="#12.+position%3A+relative">12. position: relative</a></h2> <p><code>position: absolute</code>が親要素を基準とした位置取りにならない!?って思ったときは大概こいつの設定忘れが原因。これが設定された要素の子要素に<code>position: absolute</code>が指定された場合、これが設定された要素を基準とした位置取りになる。</p> <h2 id="13. appearance: none"><a href="#13.+appearance%3A+none">13. appearance: none</a></h2> <p>デフォルトの見た目をなくすプロパティ。input要素に独自のスタイルを当てたいときなど、これを設定するとうまくいくことが多い。</p> <h2 id="14. box-shadow"><a href="#14.+box-shadow">14. box-shadow</a></h2> <p>要素が落とす影を設定するプロパティ。背景が設定されていない要素につけると違和感マシマシ。そういうインラインなテキスト要素に影をつけたい場合は、<code>text-shadow</code>プロパティを使うこと。</p> <h2 id="15. background-clip"><a href="#15.+background-clip">15. background-clip</a></h2> <p>きれいなタイトル文字の修飾をしたいときに。ヘッディング要素の<code>background-image</code>プロパティに適当な画像を設定して、このプロパティの値を<code>text</code>にすると、背景が文字の形で切り抜かれる。</p> <h2 id="16. background-attachment: fixed"><a href="#16.+background-attachment%3A+fixed">16. background-attachment: fixed</a></h2> <p>要素内のコンテンツが動いても、背景を動かしたくない場合に使う。サイトの背景に設定するといい感じになるかも。</p> <h2 id="17. border-radius"><a href="#17.+border-radius">17. border-radius</a></h2> <p>要素を角丸にできる。もはや説明不要。</p> <h2 id="18. :not"><a href="#18.+%3Anot">18. :not</a></h2> <p>セレクタにマッチしない要素にマッチする。例えば、<code>:not(.not-select)</code>というセレクタは、not-selectクラスを持たない要素にマッチする。</p> <h2 id="19. :first-child, :last-child, :nth-child, :nth-last-child"><a href="#19.+%3Afirst-child%2C+%3Alast-child%2C+%3Anth-child%2C+%3Anth-last-child">19. :first-child, :last-child, :nth-child, :nth-last-child</a></h2> <p>指定された順番にある兄弟要素にマッチする疑似クラス。</p> <h2 id="20. :first-of-type, :last-of-type, :nth-of-type, nth-last-of-type"><a href="#20.+%3Afirst-of-type%2C+%3Alast-of-type%2C+%3Anth-of-type%2C+nth-last-of-type">20. :first-of-type, :last-of-type, :nth-of-type, nth-last-of-type</a></h2> <p>指定された順番にある同じタグ(spanどうし、divどうしなど)の兄弟要素にマッチする疑似クラス。</p> <h2 id="21. :required"><a href="#21.+%3Arequired">21. :required</a></h2> <p>required属性のあるformパーツにマッチする。</p> <h2 id="22. :invalid"><a href="#22.+%3Ainvalid">22. :invalid</a></h2> <p>入力された値が要求された形式に従っていないformパーツにマッチする。</p> <h2 id="23. outline"><a href="#23.+outline">23. outline</a></h2> <p>borderの外側に描画されるborderみたいなやつ。borderと違って、それ専用に場所が確保されない。</p> <h2 id="24. attr()"><a href="#24.+attr%28%29">24. attr()</a></h2> <p>print画面でだけ<code>::after</code>疑似要素にurlを表示したいときなど、CSSのプロパティに特定のHTML属性を設定したいときに使用する。</p> <h2 id="25. user-select"><a href="#25.+user-select">25. user-select</a></h2> <p>ユーザーが要素を選択可能かどうかを設定する。spanにclickイベントを設定したときなど、選択されるのが鬱陶しかったり、要素を選択してほしくないときに使う。</p> <h2 id="26. pointer-events"><a href="#26.+pointer-events">26. pointer-events</a></h2> <p>要素のどこがマウスイベントをキャプチャするか指定するプロパティ。オーバーレイなど、ほかの要素より前に出るがマウスイベントをキャプチャしたくない要素には<code>none</code>を設定すると吉。</p> <h2 id="27. cursor"><a href="#27.+cursor">27. cursor</a></h2> <p>要素の上に乗ったカーソルの表示の種類を設定する。ユーザビリティが上がるらしい。</p> <h2 id="28. :checked"><a href="#28.+%3Achecked">28. :checked</a></h2> <p>チェックが入っているチェックボックスにマッチする。うまく活用するとHTML/CSSだけで開閉するメニューなどの2つの状態を持つUIが記述できる。</p> <h2 id="29. display: flex"><a href="#29.+display%3A+flex">29. display: flex</a></h2> <p>要素をflexboxにする。子要素の数によって、自動でいい感じに配置を決めてくれる。すごく便利。ついつい多用しがち。</p> <h2 id="30. justify-content"><a href="#30.+justify-content">30. justify-content</a></h2> <p>要素の配置を決めるプロパティ。上の<code>display: flex</code>と組み合わせて使うことが多い。</p> <h2 id="31. flex-flow"><a href="#31.+flex-flow">31. flex-flow</a></h2> <p>flexboxで、要素を配置する向きを決める。</p> <h2 id="32. flex"><a href="#32.+flex">32. flex</a></h2> <p>flexboxの子要素に指定するプロパティ。flex-grow、flex-shrink、flex-basisの3つを一気に指定できる。flex-growは要素がコンテナより小さいときにどれくらい大きくするか、flex-shrinkは逆に要素がコンテナより大きいときにどれくらい小さくするか、flex-basisは要素がコンテナの中でどれくらいの初期サイズを持っているのかを指定する。</p> <h1 id="そこまで使うわけでもないけど知っていたら便利なもの"><a href="#%E3%81%9D%E3%81%93%E3%81%BE%E3%81%A7%E4%BD%BF%E3%81%86%E3%82%8F%E3%81%91%E3%81%A7%E3%82%82%E3%81%AA%E3%81%84%E3%81%91%E3%81%A9%E7%9F%A5%E3%81%A3%E3%81%A6%E3%81%84%E3%81%9F%E3%82%89%E4%BE%BF%E5%88%A9%E3%81%AA%E3%82%82%E3%81%AE">そこまで使うわけでもないけど知っていたら便利なもの</a></h1> <h2 id="33. position: sticky"><a href="#33.+position%3A+sticky">33. position: sticky</a></h2> <p>これを設定された要素が親要素の中でrelative + fixedのような振る舞いをするようになる。Qiitaのいいねボタンやストックボタンのスマホ版みたいな振る舞いがこれ(とtop, bottom, right, leftプロパティのどれか1つ以上)だけで記述可能。</p> <h2 id="34. text-indent"><a href="#34.+text-indent">34. text-indent</a></h2> <p>行頭字下げをするプロパティ。パラグラフの先頭で字下げしたいときに有効。</p> <h2 id="35. ::first-letter"><a href="#35.+%3A%3Afirst-letter">35. ::first-letter</a></h2> <p>ある要素の中で、最初の文字にマッチする疑似要素。パラグラフの最初の文字だけ大きくするような表現に使える。</p> <h2 id="36. ::select"><a href="#36.+%3A%3Aselect">36. ::select</a></h2> <p>ある要素の中で、現在選択されているものにマッチする疑似要素。選択部分の強調などに使える。</p> <h2 id="37. ::target"><a href="#37.+%3A%3Atarget">37. ::target</a></h2> <p>urlのターゲットになっている要素にマッチする。ページ内リンクで飛んだ先の要素を強調するのに使える。</p> <h2 id="38. perspective"><a href="#38.+perspective">38. perspective</a></h2> <p>transformと組み合わせて使う。遠近法をどの程度かけるか指定するプロパティ。</p> <h2 id="39. transform-style: preserve-3d"><a href="#39.+transform-style%3A+preserve-3d">39. transform-style: preserve-3d</a></h2> <p>これを三次元の移動回転変形を指定したtransformプロパティを持つ要素の親に指定することで、3次元的な描写を可能にすることができる。</p> <h2 id="40. filter"><a href="#40.+filter">40. filter</a></h2> <p>要素に指定したSVGフィルタをかける。<code>::before</code>に指定して背景をぼかしたり、グレイスケール化したり、いろいろな視覚効果を追加することができる。</p> <h2 id="41. ::marker"><a href="#41.+%3A%3Amarker">41. ::marker</a></h2> <p>::marker<br /> リストのマーカーにマッチする疑似要素。</p> <ul> <li>←これがリストのマーカー。</li> </ul> <h2 id="42. ::placeholder"><a href="#42.+%3A%3Aplaceholder">42. ::placeholder</a></h2> <p>formパーツ要素のplaceholderにマッチする。placeholderの色やフォントなどを変えたいときに便利。</p> <h2 id="43. :defined"><a href="#43.+%3Adefined">43. :defined</a></h2> <p>任意のCustomElementにマッチする。</p> <h2 id="44. quotes"><a href="#44.+quotes">44. quotes</a></h2> <p><code><q>~</q></code>のタグを使ったときに表示される引用符を制御できる。それ以外のタグの場合も、以下のようにして利用できる。</p> <pre><code class="css">blockquote { quotes: "「" "」"; } blockquote::before { content: open-quote; } blockquote::after { content: close-quote; } </code></pre> <p>より正確な動作の説明としては「<code>open-quote</code>と<code>close-quote</code>の値を制御する」ということになる。</p> <h2 id="45. text-overflow"><a href="#45.+text-overflow">45. text-overflow</a></h2> <p>文字がコンテナのサイズを超過したときの処理を設定する。<code>...</code>のような記号で省略したり、それ以外の文字で省略したり、あるいはそれ以上を表示しなかったりするような表現が可能。</p> <h2 id="46. writing-mode"><a href="#46.+writing-mode">46. writing-mode</a></h2> <p>文字を縦書きにするか横書きにするか設定できる。サイトの種類によっては多用することもあるかも。</p> <h2 id="47. text-orientation"><a href="#47.+text-orientation">47. text-orientation</a></h2> <p><code>writing-mode</code>を<code>vertical-rl</code>または<code>vertical-lr</code>にしたときに、文字をどの向きで配置するか設定する。</p> <h2 id="48. clear"><a href="#48.+clear">48. clear</a></h2> <p>浮動要素のまわりの固定要素の配置(回り込み)を指定する。浮動要素しか含まないような要素の高さを維持するために使うこともできる。</p> <pre><code class="css">.float-only::after { content: ""; display: block; clear: both; } </code></pre> <h2 id="49. all"><a href="#49.+all">49. all</a></h2> <p>すべてのプロパティを一気に設定できる。親要素からすべてのスタイルを継承したいときや、逆に継承したくないとき、デフォルトの見た目にしたいときに使える。</p> <h2 id="50. touch-action"><a href="#50.+touch-action">50. touch-action</a></h2> <p>要素に対して可能なタッチアクションの種類を制限できる。たとえば、ズームしてほしくないとか、縦方向のスクロールを制限したいとかそういう場合に便利。Cookie Clickerのタッチ領域にこれを指定してほしいと何度思ったことか。</p> <h1 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h1> <p>CSS難しい……。MDNの解説ってプロパティごとに内容の質にけっこうばらつきが大きいんですね。</p> <h1 id="参考"><a href="#%E5%8F%82%E8%80%83">参考</a></h1> <ul> <li>https://developer.mozilla.org/en-US/docs/Web/CSS</li> <li>https://www.w3schools.com/cssref/</li> </ul> <p>Happy Hacking!</p> <p><a target="_blank" rel="nofollow noopener" href="https://www.tech-frodo.xyz/2019/08/useful-css.html">この記事はブログにも投稿しています。</a></p> frodo821 tag:crieit.net,2005:PublicArticle/14801 2019-02-15T01:21:35+09:00 2019-02-25T15:21:06+09:00 https://crieit.net/posts/Python-HTML 純粋なPythonでHTMLを記述するライブラリを作ったから使ってほしいだけの記事 <h2 id="TL;DR"><a href="#TL%3BDR">TL;DR</a></h2> <p>Crieitに記事を投稿するのはすさまじく久しぶりな気がしますが…。<br /> おはようございます、こんにちは、今晩は。Frodoです。</p> <p>さて、今回は自作ライブラリをPyPIに登録したので使ってみてほしいというだけの記事になりますw<br /> どういうライブラリを作ったのかと言いますと、純粋なPythonの構文だけで比較的分かりやすくHTMLを構築するライブラリです。</p> <p>HTMLのテンプレートライブラリと言えばPythonではJinjaが有名でしょうか。<br /> ですが、JinjaはPythonの文法をほとんど全くフォローしておらず、新しくまったく別な言語を覚えることになってしまいます。<br /> よく使われているWebフレームワークのDjangoのテンプレート言語も似たようなものですね。</p> <p>そこで、純粋にPythonの言語機能のみを使ってHTMLを構築できないかと作ったのがRattle.pyです。<br /> Rattle.pyには次のような特徴があります。</p> <ol> <li>小型・軽量であること。Rattle.pyには依存しているライブラリがありません。</li> <li>純粋なPythonの文法のみでHTMLが構築できること。HTMLやPythonが分かっていれば覚えることはほとんどありません。</li> <li>日本語でサポートが受けられること。開発者が日本人ですから当然です。もちろん、英語でのサポートもあります。</li> </ol> <p>説明してもイメージがわかないと思いますので、実際に使ってみたいと思います。</p> <h2 id="実際に使ってみる"><a href="#%E5%AE%9F%E9%9A%9B%E3%81%AB%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B">実際に使ってみる</a></h2> <p>まずはインストールしましょう。話はそれからです。</p> <pre><code class="shell">$ pip install rattlepy </code></pre> <p>このように、普通のライブラリと同様pipで簡単に導入できます。<br /> 使うのも驚くくらい簡単です。</p> <pre><code class="python">from rattlepy.templating import ( html, body, head, title, h1, p, div, span, text, meta, link) with html(lang='ja') as elem: with head(): meta(charset='utf-8') meta(name='viewport', content='initial-scale=1.0;width=device-width') link(href='main.css', rel='stylesheet', type='text/css') with title(): text("Hello, Rattle.py!") with body(): with div(className='container'): with h1(): text("Hello, Rattle.py!") with p(): text("Rattle.py is a html templating library.") with span(className='emphasized'): text("This library can support you to make HTML in pure Python.") print(elem) </code></pre> <p>これを実行するとこうなります。</p> <pre><code class="html"><html lang="ja"> <head> <meta charset="utf-8"/> <meta name="viewport" content="initial-scale=1.0;width=device-width"/> <link href="main.css" rel="stylesheet" type="text/css"/> <title> Hello, Rattle.py! </title> </head> <body> <div class="container"> <h1> Hello, Rattle.py! </h1> <p> Rattle.py is a html templating library. <span class="emphasized"> This library can support you to make HTML in pure Python. </span> </p> </div> </body> </html> </code></pre> <p>このように、非常に簡単にHTMLが記述できるのです。<br /> また、これは純粋なPythonですから、何も考えずにPythonの変数を使ったり関数を呼び出したりできます。<br /> これRattle.pyの特徴です。</p> <h2 id="興味を持っていただけたら"><a href="#%E8%88%88%E5%91%B3%E3%82%92%E6%8C%81%E3%81%A3%E3%81%A6%E3%81%84%E3%81%9F%E3%81%A0%E3%81%91%E3%81%9F%E3%82%89">興味を持っていただけたら</a></h2> <p>このライブラリは開発中で、いろいろと未実装の機能が多くあります。<br /> また、使って頂き、フィードバックや意見がいただけると、それがどのようなものであっても励みになります。</p> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/frodo821/rattlepy">GitHubのリポジトリ</a>もぜひチェックしてみてください。スターなど頂けたら激しく喜びます。<br /> フィードバックや意見は<a target="_blank" rel="nofollow noopener" href="https://twitter.com/BoufrawFrodo2">@BoufrawFrodo2</a>にメンションして送っていただくか、GitHubにissueを立てて頂ければチェックします。<br /> 完全に宣伝な記事でしたが、最後までお付き合いありがとうございました!</p> frodo821 tag:crieit.net,2005:PublicArticle/14726 2019-01-18T09:29:07+09:00 2019-01-18T12:23:31+09:00 https://crieit.net/posts/UI-HTML UIを整えるためにHTMLをデバッグするする方法 <p>HTMLを書いてブラウザで確認している時にどうしても上手く思った通りにならない場合があったりします。配置がうまくいかなかったり、marginやpaddingが思い通りにならなかったりなど。その時の確認方法などをまとめてみました。</p> <p>昔はtableやfloat等が主なレイアウト方法だったのでシンプルでわかりやすかったのですが、CSS3も一般的になり色々と便利になる一方、惑わされる要素も増えてきたような気がします。</p> <p>※ <a href="https://crieit.net/boards/post-request/2e7d073b46d856eccb4e591fa599cb88">記事投稿リクエストボード</a> に投稿していただいた件に対する記事となります。</p> <h2 id="基本的な確認方法"><a href="#%E5%9F%BA%E6%9C%AC%E7%9A%84%E3%81%AA%E7%A2%BA%E8%AA%8D%E6%96%B9%E6%B3%95">基本的な確認方法</a></h2> <p>具体的な話の前にひとまず念の為基本的な確認方法を書いておきます。ご存知の方も多いと思うので適宜読み飛ばしてください。Chromeでの話です。</p> <p>調べたい要素の上で右クリックをするとこのようなメニューが出てきますので、「検証」を選択します。これでその要素が選択された状態でChrome DevToolsが開きます。もしくはF12キーを押して直接Developer Toolsを開いても構いません。</p> <p><a href="https://crieit.now.sh/upload_images/f445e18b21a560b6a255b19346aa348d5c3fca15d4d75.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/f445e18b21a560b6a255b19346aa348d5c3fca15d4d75.png?mw=700" alt="rightmenu.png" /></a></p> <p>するとこのような画面が開きます。</p> <p><a href="https://crieit.now.sh/upload_images/08b1043105d7bcfeebbf2a55d16812c85c3fcb664c73c.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/08b1043105d7bcfeebbf2a55d16812c85c3fcb664c73c.png?mw=700" alt="devtool.png" /></a></p> <p>右上はElementsタブを開いている状態です。右クリックしたあたりが表示されています。マウスカーソルを合わせると、左の画面のようにその箇所がハイライトされます。</p> <p>また、Elementsの要素をクリックすると、その下にCSSの一覧(左)、最終的なサイズやCSSの情報(右)が表示されています。これはDevToolsをウィンドウの右側にドッキングしている状態ですので、実際にどのような使い方をしているかによってこのあたりは変わってきます。適宜使いやすい方法にしてください。</p> <p>謎の挙動がなければ、だいたいはこれでほとんど問題があれば原因は分かると思います。</p> <p>また、CSSの一覧の一番上に<code>element.style</code>という空のスタイルがあると思います。これはその場で自由にスタイルを指定できますので、「このスタイルのせいで動きがおかしくなっているんじゃないか」みたいなものに気づいたらとりあえずここでそれを上書きして試すことで、それが原因か、そうでなく他に原因があるか、というのをすぐ確認することができます。</p> <h2 id="謎の挙動"><a href="#%E8%AC%8E%E3%81%AE%E6%8C%99%E5%8B%95">謎の挙動</a></h2> <p>とはいえ謎の挙動も増えている感じがするので、思いつく限り書いてみます。</p> <h3 id="要素のサイズが思ったとおりにならない"><a href="#%E8%A6%81%E7%B4%A0%E3%81%AE%E3%82%B5%E3%82%A4%E3%82%BA%E3%81%8C%E6%80%9D%E3%81%A3%E3%81%9F%E3%81%A8%E3%81%8A%E3%82%8A%E3%81%AB%E3%81%AA%E3%82%89%E3%81%AA%E3%81%84">要素のサイズが思ったとおりにならない</a></h3> <p>横幅を指定したのに思ったとおりのサイズにならなかったりすると思います。これはわりとCSSのdisplayの設定であることが多いので、displayに指定した値によってどう変わるのかは一通りある程度把握しておいたほうが良いと思います。</p> <h4 id="inline"><a href="#inline">inline</a></h4> <p>これはspanタグやaタグのように、文章中にそのまま含めるようなタグのデフォルトのdisplayとして使われています。下記のような特徴があります。</p> <ul> <li>要素のサイズを指定しても無視される</li> <li>marginやpaddingも指定しても無視される</li> </ul> <p>しかしこれらを変えたい、という場合もあると思います。その場合は下記を使います。</p> <h4 id="inline-block"><a href="#inline-block">inline-block</a></h4> <p>これを指定すると、inline要素として文章中に並べながら要素のサイズやmargin, paddingのようなスペースを設定することができます。</p> <h4 id="block"><a href="#block">block</a></h4> <p>これは文章中などには含まず、ページ上のレイアウトを構成するための基本的な枠になります。何も指定しなければ基本的には横幅100%の要素となります。これも要素のサイズやpadding, marginは自由に設定することができます。</p> <h4 id="その他"><a href="#%E3%81%9D%E3%81%AE%E4%BB%96">その他</a></h4> <p>とりあえず基本的には上記のdisplayがベースになっています。ただ、最近は色々増えていたりするので後述します。その他、このあたりはどんどん増えていっているのでだんだんと新しいものを覚えていく必要があります。しっかり覚える必要はないと思いますが、何かあった時の問題解決のために「そういえばこういうのもあったな」くらいのフォローはしていったほうが良さそうです。</p> <h3 id="heightが0になる"><a href="#height%E3%81%8C0%E3%81%AB%E3%81%AA%E3%82%8B">heightが0になる</a></h3> <p>要素内にfloatスタイルの要素のみがある場合、親要素のサイズは連動しないためheightが0になります。</p> <p><a href="https://crieit.now.sh/upload_images/ccc543ce9d27c586c2b2b08f8dc757175c411798ada33.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ccc543ce9d27c586c2b2b08f8dc757175c411798ada33.png?mw=700" alt="" /></a></p> <p>問題がある場合はclearfixを入れたり、あとはoverflowスタイルを入れることでも対処できるようです。もしくはflexbox等に変更するなどで対応しましょう。</p> <h3 id="位置調整をしても無視される"><a href="#%E4%BD%8D%E7%BD%AE%E8%AA%BF%E6%95%B4%E3%82%92%E3%81%97%E3%81%A6%E3%82%82%E7%84%A1%E8%A6%96%E3%81%95%E3%82%8C%E3%82%8B">位置調整をしても無視される</a></h3> <p>左に1つ目の要素を起き、そのすぐ右隣に2つ目の要素を起きたいのになぜか2つ目の要素が想定した位置に行かない、という場合。</p> <p>全て自分で作っているCSSなどの場合には気づかないといったことは少ないかもしれませんが、よく使われているCSSフレームワーク等ですと最近はFlexboxがよく使われているため、それによって位置が決まってしまったりします。下記のまとめ等を見るとわかりやすいと思います。</p> <p><a target="_blank" rel="nofollow noopener" href="https://coliss.com/articles/build-websites/operation/css/css3-flexbox-properties-by-scotch.html">CSS Flexbox の各プロパティの使い方を詳しく解説 | コリス</a></p> <h3 id="横幅を指定しても無視される"><a href="#%E6%A8%AA%E5%B9%85%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%A6%E3%82%82%E7%84%A1%E8%A6%96%E3%81%95%E3%82%8C%E3%82%8B">横幅を指定しても無視される</a></h3> <p>前述のFlexboxのページにも解説がありますが、<code>flex-grow</code>を指定すると要素のサイズも固定されてしまいます。</p> <p><a href="https://crieit.now.sh/upload_images/6104d656841f5bdd41de12c15ecba1d85c411b1a28eaf.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/6104d656841f5bdd41de12c15ecba1d85c411b1a28eaf.png?mw=700" alt="flexglow.png" /></a></p> <p>この場合むりやり横幅を指定したりしても正常には動作しません。</p> <h3 id="beforeやafter"><a href="#before%E3%82%84after">beforeやafter</a></h3> <p>現在はbeforeやafterを使うこともできるため、実際の要素でなくそのあたりの設定でズレが生じてしまうこともあります。これもDeveloper Toolsで見ることができるため、確認するようにしてみてください。</p> <p><a href="https://crieit.now.sh/upload_images/c63ae1144a6799ccaf1bea54929e49f75c411ce8d0fbb.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/c63ae1144a6799ccaf1bea54929e49f75c411ce8d0fbb.png?mw=700" alt="after.png" /></a></p> <h3 id="iframeが使われている"><a href="#iframe%E3%81%8C%E4%BD%BF%E3%82%8F%E3%82%8C%E3%81%A6%E3%81%84%E3%82%8B">iframeが使われている</a></h3> <p>iframeがあっても一応要素のサイズを見ることはできるのですが、どうも状態によっては正しくDeveloper Toolsでもちゃんとサイズが見れなかったりする場合があるような気がします。この場合はiframe内の謎挙動を無視できるようにCSSを整えていくしかないかもしれません。</p> <h2 id="動きのあるコンテンツを調べたい場合"><a href="#%E5%8B%95%E3%81%8D%E3%81%AE%E3%81%82%E3%82%8B%E3%82%B3%E3%83%B3%E3%83%86%E3%83%B3%E3%83%84%E3%82%92%E8%AA%BF%E3%81%B9%E3%81%9F%E3%81%84%E5%A0%B4%E5%90%88">動きのあるコンテンツを調べたい場合</a></h2> <p>一瞬だけ出てくるアニメーション等を調べたい場合、F8で一時停止することができます。これで時を止めて要素を調べることで解決できます。</p> <h2 id="まとめ"><a href="#%E3%81%BE%E3%81%A8%E3%82%81">まとめ</a></h2> <p>今のところこれくらいしか思いつかなかったので、もし何か思いついたら追記します。他にも追記すべき情報があればコメントいただければ追記させていただきます。(もしくは詳しい方が記事を書いていただけると助かります)</p> <p>昔は本当にDeveloper Toolsでひたすら調べればなんとかなったのですが、FlexboxやGrid等、新しい機能が追加される度に、デバッグするためにはだんだんと頑張るだけではなく、知識も必要になってきています。可能な範囲でHTML、CSSの新しい情報は追っていくといざデバッグする時に役に立つと思われます。</p> だら@Crieit開発者