LoginSignup
2
0

More than 3 years have passed since last update.

【Nuxt.js】form実践編:contenteditableでイライラ解消!

Posted at

前置き

formで使うinput, textarea
中でも何かと使い勝手の悪いtextareaさん😕
HTMLのグローバル属性
contenteditableを使って
textareaをもっと見やすくしてみましょう!

textarea
textarea.gif

contenteditable
div.gif

contenteditableって?

簡単にいうと編集モードにしてくれます。
分かりやすくbuttonタグにつけました。
編集できる+文字数に応じて幅が変化してくれます!
button.gif

index.vue
<template>
 <button
   contenteditable="true"
 >
   編集できるよ
 </button>
</template>

使いやすさ比較

・textareaの場合
・div contenteditable="true"の場合

textareaにcontenteditable="true"は
使えないため擬似的にtextareaを作成🌟

◾️textarea
・基本的に高さが固定されるので全体が見えない
 リサイズボタンで拡大縮小できるけど
・横幅も動いて見にくい
・リサイズボタンがデザインできない
 resize: none;で消してしまうと拡大縮小できない
・色々使い勝手が悪い
textarea.gif

◾️div contenteditable="true"
・横幅だけ固定してしまえば
・縦幅が文字数に応じて伸縮し
 とっても見やすい!!✨👀
div.gif

コード

◾️div contenteditable="true"の場合
textareaをdiv contenteditable="true"に変更!
今回は複数行になるためrole="textbox"も追加💡

cssはtextareaとほとんど変わりません。
ただし当然ですがinput, textareaの
placeholder属性は使えません😣

Contenteditable.vue
<template>
 <label
  class="contenteditable"
 >
  <span class="label">
    {{ label }}
  </span>
  <div
    class="contenteditable"
    contenteditable="true"
    role="textbox"
    @input="$emit('input', $event.target.textContent)"
  />
 </label>
</template>

<script>
export default {
props: {
  label: {
    type: String,
    default: 'label',
  },
}
</script>

<style lang="scss" scoped>
.contenteditable {
  display: flex;
  align-items: flex-start;

  > .label {
    color: red;
    font-weight: bold;
    width: 64px;
    min-width: 64px;
    padding-top: 4px;
  }

  > .textarea {
    width: calc(100% - 64px);
    min-height: 70px;
    padding: 8px 12px;
    border: 2px solid red;
  }
}
</style>
```vue

```vue:index.vue
<template>
 <div class="page">
   <Contenteditable
     label="LABEL"
     @input="text = $event"
   />
 </div>
</template>

<script>
import Contenteditable from '~/components/Contenteditable.vue'

export default {
 components: {
   Contenteditable,
 },
 data () {
  return {
   text: "",
  }
 },
}
</script>

◾️textareaの場合

chromeだとフォントサイズが
小さく見えることがあります。
なのでtextareaの場合のみ
font-size: 100%; を追記します✍️

デフォルトのフォントサイズ16pxを指定すると
font-familyも変わる場合があるようです。

font-size: 100%;

または

font-size: 16px;
font-family: 'フォント名'

Textarea.vue
<template>
 <label
  class="textarea"
 >
  <span class="label">
    {{ label }}
  </span>
  <textarea
    :placeholder="placeholder"
    class="textarea"
    @input="$emit('input', $event.target.textContent)"
  />
 </label>
</template>

<script>
export default {
props: {
  label: {
    type: String,
    default: 'label',
  },
  placeholder: String,
}
</script>

<style lang="scss" scoped>
.textarea {
  display: flex;
  align-items: flex-start;

  > .label {
    color: red;
    font-weight: bold;
    width: 64px;
    min-width: 64px;
    padding-top: 4px;
  }

  > .textarea {
    font-size: 100%;
    width: calc(100% - 64px);
    min-height: 70px;
    padding: 8px 12px;
    border: 2px solid red;
  }
}
</style>
index.vue
<template>
 <div class="page">
   <Textarea
     label="LABEL"
     placeholder="ここに入力してください"
     @input="text = $event"
   />
 </div>
</template>

<script>
import Textarea from '~/components/Textarea.vue'

export default {
 components: {
   Textarea,
 },
 data () {
  return {
   text: "",
  }
 },
}
</script>

記事が公開したときにわかる様に、
note・Twitterフォローをお願いします😀

https://twitter.com/aLizlab

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0