質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

2回答

3518閲覧

ScrollHeightがコンテンツで定義した高さより大きくなることがある

IkazoIchikawa

総合スコア38

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

1クリップ

投稿2018/08/11 11:15

編集2018/08/12 06:17

問題点

textareaの高さと幅を動的に変化させるJavaScriptを作成しようとしています。

<textarea>を表示させる段階で、必要な高さと幅を計算して表示すれば、
定義範囲をはみ出さないように(オーバーフローせずに)表示できると考えたのですが、
予め決めたコンテンツの高さに余分な余白をつけた高さを、ブラウザが付加してしまい、
表示させるつもりがなかったスクロールバーが表示されてしまい、困っています。
(margin, border, padding0にしたとしても、です。)

文章での説明が難しいので、
実験的に以下URLにあるようなコードを作成しました。

margin, border, padding0にして、
コンテンツ表示域を100px、コンテンツの高さを200pxにしてわざとオーバーフローさせ、
その時のscrollHeightがいくつなのかを確認するものです。

CodePen Project のURLです

すると、以下画像のように、ブラウザによって付加する高さが、img要素とテキスト要素によって異なるようです。

Chrome ver68の場合

イメージ説明

Firefox ver61の場合

イメージ説明

ie ver11の場合

(Cope Penに対応していないためPJをダウンロードしてローカルで起動しています)
イメージ説明

解決したいこと

  1. このように余分な高さが付加される原因は何でしょうか?
  2. 余分な高さを付加させないようにするには、どうしたらよいでしょうか?

よろしくおねがいします

補足

<textarea>の定義についてMDNの情報を調べてみたところ、
以下の内容を見つけました。

ベースラインの不整合

どうやら、<textarea>内にテキストをどのようにレンダリングするのかは、
ブラウザにより異なる(baselineの扱いがブラウザにより異なるという事は、テキスト1行が占有する領域の算出もブラウザにより異なる)ようです。
勝手な想像ですが、**「ScrollHeightの値もブラウザにより異なるのは、共通の仕様が無いから」**と思い始めました、、。
どなたか、この考えが正しいかどうかわかる方がいますかね、、?

とりあえずは、
「一旦<textArea>をレンダリングした後、
scrollheightを取得して<textarea>heightより大きければ、scrollHeightの値でheightを再調整する」
という機能を組み込めば、期待通りの動作をする事はわかりましたが、
もっとスマートな方法は無いものでしょうか、、、、

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

1. について:原因(対策はyoshinaviさんの投稿をご参照ください。)

