Web用のテキストエディタを開発する方法
公開: 2022-03-10私はReadymagで働いています。これは、コーディングなしでWebサイト、ポートフォリオ、およびあらゆる種類のオンライン出版物を作成するのに役立つブラウザーベースの設計ツールを作成します。 私たちのツールでは多くのウィジェットを利用でき、テキストウィジェットは最も広く使用されているものの1つです。
テキストウィジェットは、ユーザーがエディターのさまざまなコントロールを使用してテキストのスタイルを設定できるテキスト入力フィールドです。 各コントロールは、CSSプロパティをテキストに適用します。 ユーザーの側から見ると、テキストを入力するための通常のフィールドのように見えますが、その見かけの単純さの背後には、膨大な数の複雑なプロセスが隠されています。
この記事では、会社が直面した課題と、アプリケーションでテキストウィジェットを作成するために使用したソリューションについて説明します。 また、それをどのように実装し、その過程で何を学んだか、そしてWebでの入力が一般的にどのように機能するかについても詳しく説明します。
Web上のテキストの編集
Webにテキスト入力フィールドを実装する方法はいくつかあります。 単純なテキストフィールド、複数行のtextarea
要素、またはcontenteditable
属性を使用して、入力を編集可能にするか、 document.designMode = on
することができます。 それらはどう違いますか?
input
要素とtextarea
要素は、ページにテキストを追加するのに理想的ですが、リッチテキスト形式のエクスペリエンスを提供しません。 このために、 contenteditable
属性を使用して、ほとんどすべての要素を編集可能にし、テキストスタイルの使用を有効にすることができます。
ページ全体を一度に編集する必要がある場合は、 document.designMode
を使用できます。 このモードでは、 iframe
を含め、特定のドキュメント内の任意の要素を編集できます。
必要なすべてのテキスト編集機能を含むcontenteditable
属性を選択しました。 この属性を使用すると、ページ上のすべてのテキストが編集可能になります。これは、CSSを使用してテキストのスタイルを設定できるようにする場合に非常に重要です。 たとえば、ユーザーは選択したセクションまたはテキスト全体を直接スタイル設定できます。
テキストスタイルとフォントプロパティ
CSSが提供するすべてのオプションへのアクセスを提供することにより、ユーザーは任意の方法でテキストのスタイルを設定できます。 フォント、スタイル、色、装飾などのよく知られたプロパティに加えて、合字、文体セット、分数などのOpenTypeフォント機能を使用する機会をユーザーに提供します。 これらの機能は、ユーザーがテキストスタイルをカスタマイズできるfont-feature-settings
プロパティを介して機能します。
注: OpenTypeのすべての機能を紹介するSparanoidの優れた記事を読むことを強くお勧めします。
現代のタイポグラフィは大きな一歩を踏み出し、 font-variation-settings
プロパティを介してWeb上で可変フォントを使用できるようになりました。
各可変フォントには、値を変更できる可変プロパティがあります。 たとえば、標準フォントでは、厳密に指定された値( 400
など) 500
使用してフォント600
太さを変更できますが、可変フォントでは、使用可能な範囲内の任意の値を使用できるため、より幅広い可能性があります。テキストスタイリング用。
.style-1 { font-weight: 600; } .style-2 { font-variation-settings: "wght" 777; }
以下に、可変フォントの操作がテキストウィジェットでどのように表示されるかの例を示します。
登録された値( wght
、 wdth
、 slnt
など)に加えて、フォントメーカーは独自のフォント機能を作成することもできます(上記の例のように)。 ユーザーに可能なすべてのフォント機能を使用する機会を与えるために、最初にこの情報が必要です。
使用するすべての機能は、フォントファイルで定義する必要があります。 その仕様を見てみましょう。 各フォントはテーブルの形式で表すことができ、その文字をレンダリングするときに使用されるさまざまな情報をすべて提供します。
フォントに関するこの情報を収集するために、2つのテーブルを使用します。
- グリフ置換テーブル
グリフ置換テーブル(GSUB)には、グリフレンダリングデータのリストが含まれています。GSUB.featureList
オブジェクトは、フォント機能とそのプロパティの列挙です。 GitHubの表にあるデータの例を表示できます。 この表では、tag
フィールドが最も興味深いものです。 これはフォント機能の名前であり、この機能がこのフォントで使用できることを示しています。font-feature-settings
プロパティでtag
を安全に使用できます。 - フォントバリエーションテーブル
フォントバリエーションテーブル(fvar)は、フォントに関連付けられた変数プロパティを表したものです。 表の例はGitHubでも入手できます。 各オブジェクトはフォントプロパティであり、可能な値(min
、max
、default)の説明とローカライズされた名前(存在する場合)が含まれます。 これらの値は、font-variation-settings
プロパティで使用します。
これらの2つの表の助けを借りて、可変フォントプロパティとさまざまなフォント機能の使用というすべての要件をカバーできます。 結果のデータは、エディターのテキストウィジェットコントロールに表示され、ユーザーはコードを使用せずにテキストのスタイルを設定できます。
キーボードの使用
テキスト入力は、テキストウィジェットのユーザーエクスペリエンスの最も重要な側面の1つです。 テキストを操作するためのショートカットを有効にすることに加えて、いくつかの異常な課題に対処する必要がありました。 矢印キーでテキストをナビゲートすることは間違いなくそれらの1つでした。
ユーザーが編集している間、テキストウィジェットには、改行なしスペースや改行などの非表示の文字も表示されます。 これらはテキストに挿入されたSVGアイコンとして実装されているため、問題が発生しますcontenteditable
を使用すると、これらのアイコンにより、ユーザーは矢印キーでカーソルを移動できなくなります。
解決策は非常に簡単です。 span
と:before
疑似要素を使用します。 このように、ブラウザはアイコンをテキストとして認識し、矢印キーはうまく機能します。
span:before { content: ""; height: 1em; position: relative; background-repeat: no-repeat; background-image: url("data:image/svg+xml,..."); background-position: center bottom; background-size: 1em; }
ショートカット
テキストウィジェットにテキストを貼り付けるための2つのキーボードショートカットがあります。
Cmd / Ctrl + Vはクリップボードからテキストを貼り付け、元のドキュメントにあったスタイルを保持します。 テキストがPages、Notes、Word、Google Docsなどのアプリケーションからコピーされた場合、クリップボードにはプレーンテキストだけでなくHTML情報が含まれます。 このHTMLは、元のスタイルを維持したまま解析および貼り付けできます。
HTMLデータは次のように取得できます。
// https://www.w3.org/TR/clipboard-apis/#reading-from-clipboard document.addEventListener('paste', (e) => { const text = e.clipboardData.getData('text/plain'); const html = e.clipboardData.getData('text/html'); handlePaste(); });
さらに、 Cmd + Shift + Vショートカットがあります。 このキーボードの組み合わせを使用してテキストを挿入すると、ブラウザはペイロードにプレーンデータを残すため、スタイルは貼り付け先によって制御されます。 これらのショートカットはデフォルトでブラウザに存在しますが、プロジェクトに実装することを忘れないでください。
テキストの選択とフォーカス
テキストの選択は、ユーザーが現在編集されているテキストを確認するのに役立ちます。 簡単な例を試してみましょう。テキストの太字を制御するボタンのある入力フィールドです。
この例では、テキストの一部を選択してBold
ボタンを押すと、テキスト内の選択はその後も残ります。 しかし、私たちの例がもっと複雑な場合はどうでしょうか? テキストサイズセレクターに入力フィールドを追加するとします。 この場合、フォーカスは新しい入力に移ります。
この問題を解決するには、2つのオプションがあります。
- 各入力イベントの後、フォーカスを強制的にテキストブロックに戻します。 この場合、特定の数の入力イベントの後に選択範囲が点滅し始めます—これは望ましくありません。
- テキストブロックを
iframe
に追加できます。 ご存知かもしれませんが、iframe
には独自のグローバルwindow
オブジェクトがあります。 そのため、選択範囲がiframe
内にある限り、フォーカスが外側に移動しても選択範囲は維持されます。
最終的にiframe
でラップされたテキストウィジェットになりました。 そのため、選択範囲がiframe
内にある限り、フォーカスが外側に移動しても選択範囲は維持されます。 下のスクリーンショットを見てください。 ページには2つの選択肢があります。テキストウィジェットで選択されたフラグメントと、コントロールで選択されたテキストサイズの値です。
テキスト入力中のパフォーマンス
テキスト編集インターフェースの応答性は重要です。 特にテキストの高速編集やフォントサイズの変更などのタスクに関しては、1秒あたりのフレーム数(FPS)の値を注意深く監視してください。
Readymagには、デスクトップとモバイルの2つのビューポートがあります。 テキストスタイルはそれぞれ異なって表示される場合があります。 テキストが入力されている間、エディタはさまざまな計算を実行して、ビューポート間でデータを同期します。 ブラウザAPIを使用することで高い応答性が実現されます: requestAnimationFrame
およびrequestIdleCallback
:
-
requestAnimationFrame
は、画面が更新されるたびに呼び出されます。 -
requestIdleCallback
は、ブラウザーがアイドル状態のときにのみ呼び出されます。
これは、メインスレッドをブロックせずに面倒な操作を実行するための優れた方法です。
アクセシビリティ
アクセシビリティを有効にすることは、今日のWeb開発において最も重要なプラクティスの1つです。 あなたのウェブサイトがアクセシビリティを念頭に置いて設計されている場合、それはより多くの人々にあなたの製品へのアクセスを与えるでしょう。 これは、障害を持つ人々だけでなく、デスクトップおよびタッチデバイス、スクリーンリーダー、聴覚デバイスなど、さまざまなプラットフォームのユーザーにも対応できることを意味します。 プロジェクトをアクセシブルにすることがどれほど重要であるかを理解するには、最近のアクセシビリティ統計を確認することをお勧めします。
Webアクセシビリティの実践を取り入れ始めるには、まず、このトピックに関する最も包括的なリソースであるWebコンテンツアクセシビリティガイドライン(WCAG)を確認してください。 また、Readymagが公開用のツールである限り、WCAGに加えて、オーサリングツールのアクセシビリティガイドライン(ATAG)にも従う必要があります。
私たちのチームは現在、アクセシビリティをエディタに統合する段階にあります。 以降の記事では、Readymagでアクセシビリティを完全に統合するための私たちの旅について詳しく説明します。 アクセシビリティチェックリストを使用して、Readymagで作成された作業を確認することもできます。
ベストプラクティス
最後に、Web上でテキストエディタを開発するのに役立つヒントをいくつか示します。
- レイアウトについて慎重に検討してください。
必要な機能と、テキストエディタの要素をどのように操作するかを事前に特定します。 - 視覚的なテストを設定します。
テキストを操作する場合、スナップショットテストの結果に完全に依存することはできません。 ブロックに指定されたCSSを期待して、テストで正しい結果が得られる場合がありますが、期待した結果が得られない場合があります。 - さまざまなブラウザで作業をテストします。
ほとんどのブラウザは新しいオンライン機能をかなりうまくサポートしていますが、異なるブラウザで同じスタイルを表示すると問題が発生することがよくあります。 - 新機能をより安全に開発するには、機能フラグを使用します。
- テキストを入力するときにブラウザでFPSを測定します。
シングルスレッドでCPUを集中的に使用するタスクを実行しないでください。 - 実験することを恐れないでください。
- 最後になりましたが、Readymagでテキストウィジェットを試してみてください。
いくつかの便利なリンク
- 「OpenType機能の完全なCSSデモ」、Sparanoid
- 「Web上の可変フォントの概要」、web.dev
- 「素晴らしいタイポグラフィ」、ジョエル・ガレラン
- 「可変フォント」、ニック・シャーマン
- Fontkit
- OpenType.js