前置き
チャットシリーズ
ようやくCSSです✨笑
初めにデザインを決めていなかったので
ざっくりですが、整理していきました。
そのためSP対応も未完ですが、
⬆️上の画像イメージを元に
作成しています🍎
今後はこの辺をやっていきたいですね🎈🧸
・SP対応
・スクロール、スクロールボタンの実装
・エディタの使用
(選択テキストをコード化させる)
・日付に応じて「今日」「昨日」の表示
メッセージを吹き出しにする
チャットインターフェイスなどでググって
出てきた画像を参考にしました。
アプリのチャットインターフェース設計に役立つアイディア48選
max-width
は400px
にしています。
SPだと280px
くらいが良さそう。
border-radius
って
一律で設定するのが
一般的なので、
1箇所だけ0
にすることで
吹き出しを作る発想が
面白いなと思いました💫😁
これを使う場合は
他の値を少なくとも10px
にはしないと
尖った部分との差が分かりにくいな
と感じました🤔💭
⬇️こういう吹き出しも
素敵だなと思ったので
これはこれでやってたいですね🌟
画像と吹き出しを切り離す
画像の場合は
吹き出し不要だなと思っていますが…
前回の記事でエディタ導入を
検討し始めたので
こちらの挙動などを確認しながら
今後、進めていきます。
textareaの選択した文字に装飾(ボツネタ)
現段階ではここまで。
エディタだけの記事が
あっても良さそう。
メッセージ入力form部分を調整する
名前の入力を消す
そういえば
Firebase Authenticationで
アカウント作成時に
表示用の名前を作る機能って
あるのかな…🤔💭
と思っていたらありました!!!
[Firebase][iOS] Firebase Authentication で会員機能を作ってみよう
ということで
ログインできれば
いちいち表示名を入力する必要がないことが
わかりました💡
Firebaseで表示名を
作れないわけがないですよね…!😂笑
ということで今回はそこの実装は省き、
とりあえずCSSを優先し、
名前入力のinputを非表示にしています。
fill変更
画像アップロードボタンの
主張が強かったので
色を変更しています。
#888888にするため#
を%23
にし%23888888
と書き換えればOKです。
1 |
background-image: url('data:image/svg+xml, <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="%23888888" d="M5 8.5c0-.828.672-1.5 1.5-1.5s1.5.672 1.5 1.5c0 .829-.672 1.5-1.5 1.5s-1.5-.671-1.5-1.5zm9 .5l-2.519 4-2.481-1.96-4 5.96h14l-5-8zm8-4v14h-20v-14h20zm2-2h-24v18h24v-18z"/></svg>'); |
message入力部分の変更
spanを取る
名前とメッセージを区別する必要が
なくなったので取り除きます🤏
右下の//を消す
リサイズするための物なのでresize: none;
でなくなります。
リサイズできなくなるので
入力部分の大きさを決めておきます💫
placeholder
を
中央にするためにpadding
で調整してます。
1 2 3 4 5 6 7 8 9 |
> textarea { border-radius: 14px; resize: none; height: 32px; padding-top: 5px; padding-left: 8px; max-width: 1200px; width: 1200px; } |
placeholder
は
iPhoneとAndroidでの
調整が必要そうです。
2016年の記事なので
変わっているかも❓
iPhoneとAndroidのブラウザによるplaceholderの上下位置
1番下に固定
fixed
で固定します。
1 2 3 4 5 |
&.submit { position: fixed; bottom: 0; width: 100%; } |
コード
Vuex部分は調整中のため
HTML/CSSのみ
参考になればと思います🙏
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
<template> <div class="page"> <form class="form" @submit.prevent > <label class="label"> <span class="label"> email </span> <input class="input" type="text" v-model="email" > </label> <label class="label"> <span class="label"> password </span> <input class="input" type="password" v-model="password" > </label> <button class="button" type="submit" @click="login" > Login </button> </form> <ul> <li v-for="post in posts" :key="post.id" :class="{ me: user.email === post.userId}" > <div> <p>{{ post.name }} <span>{{ $dayjs(post.time).format('MM/DD HH:mm') }}</span></p> <div> <img v-if="post.thumbnail" :src="post.thumbnail" alt="" > <p v-html="post.message">{{ post.message }}</p> </div> </div> </li> </ul> <form class="submit" @submit.prevent > <label class="img" > <input type="file" class="file" @change="changeImg" > </label> <img :src="user.thumbnail" alt=""> <!-- <label> <span> 名前: </span> <input type="text" v-model="user.name" > </label> --> <label> <textarea v-model="user.message" placeholder="message" > </textarea> </label> <button type="submit" @click="submit" > Submit </button> </form> </div> </template> <script> import axios from 'axios' import firebase from '@/plugins/firebase' export default { async fetch ({ store }) { await store.dispatch('chat/getData') }, computed: { posts () { return this.$store.getters['chat/posts'] }, loginUser () { return this.$store.getters['chat/loginUser'] }, }, data () { return { email: '', password: '', thumbnail: '', user: { email: '', name: "", message: "", thumbnail: '', }, } }, methods: { submit () { this.$store.dispatch('chat/submit', { name: this.user.name, message: this.user.message, userId: this.user.email, thumbnail: this.user.thumbnail }) this.user.name = '' this.user.message = '' }, login(email, password) { this.$store.dispatch('chat/login', { email: this.email, password: this.password }) }, changeImg (e) { this.thumbnail = e.target.files[0] if (this.thumbnail) { const reader = new FileReader() reader.onload = () => { this.user.thumbnail = reader.result + '' } reader.readAsDataURL(this.thumbnail) } }, }, } </script> <style lang="scss" scoped> .page { > ul { margin-top: 100px; padding: 24px; > li { display: flex; margin-bottom: 16px; &:last-child { margin-bottom: 0; } &.me { justify-content: flex-end; > div { > p { text-align: right; } > div { margin-top: 5px; background-color: #FF9888; color: white; padding: 10px 16px; border-radius: 14px 0 14px 14px; } } } > div { max-width: 400px; > p { font-weight: 600; > span { font-size: 12px; font-weight: 500; color: #888888; } } > div { margin-top: 5px; background-color: #F1F3F2; padding: 10px 16px; border-radius: 0 14px 14px 14px; } img { width: 100px; } } } } > form { padding: 20px; background-color: #FFF5F3; display: flex; align-items: center; justify-content: space-between; > label, button { display: block; &.img { width: 32px; height: 32px; background-image: url('data:image/svg+xml, <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="%23888888" d="M5 8.5c0-.828.672-1.5 1.5-1.5s1.5.672 1.5 1.5c0 .829-.672 1.5-1.5 1.5s-1.5-.671-1.5-1.5zm9 .5l-2.519 4-2.481-1.96-4 5.96h14l-5-8zm8-4v14h-20v-14h20zm2-2h-24v18h24v-18z"/></svg>'); background-repeat: no-repeat; background-size: cover; } > input, textarea { border: 1px solid #FF9888; &.file { display: none; } } > textarea { border-radius: 14px; resize: none; height: 32px; padding-top: 5px; padding-left: 8px; max-width: 1200px; width: 1200px; } } img { height: auto; display: none; } &.submit { position: fixed; bottom: 0; width: 100%; } } } </style> |
まとめ
まずはやってみる、
で進めてきました❣️
案外できることは分かりましたが…
後からVuexの移行をしたり
デザインで迷ったり🎨💦
非効率だなと思いました🤣笑
事前に決めることの
大切さを実感しております。
とはいえ、
「background-imageでSVG使えるんだ🤭」
「エディタ使わなきゃダメなんだ😯」
「ユーザーの表示名つくれるんだ😀」
など新しい発見もあって良かったです❣️
現実的にできる部分が見えてきたことが
私にとっての報酬でした🍎
実装までのイメージが湧かず
ググっても無理だろうな…
現実的じゃないな…
となってしまうと、
やる気が微塵も起きないので…😂笑
事前の要件定義、設計、デザインを含めて
記事にしてみるのも面白いな〜
と思っています🎈🧸
デザインのトレンド、
進化が凄い(語彙力。。。)
ついに出た!2021年注目のWebデザイン人気トレンド9個まとめ
実装については、
全工程をスムーズにまとめて
別記事や動画などに
できれば良いなと思っています♪