yoshinaviさんがおっしゃっているように、<img>はインライン要素です。
このため、ベースライン=a, b, cなどの文字の下端と、画像の下端が一致するように描画されます。
一方、ベースラインより下にもはみ出すy, jなどの文字のため、ベースラインの下にも空間があります。
この空間が、画像の下の空白となって現れています。
(参考:https://stackoverflow.com/questions/5804256/image-inside-div-has-extra-space-below-the-image)

ベースライン下の空白の大きさが異なるのは、(少なくとも投稿にあるCodePenでは)フォントがブラウザごとに異なり、ベースライン下の空間も大きさが異なるためです。
CSSを少し変えて、

CSS

1body { 2 border: 1px solid black; 3 font-family: Arial; 4 font-size: 20px; 5 line-height: 20px; 6}

のようにフォントなどを指定すると、ChromeとFirefoxで、画像のscrollHeightは一致しました。

2. について
文字の下の空白=ベースライン下の空白です。これが異なるのは、1. と同様の理由です。
ただし、font-family font-size line-heightを指定しても、ChromeよりもFirefoxのscrollHeightのほうが1ピクセル大きくなりました。
この点、ブラウザ間の微妙な差、ということかと思います…。

##追記(8月12日22:40)
質問に「補足」として書かれた、

「一旦<textArea>をレンダリングした後、scrollheightを取得して<textarea>のheightより大きければ、scrollHeightの値でheightを再調整する」

この方法でコンテンツの高さ(scrollHeightで取得)とtextareaの高さを同じにするのがいいかと思います。
こんなコードでしょうか。

JavaScript

1var img = document.getElementById('imgTest'); 2var imgHeight = img.scrollHeight; 3var imgWidth = img.scrollWidth; 4img.style.height = imgHeight + 'px'; 5img.style.width = imgWidth 'px'; 6 7var txt = document.getElementById('txtAreaTest_textarea'); 8var txtHeight = txt.scrollHeight; 9var txtWidth = txt.scrollWidth; 10txt.style.height = txtHeight + 'px'; 11txt.style.width = txtWidth + 'px';

問題点は、このコードだと、

  • Firefox→フォントを問わず期待通り動作
  • Chrome→Arialなど一部フォントをfont-familyで設定した場合のみ、スクロールバーが出ます

(これに気がついたときは目から汗が…)

とりあえずの対処法として思いつくのは、

  • Chromeでテストをして、期待通りに動作するフォントを選ぶ。ただし、Arlal、メイリオ、MS Pゴシックなどはだめでした。
  • txtHeight + 'px';txtHeight + 20 + 'px'などとしてスクロールバーの高さ・幅+αをtextareaの高さに足す

といったところでしょうか…。「いいかと思います」と言いながら申し訳ありません。

投稿2018/08/12 06:45

編集2018/08/12 13:40
code_ugoite

総合スコア18

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

IkazoIchikawa

2018/08/12 09:25

わかりやすい説明ありがとうございます <textarea>要素でfont-familyとfont-sizeを指定しても、より上位要素のfont設定(ここを明示的に指定してあげないと、ブラウザ毎に異なる計算がされる)により、baseline下の空間(ディセンダというものでしょうか)が変わるという事ですね。 しかしそれだと<textarea>外で別のフォントを使用したいといった場合に、このフォントはOKだけどこのフォントはNGといった制限がかかってしまうので、、微妙ですね、、。 また、1pxとはいえ、「ブラウザ間の微妙な差」ができてしまうというのも、、 (1pxの計算違いで、15px程あるスクロールバーが表示されるかされないかが変わってしまう事になるからです) 「ベースラインの不整合」の説明を読む限り、<textarea>に対してvertical-alignは使用しないほうが良さそうですし、、、 、、やはりscrollheightの大きさはコンテンツのサイズによって、'ぴったりこの数字にする'ということは出来ない事として、対処療法を考えるしか無いのでしょうか、、
code_ugoite

2018/08/12 13:02

><textarea>外で別のフォントを使用したいといった場合 →CSSで、textareaにのみfont-familyを設定すれば、bodyの他の部分と別のフォントが使えます。 >1pxの計算違いで、15px程あるスクロールバーが表示されるかされないかが変わってしまう >scrollheightの大きさはコンテンツのサイズによって、'ぴったりこの数字にする'ということは出来ない →この点、もとの投稿に書こうか悩んだところでもあったので、もとの投稿に追記しました。ご確認ください。
guest

0

imgについては「インライン要素」なので、余白が気になるようであればdisplay:block;またはvertical-align:bottom;を追加してみてください。

テキストは、私の環境では余白は無いように見えます。
(Chrome:68.0.3440.106)

投稿2018/08/11 23:10

yoshinavi

総合スコア3521

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

IkazoIchikawa

2018/08/12 06:07

回答ありがとうございます > imgについては「インライン要素」なので、余白が気になるようであれば > display:block;またはvertical-align:bottom;を追加してみてください。 →`display:block;`を<img>に適用したところ、目的通り余白が表示されなくなりました。  しかし`vertical-align:bottom;`は効果が無いようです。(環境により異なるのでしょうか、、) > テキストは、私の環境では余白は無いように見えます。 > (Chrome:68.0.3440.106) →ごめんなさい説明不足でした。  Chrome68のテキスト表示に限っては、期待通り余白が表示されていなかったです。  (画像にコメントを追加しておきました)
yoshinavi

2018/08/12 22:33

>「ScrollHeightの値もブラウザにより異なるのは、共通の仕様が無いから」 HTML4で一応は共通項目としてデフォルトのスタイルシートが存在しますが各ブラウザは個別の値を取っているのが多いです。最近はある程度は共通化していますが、全てでは無いので、どうしても揃える時は「リセットCSS」をまず適用させるしかないと思います。 参考までに https://www.w3.org/TR/CSS2/sample.html
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問