tag:crieit.net,2005:https://crieit.net/tags/vuetify/feed 「vuetify」の記事 - Crieit Crieitでタグ「vuetify」に投稿された最近の記事 2021-12-27T23:20:34+09:00 https://crieit.net/tags/vuetify/feed tag:crieit.net,2005:PublicArticle/17895 2021-12-27T23:20:34+09:00 2021-12-27T23:20:34+09:00 https://crieit.net/posts/Web-61c9cbb273b27 【個人開発】踏破した都道府県を日本地図でシェアできるWebサービス「日本踏破図🗾」を作りました <h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2> <p>「日本踏破図🗾」というWebサービスをNuxt × Vuetifyで個人開発しました!</p> <p><a target="_blank" rel="nofollow noopener" href="https://traverse-japan.dev/">日本踏破図🗾</a></p> <h2 id="どんなWebサービスか"><a href="#%E3%81%A9%E3%82%93%E3%81%AAWeb%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%81%8B">どんなWebサービスか</a></h2> <p>踏破した都道府県を日本地図でチェックすることができ、自分が今までに日本をどれだけ踏破したかをみんなにシェアできます👍<br /> 以下のように日本地図上で都道府県をチェックできます。これをシェアボタンでシェアすると・・・<br /> <a href="https://crieit.now.sh/upload_images/c21a19f689e6b03b8fd32ed155a13cc561c9c9f546005.gif" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/c21a19f689e6b03b8fd32ed155a13cc561c9c9f546005.gif?mw=700" alt="cap3.gif" /></a></p> <p>以下のようなOGP画像でシェア可能です!地図のカラーも好きな色に変更することができます。<br /> <a href="https://crieit.now.sh/upload_images/c96a5c5d12e327a1c82680dd58a2f4c261c9c899adde1.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/c96a5c5d12e327a1c82680dd58a2f4c261c9c899adde1.png?mw=700" alt="cap2.png" /></a></p> <h2 id="使用したフレームワーク・インフラなど"><a href="#%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%9F%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%BB%E3%82%A4%E3%83%B3%E3%83%95%E3%83%A9%E3%81%AA%E3%81%A9">使用したフレームワーク・インフラなど</a></h2> <ul> <li>NuxtJS(Nuxt Bridge)</li> <li>Vuetify</li> <li>vuex(vuex-module-decorators)</li> <li>PWA</li> <li>Vercel(Serverless Functions)</li> </ul> <p>主なものになります。多機能なWebサービスではないのでそんなに色々使ってはいません。<br /> よく使うNuxtとVuetifyでフロントを構築して、Nuxtの<a target="_blank" rel="nofollow noopener" href="https://v3.nuxtjs.org/concepts/server-engine/">Nitroエンジン</a>を使ってVercelのServerless Functionsへデプロイしています。</p> <p>当初はSSRにするつもりはなかったのですが、動的OGPを実装するために色々試行錯誤した結果SSRにしました。ただ、Nuxt3/Nuxt Bridgeから使えるようになったNitroエンジンのおかげで高速&ゼロコンフィグでVercelを利用できます。</p> <h2 id="苦労したところ"><a href="#%E8%8B%A6%E5%8A%B4%E3%81%97%E3%81%9F%E3%81%A8%E3%81%93%E3%82%8D">苦労したところ</a></h2> <h3 id="動的OGPをどう実装するか"><a href="#%E5%8B%95%E7%9A%84OGP%E3%82%92%E3%81%A9%E3%81%86%E5%AE%9F%E8%A3%85%E3%81%99%E3%82%8B%E3%81%8B">動的OGPをどう実装するか</a></h3> <p>正確に言うと「いかに簡単かつ無料で実装するか」に苦労しました。<br /> 検索するとfirebaseを使ってmetaだけSSRしたものを返してリダイレクトさせる等々、実現方法自体は色々でてきます。</p> <p>ただ、正直なところこの規模・機能のWebサービスにそこまでしたくなかったんですね(できるだけシンプルな作りにするということも最初に決めていました)</p> <p>最終的に実装した方法は以下です。</p> <ol> <li>OGP画像を生成して画像を返すServerless Functionsを用意する</li> <li>Functionsへ画像生成に必要な情報(チェック済みの都道府県、地図カラー)を渡す</li> </ol> <p>必要な情報をURLパラメータに持ち、それを利用してmetaタグのog:imageのエンドポイントを作っています。<br /> そのためサービス自体はSSRする必要がありますがVercelを使えば十分な無料枠でServerless FunctionsでSSRできます。</p> <p>個人的には下手にhackyな方法をとるよりも、SSRが必要な場面ではおとなしくSSRしておいた方が良い気がします🤔<br /> (結局のところTwitter・Facebookのクローラーのためだけにあれこれやりたくない)</p> <p>ちなみにNetlifyに<a target="_blank" rel="nofollow noopener" href="https://docs.netlify.com/site-deploys/post-processing/prerendering/">Prerendering</a>という機能があるのですが、これを有効にすることで事前レンダリングされたHTMLを返すことができます。<br /> SPA構成にしてPrerenderingを試してみたのですが、どうもPrerenderingの対象はUserAgentを見ているだけらしくTwitterクローラーであればNetlify Functionsのエンドポイントも問答無用でPrerenderingされるみたいでした。<br /> なのでOGP画像を返すはずのFunctionsがTwitterクローラーの時はPrerenderingされてHTMLを返すようになってしまい、OGP画像が表示されず使えませんでした。。</p> <p>まぁ、NetlifyのPrerenderingはキャッシュ時間(24〜48時間)もコントロールできないし、なによりBETAなのでまだ実用的ではないですね。。</p> <h3 id="サイトデザイン"><a href="#%E3%82%B5%E3%82%A4%E3%83%88%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3">サイトデザイン</a></h3> <p>デザインというのはセンスだと思っています。つまるところ、それを磨くためには多大な時間・努力が必要ということです😉<br /> 私はデザイナーではないのでそこについて時間をかけて勉強するのは得策ではありません。<br /> 悩み・試行した結果、全体的にカードベースのデザインになりました。</p> <p>また、根本のデザインはいわゆるUIフレームワークに頼るわけですが今回はよく使うVuetifyを利用しました。Vuetifyのコンポーネントを使うことで何も考えずそこそこきれいなサイトができあがります。</p> <p><a target="_blank" rel="nofollow noopener" href="https://vuetifyjs.com/ja/">https://vuetifyjs.com/ja/</a></p> <p>ただ、今回は個人的にやってみたいと思っていたGlassmorphism(グラスモーフィズム)チックなデザインを実装しました。<br /> これが間違いで、Vuetifyはマテリアルデザインを実装するフレームワークなんですね。それに対してマテリアルデザインからかけ離れるようなものを実装すると色々と歪みが生じます🙃</p> <p>importantを使ってVuetifyのcssを上書きして実装しましたが、こういうことをする場合はTailwind CSSを利用するべきでした。。</p> <p><a target="_blank" rel="nofollow noopener" href="https://tailwindcss.com/">https://tailwindcss.com/</a></p> <h2 id="運営コストについて"><a href="#%E9%81%8B%E5%96%B6%E3%82%B3%E3%82%B9%E3%83%88%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">運営コストについて</a></h2> <p>現状、ドメイン代オンリーです。<br /> 上の方でも少し書いていますが個人開発においては<strong>無料で運営できること</strong>にこだわっています。</p> <p>まぁ、お金はかからないに越したことはないし、お金がかかってくるとちゃんとメンテしなくちゃとか、マネタイズ考えないと!とか思ってしまうわけですが無料であればひとまず放置で問題ないですからね。</p> <p>ちなみに、このWebサービスでは最初からマネタイズは一切考えていません。機能的にサービス自体がマネタイズにつながるものでもないですがアドセンス等の広告等も一切はらないと決めて開発をスタートしました。</p> <h2 id="サイトパフォーマンスについて"><a href="#%E3%82%B5%E3%82%A4%E3%83%88%E3%83%91%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%B3%E3%82%B9%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6">サイトパフォーマンスについて</a></h2> <p>使っている技術からもわかるかと思いますが、パフォーマンスは問題なく良いです。<br /> 特にSSRするとやっぱり初期描画のパフォーマンスがすごいです(コールドスタート時以外)</p> <p>いくら無料のインフラにこだわっているかといってパフォーマンスを犠牲にしたらお話にならないですからね😉</p> <p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/271387/b46f5426-3ef1-c2d9-327f-071178f7d3b2.png" alt="image.png" /></p> <h2 id="機能の説明"><a href="#%E6%A9%9F%E8%83%BD%E3%81%AE%E8%AA%AC%E6%98%8E">機能の説明</a></h2> <p>日本踏破図🗾でできることを改めて説明させていただきます。</p> <h3 id="日本地図で踏破した都道府県をチェック"><a href="#%E6%97%A5%E6%9C%AC%E5%9C%B0%E5%9B%B3%E3%81%A7%E8%B8%8F%E7%A0%B4%E3%81%97%E3%81%9F%E9%83%BD%E9%81%93%E5%BA%9C%E7%9C%8C%E3%82%92%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF">日本地図で踏破した都道府県をチェック</a></h3> <p><a href="https://crieit.now.sh/upload_images/8bd592eed3b0970775e45c8493e1361161c9ca82b4032.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/8bd592eed3b0970775e45c8493e1361161c9ca82b4032.png?mw=700" alt="image.png" /></a></p> <p>日本地図上の都道府県を選択することができます。選択状況した数によって日本をどれくらい踏破したかがわかります。<br /> また、シェアボタンから踏破した都道府県をシェアすることができます❗</p> <h3 id="日本地図のメニュー"><a href="#%E6%97%A5%E6%9C%AC%E5%9C%B0%E5%9B%B3%E3%81%AE%E3%83%A1%E3%83%8B%E3%83%A5%E3%83%BC">日本地図のメニュー</a></h3> <p><a href="https://crieit.now.sh/upload_images/8bd592eed3b0970775e45c8493e1361161c9ca9f1b976.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/8bd592eed3b0970775e45c8493e1361161c9ca9f1b976.png?mw=700" alt="image.png" /></a></p> <p>地図メニューから、それぞれの機能を利用できます。</p> <ul> <li>地図をリセットする(都道府県の選択状態・色をリセットする)</li> <li>地図の色を変える(日本地図の色を変更できます)</li> <li>日本を踏破する(すべての都道府県を選択状態にします)</li> <li>コピー(日本地図をクリップボードへコピーします)</li> <li>ダウンロード(日本地図をpng画像としてダウンロードします)</li> </ul> <h3 id="チェックボックス"><a href="#%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9">チェックボックス</a></h3> <p><a href="https://crieit.now.sh/upload_images/8bd592eed3b0970775e45c8493e1361161c9cab5eba93.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/8bd592eed3b0970775e45c8493e1361161c9cab5eba93.png?mw=700" alt="image.png" /></a></p> <p>日本地図上から都道府県を選択する以外に、チェックボックスでも選択することができます。チェックボックスで選択すれば連動して日本地図上の都道府県も選択状態になります。</p> <h2 id="ソースコード"><a href="#%E3%82%BD%E3%83%BC%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89">ソースコード</a></h2> <p>日本踏破図🗾のソースコードはMITライセンスで公開しています👉</p> <p><a target="_blank" rel="nofollow noopener" href="https://github.com/k-urtica/traverse-japan">https://github.com/k-urtica/traverse-japan</a></p> <h2 id="さいごに"><a href="#%E3%81%95%E3%81%84%E3%81%94%E3%81%AB">さいごに</a></h2> <p>登録ログイン不要で使えるのでぜひ使ってみてください。<br /> よろしくおねがいします!</p> <p>🌐 サイト:<a target="_blank" rel="nofollow noopener" href="https://traverse-japan.dev/">https://traverse-japan.dev/</a><br /> 👀 開発:<a target="_blank" rel="nofollow noopener" href="https://twitter.com/k_urtica">K</a><br /> 🚩 ソース:<a target="_blank" rel="nofollow noopener" href="https://github.com/k-urtica/traverse-japan">https://github.com/k-urtica/traverse-japan</a></p> <h2 id="おまけ"><a href="#%E3%81%8A%E3%81%BE%E3%81%91">おまけ</a></h2> <p>Web ToolBoxというブラウザで無料で使えるツール集を公開しています。<br /> こちらもよろしくおねがいします。</p> <p><a target="_blank" rel="nofollow noopener" href="https://web-toolbox.dev/">https://web-toolbox.dev/</a></p> K@個人開発バックエンドエンジニア tag:crieit.net,2005:PublicArticle/16210 2020-11-10T18:19:54+09:00 2020-11-10T18:22:30+09:00 https://crieit.net/posts/Apache-Laravel-Vue-js-Vuetify-web 【Apache Laravel Vue.js Vuetify】webアプリをスマホに対応させるためにやったこと <p>Apache+Laravel+Vue.js+Vuetify で作った社内ツールをスマホ対応したときに行った作業内容メモ。<br /> <del>ほんとにiosが嫌いになりそうだった</del></p> <p>対応ブラウザは、</p> <ul> <li>chrome(PC, Android, ios)</li> <li>safari(ios)</li> </ul> <h2 id="まずはiPhone、Androidのデバッグが出来るように準備する"><a href="#%E3%81%BE%E3%81%9A%E3%81%AFiPhone%E3%80%81Android%E3%81%AE%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E3%81%8C%E5%87%BA%E6%9D%A5%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E6%BA%96%E5%82%99%E3%81%99%E3%82%8B">まずはiPhone、Androidのデバッグが出来るように準備する</a></h2> <p>それぞれの端末を持っていれば、PCに繋いでデバッグができる!なんて素晴らしい。<br /> iosはiPhone以外にもiPad、iPod touch でも問題なし。<br /> それぞれ以下を参考に。</p> <p>Android:<a target="_blank" rel="nofollow noopener" href="https://qiita.com/hojishi/items/12b726f8b02ef3d713e4">https://qiita.com/hojishi/items/12b726f8b02ef3d713e4</a><br /> ios:<a target="_blank" rel="nofollow noopener" href="https://webkatu.com/archives/ios-safari-debug-on-windows/">https://webkatu.com/archives/ios-safari-debug-on-windows/</a></p> <h2 id="Polyfillを入れる"><a href="#Polyfill%E3%82%92%E5%85%A5%E3%82%8C%E3%82%8B">Polyfillを入れる</a></h2> <p><a target="_blank" rel="nofollow noopener" href="https://v2.vuetifyjs.com/ja/getting-started/browser-support/">Vuetifyの公式ドキュメント</a>に則って入れればOK。</p> <pre><code class="bash">npm install babel-polyfill --save npm install @babel/preset-env --save </code></pre> <p>インストール後、<br /> <code>import Vue from 'vue'</code> とか<br /> <code>import vuetify from '@/plugins/vuetify</code><br /> を書いているファイルに、<br /> <code>import 'babel-polyfill'</code> を追加。<br /> (自分の場合は <code>/resources/assets/js/app.js</code>)</p> <p>ルートディレクトリの .babelrcに、</p> <pre><code> { "presets": ["@babel/preset-env"] } </code></pre> <h2 id="対応していないjsを地道に直す"><a href="#%E5%AF%BE%E5%BF%9C%E3%81%97%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84js%E3%82%92%E5%9C%B0%E9%81%93%E3%81%AB%E7%9B%B4%E3%81%99">対応していないjsを地道に直す</a></h2> <p>特に問題なければ、↑を行えば画面は表示されるはず…と思っていたのだが、画面が真っ白だった。</p> <p>エラーを調べると、どうやら正規表現で後読みを使っているのが原因みたいだったので、該当箇所を修正。<br /> (safariは後読みに対応していない)</p> <p>※書いている最中に気づいたけど、それってつまりうまくPolyfillが使えていなかったのでは…??</p> <h2 id="「Error: Network Error POST 応答を解析できません」を直す"><a href="#%E3%80%8CError%3A+Network+Error%E3%80%80POST++%E5%BF%9C%E7%AD%94%E3%82%92%E8%A7%A3%E6%9E%90%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%9B%E3%82%93%E3%80%8D%E3%82%92%E7%9B%B4%E3%81%99">「Error: Network Error POST 応答を解析できません」を直す</a></h2> <p>iosのみ起きる謎現象。これに2日かかった…<br /> 自分は、Apacheの設定を変更で直った。</p> <pre><code><Directory "/var/www/html/public"> AllowOverride All # Allow open access: Header unset Upgrade ←これを追加 </Directory> </code></pre> <p>とりあえずここまでで画面が開けるようになりました。<br /> 以降は細かい部分です。</p> <h2 id="スクロールを入れたくないのにスマホだと入ってしまう"><a href="#%E3%82%B9%E3%82%AF%E3%83%AD%E3%83%BC%E3%83%AB%E3%82%92%E5%85%A5%E3%82%8C%E3%81%9F%E3%81%8F%E3%81%AA%E3%81%84%E3%81%AE%E3%81%AB%E3%82%B9%E3%83%9E%E3%83%9B%E3%81%A0%E3%81%A8%E5%85%A5%E3%81%A3%E3%81%A6%E3%81%97%E3%81%BE%E3%81%86">スクロールを入れたくないのにスマホだと入ってしまう</a></h2> <p>webアプリ全体にスクロールを入れたくない場合、bodyに<code>height:100%</code>とか入れればPCでは大丈夫だったりしたんですが、<br /> スマホだとどうにも謎のスクロールが入ってしまうので、以下のように対応。</p> <pre><code class="html"><html id="content">  … </code></pre> <p>※jsでhtmlのところにstyleを指定する方法がわからなかったのでid属性を無理やり、、、</p> <pre><code class="js">const windowHeight = window.innerHeight; // windowの高さを取得 // <html>の高さを、windowsの高さいっぱいに設定 document.getElementById("content").style.height = windowHeight + "px"; // bodyはheight:100% document.body.style.height = "100%"; // スクロールバー非表示 // スマホのときはbodyに、PCのときはhtmlにかけないと反映されないっぽいので分ける const isSP = /iPhone|iPod|iPad|Android/i.test(navigator.userAgent); if (isSP) { document.body.style.overflowY = "hidden"; } else { document.getElementById("content").style.overflowY = "hidden"; } </code></pre> <p>…無理矢理感半端ないけど、ひとまずこれでPCでもスマホでも画面いっぱいでコンテンツが収まるようになった。</p> <h2 id="iosだけ、キーボードのenterでボタンクリック判定されてしまう"><a href="#ios%E3%81%A0%E3%81%91%E3%80%81%E3%82%AD%E3%83%BC%E3%83%9C%E3%83%BC%E3%83%89%E3%81%AEenter%E3%81%A7%E3%83%9C%E3%82%BF%E3%83%B3%E3%82%AF%E3%83%AA%E3%83%83%E3%82%AF%E5%88%A4%E5%AE%9A%E3%81%95%E3%82%8C%E3%81%A6%E3%81%97%E3%81%BE%E3%81%86">iosだけ、キーボードのenterでボタンクリック判定されてしまう</a></h2> <p>PCやAndroidでは大丈夫なのに、iosだけ起きる謎現象。<br /> 改行する度にボタンが押されて送信されるという、、、、</p> <p>※単純にv-formのsubmitイベントが発火してしまっている場合は、<a target="_blank" rel="nofollow noopener" href="https://riotz.works/articles/lopburny/2019/07/31/page-reload-issue-by-implicit-submission/">こちら</a>を参考に。</p> <p>根本的な原因はわからなかったため、<br /> 入力文字が空欄・改行のみの場合は、ボタンクリックで呼ばれる処理が走らないようにした。</p> <pre><code class="html"><textarea v-model="inputText"></textarea> <v-btn @click="submit()">送信</v-btn> </code></pre> <pre><code class="js"><br />data: () => ({ inputText: "", }), computed: { /** * 空文字判定 */ isTextEmpty() { return !this.inputText || !this.inputText.match(/\S/g); }, }, methods: { submit() { if (this.isTextEmpty) return; // 以下送信処理 } } </code></pre> <h2 id="iosだけファイルアップロードができない"><a href="#ios%E3%81%A0%E3%81%91%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%81%8C%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84">iosだけファイルアップロードができない</a></h2> <p>ファイル選択のダイアルボックスを開く→ファイルを選択→アップロード<br /> という流れのとき、iosだけダイアルボックスが開かないという謎現象。<br /> エラーも出ない…</p> <p>調べてみたら、どうやら<code>input.onchange</code>が動いていないようだった。</p> <pre><code class="javascript">function uplod() { return new Promise(resolve => { const input = document.createElement('input'); input.type = "file"; input.multiple = false; input.accept = "image/gif,image/jpeg,image/png"; input.onchange = event => { var file = event.target.files[0]; resolve(file); }; input.click(); }); } </code></pre> <p>ios以外は↑でも動いたが、どうやらiosではちゃんと<code><input></code>要素をDOMに追加してあげないといけないらしい。<br /> 参考:<a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/47664777/javascript-file-input-onchange-not-working-ios-safari-only">https://stackoverflow.com/questions/47664777/javascript-file-input-onchange-not-working-ios-safari-only</a></p> <p>というわけで、以下のように修正</p> <pre><code class="javascript">function uplod() { return new Promise(resolve => { const input = document.createElement('input'); input.type = 'file'; input.multiple = false; input.accept = "image/gif,image/jpeg,image/png"; document.body.appendChild(input); // ←DOMに追加 input.onchange = event => { var file = event.target.files[0]; document.body.removeChild(input); // ←DOMから削除 resolve(file); }; input.click(); }); } </code></pre> <h2 id="iosだけ画像が縦に伸びる時"><a href="#ios%E3%81%A0%E3%81%91%E7%94%BB%E5%83%8F%E3%81%8C%E7%B8%A6%E3%81%AB%E4%BC%B8%E3%81%B3%E3%82%8B%E6%99%82">iosだけ画像が縦に伸びる時</a></h2> <p>これは別記事にもメモしてあるが、<br /> <code>display:flex;</code>を指定している箇所に、<code>align-items: flex-start;</code>を追記するだけ。<br /> 参考:<a target="_blank" rel="nofollow noopener" href="https://nichiyogogo.com/image-looks-stretched/">https://nichiyogogo.com/image-looks-stretched/</a></p> <h2 id="iosだけ、heightを指定した要素内の「overflow-y: visible scroll;」が効かない"><a href="#ios%E3%81%A0%E3%81%91%E3%80%81height%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%97%E3%81%9F%E8%A6%81%E7%B4%A0%E5%86%85%E3%81%AE%E3%80%8Coverflow-y%3A+visible+scroll%3B%E3%80%8D%E3%81%8C%E5%8A%B9%E3%81%8B%E3%81%AA%E3%81%84">iosだけ、heightを指定した要素内の「overflow-y: visible scroll;」が効かない</a></h2> <p>これもiosの一部で起きる現象。<br /> safariのバージョンの問題かもしれない。</p> <p>ますは<a target="_blank" rel="nofollow noopener" href="https://shanabrian.com/web/html-css-js-technics/css-ios-safari-02.php">ここ</a>を参考に修正。<br /> 自分はこのときにも頑なに<code>overflow-y: visible scrol</code>と書き続けていたら直らず、<br /> 素直に <code>overflow-y:auto;</code> にするだけで解決…。</p> <h2 id="おわり"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A">おわり</a></h2> <p>ほとんどios対応ですね。<br /> Androidはグリッドをちゃんと設定して、表示崩れしないようにだけしてあげれば殆ど動きました。<br /> マジでiosとsafariが嫌いになりそうだった…。</p> みみみみみ tag:crieit.net,2005:PublicArticle/15356 2019-08-27T18:28:49+09:00 2019-08-27T18:30:00+09:00 https://crieit.net/posts/CSS-Bluma-Vuetify-Element-Bootstrap-etc CSSフレームワークのブレイクポイントを比べて(Bluma, Vuetify, Element, Bootstrap, etc..) <p>いま開発している<a target="_blank" rel="nofollow noopener" href="https://tsundoku.site">積読用の読書管理アプリ</a>では、CSSフレームワークに<a target="_blank" rel="nofollow noopener" href="https://bulma.io/">Bluma</a>を使ってる。<br /> 昔は、VuetifyやBootstrapを使っていたけど、ブレイクポイントが違っているのでまとめてみた(<em>´ω`</em>)</p> <h2 id="ブレイクポイントのまとめ"><a href="#%E3%83%96%E3%83%AC%E3%82%A4%E3%82%AF%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88%E3%81%AE%E3%81%BE%E3%81%A8%E3%82%81">ブレイクポイントのまとめ</a></h2> <div class="table-responsive"><table> <thead> <tr> <th></th> <th>xs</th> <th>sm</th> <th>md</th> <th>lg</th> <th>xl</th> </tr> </thead> <tbody> <tr> <td>Bluma</td> <td>< 769</td> <td>< 1024</td> <td>< 1216</td> <td>< 1408</td> <td>1408</td> </tr> <tr> <td>Bootstrap</td> <td>< 576</td> <td>< 767</td> <td>< 992</td> <td>< 1200</td> <td>1200</td> </tr> <tr> <td>MaterialDesign</td> <td>< 600</td> <td>< 1024</td> <td>< 1440</td> <td>< 1920</td> <td>1920</td> </tr> <tr> <td>Vuetify</td> <td>< 600</td> <td>< 960</td> <td>< 1264</td> <td>< 1904</td> <td>1904</td> </tr> <tr> <td>Material-UI</td> <td>< 600</td> <td>< 960</td> <td>< 1280</td> <td>< 1920</td> <td>1920</td> </tr> <tr> <td>Element</td> <td>< 768</td> <td>< 992</td> <td>< 1200</td> <td>< 1920</td> <td>1920</td> </tr> <tr> <td>TwilwindCSS</td> <td>< 640</td> <td>< 768</td> <td>< 1024</td> <td>< 1280</td> <td>1280</td> </tr> </tbody> </table></div> <p>だいたい5段階になってるっぽい。上限や下限がそれぞれ違うのがおもしろい(<em>´ω`</em>)<br /> ちなみに単位はpx。収まらなかったので省略...</p> <h2 id="調べたのはこの7つ"><a href="#%E8%AA%BF%E3%81%B9%E3%81%9F%E3%81%AE%E3%81%AF%E3%81%93%E3%81%AE7%E3%81%A4">調べたのはこの7つ</a></h2> <ol> <li>Bluma ... <a target="_blank" rel="nofollow noopener" href="https://bulma.io/documentation/overview/responsiveness/">Responsiveness | Bulma</a></li> <li>Bootstrap ... <a target="_blank" rel="nofollow noopener" href="https://getbootstrap.com/docs/4.3/layout/overview/#responsive-breakpoints">Overview · Bootstrap</a></li> <li>Material Design ... <a target="_blank" rel="nofollow noopener" href="https://material.io/design/layout/responsive-layout-grid.html#breakpoints">Responsive layout grid - Material Design</a></li> <li>Vuetify ... <a target="_blank" rel="nofollow noopener" href="https://vuetifyjs.com/ja/customization/breakpoints">Breakpoints — Vuetify.js</a></li> <li>Material-UI ... <a target="_blank" rel="nofollow noopener" href="https://material-ui.com/customization/breakpoints/#breakpoints">Breakpoints - Material-UI</a></li> <li>Element ... <a target="_blank" rel="nofollow noopener" href="https://element.eleme.io/#/en-US/component/layout#responsive-layout">Component | Element</a></li> <li>Twilwind CSS ... <a target="_blank" rel="nofollow noopener" href="https://tailwindcss.com/docs/breakpoints/#app">Breakpoints - Tailwind CSS</a></li> </ol> <p>Material DesingはCSSフレームワークではないけど参考として。</p> <h3 id="Bluma"><a href="#Bluma">Bluma</a></h3> <p>参照元: <a target="_blank" rel="nofollow noopener" href="https://bulma.io/documentation/overview/responsiveness/">Responsiveness | Bulma: Free, open source, & modern CSS framework based on Flexbox</a></p> <p>まずは使っているBluma。<br /> Bluma独特なのが、コードがxsなどではなく、デバイスの種類になっている点。<br /> classに書くときもわかりやすい。が、全体的に狭い範囲で細かい切り替えになっているよう。</p> <div class="table-responsive"><table> <thead> <tr> <th>コード</th> <th>説明</th> <th>範囲</th> </tr> </thead> <tbody> <tr> <td>mobile</td> <td>Mobile</td> <td>< 769px</td> </tr> <tr> <td>tablet</td> <td>Tablet</td> <td>< 1024px</td> </tr> <tr> <td>desktop</td> <td>Desktop</td> <td>< 1216px</td> </tr> <tr> <td>widescreen</td> <td>Widescreen</td> <td>< 1408px</td> </tr> <tr> <td>fullhd</td> <td>FullHD</td> <td>1408px</td> </tr> </tbody> </table></div> <pre><code class="css">// Extra Small (phones) // Small devices (tabletS) @media (min-width: 770px) { ... } // Medium devices (desktops) @media (min-width: 1024px) { ... } // Large devices (widescreen desktops) @media (min-width: 1216px) { ... } // Extra large devices (fullhd desktops) @media (min-width: 1408px) { ... } </code></pre> <h3 id="Bootstrap"><a href="#Bootstrap">Bootstrap</a></h3> <p>参照元: <a target="_blank" rel="nofollow noopener" href="https://getbootstrap.com/docs/4.3/layout/overview/#responsive-breakpoints">Overview · Bootstrap</a></p> <p>xsのブレイクポイントが一番小さいのが印象的。</p> <div class="table-responsive"><table> <thead> <tr> <th>コード</th> <th>説明</th> <th>範囲</th> </tr> </thead> <tbody> <tr> <td>xs</td> <td>portrait phones</td> <td>< 576px</td> </tr> <tr> <td>sm</td> <td>landscape phones</td> <td>< 767px</td> </tr> <tr> <td>md</td> <td>tablets</td> <td>< 992px</td> </tr> <tr> <td>lg</td> <td>desktops</td> <td>< 1200px</td> </tr> <tr> <td>xl</td> <td>large desktops</td> <td>1200px</td> </tr> </tbody> </table></div> <pre><code class="css">// Extra Small (portrait phones) // Small devices (landscape phones) @media (min-width: 576px) { ... } // Medium devices (tablets) @media (min-width: 768px) { ... } // Large devices (desktops) @media (min-width: 992px) { ... } // Extra large devices (large desktops) @media (min-width: 1200px) { ... } </code></pre> <h3 id="Material Design"><a href="#Material+Design">Material Design</a></h3> <p>参照元: <a target="_blank" rel="nofollow noopener" href="https://material.io/design/layout/responsive-layout-grid.html#breakpoints">Responsive layout grid - Material Design</a></p> <p>ホントの分類はこんな感じ。<br /> 縦向き・横向きでそれぞれ決められているので、かなり細かい。</p> <div class="table-responsive"><table> <thead> <tr> <th>コード</th> <th>説明</th> <th>範囲</th> </tr> </thead> <tbody> <tr> <td>xsmall</td> <td>Portrait: small handset</td> <td>< 360px</td> </tr> <tr> <td>xsmall</td> <td>Portrait: medium handset</td> <td>< 400px</td> </tr> <tr> <td>xsmall</td> <td>Portrait: large handset</td> <td>< 480px</td> </tr> <tr> <td>xsmall</td> <td>Portrait: large handsetLandscape: small handset</td> <td>< 600px</td> </tr> <tr> <td>small</td> <td>Portrait: small tabletLandscape: medium handset</td> <td>< 720px</td> </tr> <tr> <td>small</td> <td>Portrait: large tabletLandscape: large handset</td> <td>< 840px</td> </tr> <tr> <td>small</td> <td>Portrait: large tabletLandscape: large handset</td> <td>< 960px</td> </tr> <tr> <td>small</td> <td>Landscape: small tablet</td> <td>< 1024px</td> </tr> <tr> <td>medium</td> <td>Landscape: large tablet</td> <td>< 1280px</td> </tr> <tr> <td>medium</td> <td>Landscape: large tablet</td> <td>< 1440px</td> </tr> <tr> <td>large</td> <td></td> <td>< 1600px</td> </tr> <tr> <td>large</td> <td></td> <td>< 1920px</td> </tr> <tr> <td>xlarge</td> <td></td> <td>1920px</td> </tr> </tbody> </table></div> <pre><code class="css">// Extra Small (phones) // Small devices (portrait tablets) @media (min-width: 600px) { ... } // Medium devices (landscape tablets) @media (min-width: 1024px) { ... } // Large devices (laptops) @media (min-width: 1440px) { ... } // Extra large devices (desktops) @media (min-width: 1920px) { ... } </code></pre> <h3 id="Vuetify"><a href="#Vuetify">Vuetify</a></h3> <p>参照元: <a target="_blank" rel="nofollow noopener" href="https://vuetifyjs.com/ja/customization/breakpoints">Breakpoints — Vuetify.js</a></p> <p>Material Designを実現するためのCSSフレームワークなので、<br /> Material Designと区分けが近いが、少し異なるので注意が必要かも?</p> <div class="table-responsive"><table> <thead> <tr> <th>コード</th> <th>説明</th> <th>範囲</th> </tr> </thead> <tbody> <tr> <td>xs</td> <td>small to large handset</td> <td>< 600px</td> </tr> <tr> <td>sm</td> <td>small to medium tablet</td> <td>< 960px</td> </tr> <tr> <td>md</td> <td>large tablet to laptop</td> <td>< 1264px</td> </tr> <tr> <td>lg</td> <td>desktop</td> <td>< 1904px</td> </tr> <tr> <td>xl</td> <td>4k and ultra-wides</td> <td>1904px</td> </tr> </tbody> </table></div> <pre><code class="css">// Extra Small (small to large handset) // Small devices (small to medium tablet) @media (min-width: 600px) { ... } // Medium devices (large tablet to laptop) @media (min-width: 960px) { ... } // Large devices (desktop) @media (min-width: 1264px) { ... } // Extra large devices (4k and ultra-wides) @media (min-width: 1904px) { ... } </code></pre> <h3 id="Material-UI"><a href="#Material-UI">Material-UI</a></h3> <p>参照元: <a target="_blank" rel="nofollow noopener" href="https://material-ui.com/customization/breakpoints/#breakpoints">Breakpoints - Material-UI</a></p> <p>こちらもMaterial Designを実現するためのCSSフレームワーク。<br /> ドキュメントには詳しい説明がないが、「Material DesignのSpecをsimplifiedしたぜ」とのこと。</p> <div class="table-responsive"><table> <thead> <tr> <th>コード</th> <th>説明</th> <th>範囲</th> </tr> </thead> <tbody> <tr> <td>xs</td> <td>extra-small</td> <td>< 600px</td> </tr> <tr> <td>sm</td> <td>small</td> <td>< 960px</td> </tr> <tr> <td>md</td> <td>medium</td> <td>< 1280px</td> </tr> <tr> <td>lg</td> <td>large</td> <td>< 1920px</td> </tr> <tr> <td>xl</td> <td>extra-large</td> <td>1920px</td> </tr> </tbody> </table></div> <pre><code class="css">// Extra Small // Small devices @media (min-width: 600px) { ... } // Medium devices @media (min-width: 960px) { ... } // Large devices @media (min-width: 1280px) { ... } // Extra large devices @media (min-width: 1920px) { ... } </code></pre> <h3 id="Element UI"><a href="#Element+UI">Element UI</a></h3> <p>参照元: <a target="_blank" rel="nofollow noopener" href="https://element.eleme.io/#/en-US/component/layout#responsive-layout">Component | Element</a></p> <p>こちらもMaterial-UIと同様に、あまり説明はない。<br /> smやmdの値が少し独自な感じ。</p> <div class="table-responsive"><table> <thead> <tr> <th>コード</th> <th>説明</th> <th>範囲</th> </tr> </thead> <tbody> <tr> <td>xs</td> <td>extra small viewports</td> <td>< 768px</td> </tr> <tr> <td>sm</td> <td>small viewports</td> <td>< 992px</td> </tr> <tr> <td>md</td> <td>medium viewports</td> <td>< 1200px</td> </tr> <tr> <td>lg</td> <td>large viewports</td> <td>< 1920px</td> </tr> <tr> <td>xl</td> <td>extra large viewports</td> <td>1920px</td> </tr> </tbody> </table></div> <pre><code class="css">// Extra Small // Small devices @media (min-width: 768px) { ... } // Medium devices @media (min-width: 992px) { ... } // Large devices @media (min-width: 1200px) { ... } // Extra large devices @media (min-width: 1920px) { ... } </code></pre> <h3 id="Tailwind CSS"><a href="#Tailwind+CSS">Tailwind CSS</a></h3> <p>参照元: <a target="_blank" rel="nofollow noopener" href="https://tailwindcss.com/docs/breakpoints/#app">Breakpoints - Tailwind CSS</a></p> <p>他と比べ、全体的に低めな値が印象的。</p> <div class="table-responsive"><table> <thead> <tr> <th>コード</th> <th>説明</th> <th>範囲</th> </tr> </thead> <tbody> <tr> <td>xs</td> <td>phones</td> <td>< 640px</td> </tr> <tr> <td>sm</td> <td>tablet</td> <td>< 768px</td> </tr> <tr> <td>md</td> <td></td> <td>< 1024px</td> </tr> <tr> <td>lg</td> <td>laptop</td> <td>< 1280px</td> </tr> <tr> <td>xl</td> <td>desktop</td> <td>1280px</td> </tr> </tbody> </table></div> <pre><code class="css">// Extra Small // Small devices @media (min-width: 640px) { ... } // Medium devices @media (min-width: 768px) { ... } // Large devices @media (min-width: 1024px) { ... } // Extra large devices @media (min-width: 1280px) { ... } </code></pre> <h2 id="おわりに"><a href="#%E3%81%8A%E3%82%8F%E3%82%8A%E3%81%AB">おわりに</a></h2> <p>いろんなフレームワークを横串で見ていくといろいろおもしろい。<br /> 個別の対応をどこまで考えないといけないかなども見えてくるかも。<br /> 実際にBlumaを使ってるけど、xs以下のサイズは、個別でブレイクポイントを設定したりなども。</p> <p>新しいものを使うときはいろいろ見ないといけない(<em>´ω`</em>)</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%E3%80%82">こんなのつくってます。</a></h2> <p>最近、積読用の読書管理アプリ「積読ハウマッチ」をリリースしました!<br /> <a target="_blank" rel="nofollow noopener" href="https://tsundoku.site">積読ハウマッチ</a>は、Nuxt.js+Firebaseで開発してます!<br /> CSSフレームワークにBlumaを使ってます(<em>´ω`</em>)</p> <p><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478782/572d4947-f40b-e4dc-1c9c-bc584cd2a66c.png" width="25%"/></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> きらぷか@積読ハウマッチ/SSSAPIなど