このページでは、電子出版物のコンテンツを非表示にしたり最小化したりするために使用されるさまざまなテクニックのアクセシビリティと影響について説明します。

ただし、コンテンツが出版物の理解の中心ではない限り、支援技術のユーザーのみを対象とした非表示コンテンツを含めることは一般的に避けることをお勧めします。代替テキストへの標準的なハイパーリンクや、コンテンツを最小化する宣言的なアプローチ(例:details要素)は、非表示コンテンツよりも幅広く使用できます。このコンテンツの恩恵を受けるすべての人が支援技術を使用しているわけではありません。

コンテンツを選択的に表示する必要がある場合は、プログレッシブ エンハンスメント手法に従っていることを確認してください。

HTMLテクニック

hidden属性

HTML5 では、宣言的にコンテンツを非表示にする(つまり、CSS などの他のテクノロジーに依存せずにコンテンツを非表示にする)方法としてhidden属性が導入されました。要素にこの属性が設定されると、そのコンテンツはどのプレゼンテーションでもレンダリングされないため、支援技術によって読み取られません。

例 — hidden属性

次の例では、 hidden属性を使用して、「not the」という単語を含む範囲を非表示にします。

マークアップ:

<p>This is <span hidden="">not the</span> content.</p>

デモ:

This is content.

属性の値は、前の例のように空の文字列か、値「 hidden 」(hidden="hidden")のいずれかである必要があります。「ブール」属性と呼ばれますが、その値を「true」または「false」に設定することはできません。コンテンツを再び表示するには、要素からhidden属性を削除する必要があります。

hidden属性は、その内容が表示されることがない場合に、要素に直接記載するのに最適です。(コンテンツが表示と非表示の間で切り替えられる場合は、属性を動的に設定するスクリプト セクションを参照してください。)

hidden属性は、コンテンツを表示しないARIA 属性(例:aria-labelledbyおよびaria-describedby)で最もよく使用されます。これらの属性により、特定のコンテキストで支援技術がテキストを利用できるようになります。

この属性を設定すると、CSS のdisplayプロパティをnoneに設定するのと同じ効果が得られます。ただし、すべてのユーザー エージェントが CSS スタイルをサポートしているわけではないため、この属性は最新のユーザー エージェントの CSS オプションよりも信頼性が高くなります。

新しい HTML5 要素と属性をサポートしていない古いユーザー エージェントの場合は、hidden 属性の CSS フォールバックも含める必要があります。次のようなセレクターを使用すると、属性を持つすべての要素が CSS によって非表示になります。

*[hidden] { display: none; }

details要素

details要素は、コンテンツを非表示にする要件を完全には満たしていません。 summaryタグで指定されたラベルのみにコンテンツを折りたたむ機能を提供します。この要素の利点の 1 つは、コンテンツを展開したり折りたたんだりするのに、EPUB リーディングシステムではしばしば欠けているスクリプト サポートを必要としないことです。

例 — details要素

次の例は、折りたたまれたdetails要素を示しています。ラベルをクリックすると、コンテンツが展開されます。

マークアップ:

<details>
<summary>Description</summary>
<p>The first of the three gas giants is …</p>
</details>

デモ

コンテンツが折りたたまれた状態で始まる必要はありません。 open属性を追加すると、コンテンツは最初は展開されます(この属性もhidden属性と同様にブール値であるため、その値は空の文字列または値openのいずれかになります)。

例 — 展開されたdetails要素

マークアップ:

 <details open="">
<summary>Description</summary>
<p>The first of the three gas giants is …</p>
</details>

デモ

ただし、現在の制限として、要素が展開または折りたたまれたときに、リーディングシステムがページを再ページ化すると必ずしもうまくいかないことがあります。展開すると、要素の下のコンテンツが現在のページの下部から押し出され、目の見える読者が利用できなくなる可能性があります。また、この属性は古いブラウザーでは十分にサポートされておらず、Internet Explorer のバージョンではまったくサポートされていないため、機能させるにはポリフィルが必要です。

details要素は通常、説明を要素に関連付けるためにaria-details属性と組み合わせて使用​​されます。

CSSテクニック

CSS はコンテンツを視覚的に非表示にするさまざまなアプローチを提供しますが、それを使用する際の主な問題は次のとおりです。

  1. CSS は常にサポートされているわけではなく、ユーザーによって無効にされることがよくあります。
  2. 新しいプロパティのサポートは開発に長い時間がかかることが多く、古いユーザー エージェントではサポートされないものも多くあります。
  3. EPUB リーディングシステムは独自のスタイルを提供することが多いため、コンテンツ制作者のスタイルは無視されたり上書きされたりすることがあります。

その結果、スタイル設定されたコンテンツが、ユーザーが使用しているユーザー エージェントによっては、ユーザーに対して非表示になるという保証がありません。一般的に、 HTML テクニックの方が信頼性が高いです。

displaynoneに設定する

displayプロパティは、 視覚的に非表示にするために広く使用されている方法です。その起源はhidden属性よりはるかに古く、要素の高さと幅を設定するよりも直接的で簡単に操作できます。display をnoneに設定すると、そのプロパティが適用されている要素は視覚的な表示とアクセシビリティ ツリーから削除されるため、支援技術はコンテンツを読み取れません。

例 — 表示なし

マークアップ:

.display-none {
display: none;
}

<p>This is the visible
text<span class="display-none"> and this is 
not</span>.</p>

デモ:

This is the visible text.

hidden属性と同様に、 displayプロパティを使用して非表示にされたコンテンツには、非表示コンテンツを受け入れるARIA 属性によってアクセスできます。ただし、このアプローチには、支援技術を使用しないユーザーにとって有用な情報が非表示になるという同じ欠陥もあります。

クリッピング

クリッピングは、視覚ユーザーが追加コンテンツの存在に気付かないように、コンテンツを 1 ピクセルに縮小する手法です。

コンテンツを完全に非表示にするのではなくクリッピングする利点は、支援技術は、非表示にするように設定またはスタイル設定されたコンテンツは無視するのに対して、クリッピングされたコンテンツは読み上げるという点です。

clip-pathプロパティは、この効果を実現するために使用される主要なプロパティですが、次の例に示すように、他のいくつかのプロパティも必要です(一部はフォールバックとして)。

例 — クリッピング

「and this is not」というテキストを含むspan コンテンツはレンダリングされるときには表示されませんが、支援技術によってテキストは読まれます。

マークアップ:

.clip {
clip-path: inset(100%);
clip: rect(1px, 1px, 1px, 1px);
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
width: 1px;
}

<p>This is the visible text<span class="clip"> and
 this is not</span>.</p>

デモ:

This is the visible text and this is not.

注記

clipプロパティは非推奨になりました。これは、古いブラウザ用のフォールバックとして含まれています。

この手法は Web ブラウザーではうまく機能しますが、EPUBリーディングシステムでのサポートは一貫していません。新しいclip-pathプロパティのサポートは広く普及しておらず、絶対位置指定を必要とする古いclipプロパティもサポートされていません。

height(高さ)とwidth(幅)をゼロに設定する

要素のheightwidthプロパティを0に設定することは、クリッピング手法に似ていますが、通常、支援技術では、サイズ指定のない要素のコンテンツは読み取れません。

例 — 高さと幅がゼロの場合

マークアップ:

.zero-height-width {
height: 0;
width: 0;
}

<p>This is the visible
text<span class="zero-height-width"> and this
is not</span>.</p>

デモ:

This is the visible text and this is not.

要素の寸法を 0 に設定しても、コンテンツはアクセシビリティ ツリーから削除されませんが、支援技術は多くの場合、このようにスタイル設定されたコンテンツを無視するように最適化されています(たとえば、クリッピング手法でサイズを 1 ピクセルに縮小するだけであるのはそのためです)。ただし、この動作は普遍的なものではないため、場合によってはコンテンツが読み取られることがあります。

opacity(不透明)の透明化

要素のopacityプロパティを0に設定すると、ユーザーに対しては完全に透明になりますが、支援技術はテキストを読み取ります。

例 — 完全不透明

次の例では、2 番目の段落の不透明度を0に設定して透明にしていますが、その場所にはまだスペースが残ります。

マークアップ:

.transparent {
opacity: 0;
}

<p>This paragraph appears.</p>
<p class="transparent">While this one is made fully
opaque.</p>
<p>So there is space between.</p>

デモ:

This paragraph appears.

While this one is made fully opaque.

So there is space between.

opacityの使用に関する主な問題は、EPUB リーディングシステムでのサポートと、不透明なテキストがある場所にスペースが残ってしまうことです。

注記

アルファ チャンネルを透明に設定することで(たとえば、 rgba()または#RRGGBBAA値構文を使用)、要素のテキストのみの不透明度を変更することもできます。ただし、EPUB ではアルファ チャンネル値のサポートも広く普及していません。

変形(Transformation)

transformプロパティには、コンテンツを非表示にする 2 つのオプションがあります。1 つは要素をゼロに縮小(スケーリング)する方法で、もう 1 つは要素を画面外に移動(トランスレート)する方法です。どちらの場合でも、支援技術はテキストを読み取ります。

scale変形を使用すると、参照されている要素は、スペースを占有しなくなるまで縮小されます。これは、高さと幅を 0 に設定するのと効果は似ていますが、縮小時に要素が占有するスペース全体が消えないという点が異なります。

例 — スケーリング

次の例では、2 番目の段落は 0 に縮小されていますが、それが占めるスペースは残ります。デモのボタンをクリックして、スケーリングを切り替えます。

マークアップ:

.scale {
transform: scale(0);
}

<p>This paragraph appears.</p>
<p class="scale">While this one is scaled.</p>
<p>So there is space between.</p>

デモ:

This paragraph appears.

While this one is scaled.

So there is space between.

translate変形を使用すると、要素が占めるスペース全体が消えないことを除けば、画面外のコンテンツの絶対配置と効果は似ています。値は、移動ベクトルのx座標とy座標です。

例 — トランスレート

次の例では、2 番目の段落が、x 座標に-9999px 、y 座標に0を使用して画面外に移動されています。ただし、要素が占めるスペースはそのまま残ります。効果を切り替えるには、デモのボタンをクリックします。

マークアップ:

.translate {
transform: translate(-9999px);
}

<p>This paragraph appears.</p>
<p class="translate">While this one is translated
off screen.</p>
<p>So there is space between.</p>

デモ:

This paragraph appears.

While this one is translated off screen.

So there is space between.

opacityと同様に、 transformを使用する場合の主な問題は、このようなアニメーションが EPUB リーディングシステムで十分にサポートされておらず、変形されたテキストがあった場所にスペースが残ってしまうことです。

visibility(可視性)をhidden(非表示)に設定する

visibilityプロパティは、電子出版物内のコンテンツを非表示にするために使用されることはあまりありません。 displayプロパティとは異なり、レンダリングされたコンテンツ内に要素が表示されるスペースを残してしまうためです。可視スペースがあるにもかかわらず、コンテンツは支援技術によって読み込まれません。

例 — 可視性非表示

次の例では、非表示のspanがある場所に、テキスト「 and this is not 」の長さのスペースが発生します。デモのボタンをクリックして、表示を切り替えます。

マークアップ:

.vis-hidden {
visibility: hidden;
}

<p>This is the visible
text<span class="vis-hidden"> and this is 
not</span> but now with space.</p>

デモ:

This is the visible text and this is not but now with space.

このプロパティは、Web では、要素が非表示または表示されたときにページ上の他のコンテンツが移動するのを防ぐためによく使用されます(たとえば、ページ フッターがページの下部から引き上げられないようにするため)。

displayプロパティと同様に、この方法で非表示にされたコンテンツは、非表示のコンテンツを許可するARIA 属性から参照されない限り、支援技術に対して非表示になります。

絶対position(位置)

positionプロパティを使用してコンテンツを画面外に絶対配置することは、視覚的には非表示にして、支援技術には読み込ませるというもう 1 つの一般的な Web 手法です。変更されるのはコンテンツの視覚的な位置だけなので、支援技術は引き続きテキストを読みます。

例 — 絶対位置指定

マークアップ:

.abs-position {
position: absolute;
left: -9999px;
}

<p>This paragraph appears.</p>
<p class="abs-position">While this one is positioned
off screen.</p>
<p>But there is no space between.</p>

デモ:

This paragraph appears.

While this one is positioned off screen.

But there is no space between.

ただし、絶対配置を使用してコンテンツを画面外に配置することは、EPUB リーディングシステムでは非常に信頼性が低くなります。コンテンツの絶対配置は、リフロー可能なコンテンツのレンダリングとページ付けを複雑にするため、固定レイアウトの出版物以外では無効になっていることがよくあります。その結果、コンテンツがページ上の予期しない位置に固定されて表示され、視覚的に読み取る人にとって他のコンテンツが見えにくくなる可能性があります。

負のtext-indent

text-indentプロパティは、大きな負の数を指定してコンテンツを画面の表示領域から押し出すために使用されることがあります。大きな数を使用すると、テキストが 1 行にレンダリングされ、画面の表示領域に届かなくなります。コンテンツは視覚的には表示されませんが、支援技術によって読み取られます。

例 — 負のインデント

次の例では、2 番目の段落の負のインデントにより、2 番目の段落が画面外にレンダリングされ、もはやそこに存在しないように見えます。デモのボタンをクリックして、インデントを切り替えます。

マークアップ:

.negative-indent {
text-indent: -9999px;
}

<p>This paragraph appears.</p>
<p class="negative-indent">While this one is pushed
off screen.</p>
<p>But the space the element occupied remains.</p>

デモ:

This paragraph appears.

While this one is pushed off screen.

But the space the element occupied remains.

CSS テクニックの中でも、負のインデントは特に信頼性が低い傾向があります。たとえば、ユーザーがコンテンツに到達できるように、ブラウザに大きなスクロールバーが表示される可能性があることが指摘されています(ただし、方向性を設定することでこれを軽減できます)。EPUB リーディングシステムでより一般的な問題は、負のインデントや、表示領域外のコンテンツを操作するその他の試みが無視されることです。

また、通常、最初の行を単に後ろに移動することによって生じる空白を縮小するには、縮小されたフォント サイズや要素の高さの変更など、他のタンデム プロパティも必要です。これらも、EPUB リーディングシステムでは十分にサポートされていない可能性があります。

注記

100%のインデントを使用してコードを反対方向に画面外に押し出す同様の手法もブラウザー用に提案されていますが、コンテンツが画面外に配置されないようにするリーディングシステムではこれも機能しません。

背景とcolor(色)を合わせる

前景色を背景色と一致させることでコンテンツを非表示にすることは可能ですが、これは EPUB コンテンツに使用できる最悪の選択であると言えます。

この方法でEPUB のコンテンツを非表示にすると、次のような問題が発生します。

  • 多くの場合、リーディングシステムでは、すべての出版物が同じ外観と雰囲気を持つように、独自の前景色と背景色が適用されます。その結果、テキストが実際に非表示になるという保証はありません。
  • 同様に、リーディングシステムでは、前景テキストと背景テキストの色の設定を変更するオプションがユーザーに提供されることがよくあります。
  • 多くの場合、リーディングシステムでは、前景色と背景色をリセットする複数の読書モード(夜間読書など)が提供されており、これによりデフォルトでテキストが非表示になっていても表示されるようになります。

どのユーザー エージェントでもよくある問題は、この非表示方法ではテキストが隠れるだけであるということです。可視性を変更した場合と同様に、テキストが占める領域は引き続き表示されます。

色を変更してもテキストが実際に削除されるわけではないため、支援技術ではこの方法で隠されたテキストを読み取ります。

例 — 背景とテキストを一致させた効果

次の例では、テキストを隠すために、 colorbackground-colorプロパティの両方が白に設定されています。

マークアップ:

.color-match {
color: rgb(255,255,255);
background-color: rgb(255,255,255);
}

<p>This paragraph appears.</p>
<p class="color-match">While this one is colored to
be hidden.</p>
<p>So there is space between.</p>

デモ:

This paragraph appears.

While this one colored to be hidden.

So there is space between.

ARIA テクニック

ARIA はコンテンツの表示には影響しませんが、支援技術からコンテンツを非表示にしたり、非表示のコンテンツを支援技術がアクセスできるようにしたりするために使用できる属性が多数含まれています。

aria-describedby属性

aria-describedby属性は、参照される要素が非表示である必要はありませんが、非表示の説明を要素に関連付けるためによく使用されます。属性の値は、説明を含む要素の ID です。

例 — 説明と画像を関連付ける

属性の値はフラグメント識別子ではないことに注意してください(つまり、ハイパーリンクのように、先頭にハッシュ記号 ( # ) が含まれていません)。

<img … aria-describedby="img-desc"/>
<p id="img-desc" hidden="hidden">The infographic shows …</p>

説明が複数の要素に分割されている場合、 aria-describedby属性は複数の要素を参照することがあります。

aria-describedby使用して、非表示かどうかに関係なく、任意のコンテンツを参照する場合の問題は、そのコンテンツが単純なテキスト文字列になることです(つまり、説明内を効果的に移動する方法がありません)。その結果、支援技術のユーザーは、先に進む前にそのテキスト文字列全体を聞かなければならず、イライラすることがあります。

非表示のコンテンツを含むaria-describedbyを使用すると、アクセスの恩恵を受ける可能性のあるユーザーが多数いる場合でも、支援技術のユーザーによる説明へのアクセスが制限されます。

aria-details属性

aria-details属性は、どちらも要素のコンテンツに関する追加情報を識別するという点でaria-describedby属性に似ていますが、いくつかの重要な違いがあります。

  1. 非表示コンテンツを参照することを目的としたものではありません。
  2. 参照されるコンテンツは単純なテキスト文字列になるのではなく、ユーザーは参照されるコンテンツの構造をナビゲートできます。

aria-details属性の値は、説明を含む要素の ID です。この属性は1 つの要素のみを参照できます。

この属性は、折りたたみ可能なdetails要素を参照するためによく使用されます。この使用法により、この属性は、すべてのユーザーに対してできるだけ目立たない方法で説明を提供するための最適なオプションの 1 つになります。

注記

要素名と属性名に「details」が使用されているのは、ある意味偶然です。 aria-details要素は、追加情報を含む任意の要素を参照できます。

例 — 画像の説明を追加する

属性の値はフラグメント識別子ではないことに注意してください(つまり、ハイパーリンクのように、先頭にハッシュ記号 ( # ) が含まれていません)。

<img src="dollars.jpg" alt="…"
 aria-details="dollar-desc"/>

<details id="dollar-desc">
<summary>Description</summary>
…
</details>

aria-hidden属性

その名前にもかかわらず、 aria-hidden属性はコンテンツの視覚的なレンダリングを制御しません。設定されている場合、指定されたコンテンツは支援技術によってレンダリングされない(つまり、アクセシビリティ ツリーに含まれない)ことを示します。

例 — 引用文の冗長テキストを非表示にする

<div role="doc-pullquote" aria-hidden="true">
…
</div>

hidden属性とは異なり、値は「 true 」または「 false 」である必要があります。空の値 ( aria-hidden="" ) は、属性を指定しないのと同じです。

aria-hidden属性は、電子出版物ではほとんど必要ありません。引用文など、冗長または無関係な視覚コンテンツがある場合にのみ役立ちます。

非表示コンテンツを参照できる ARIA 属性(例: aria-describedbyおよびaria-labelledby )はこの属性を無視します。値に非表示テキストが含まれることに注意してください。

aria-labelaria-labelledby属性

aria-label属性とaria-labelledby属性はどちらも、要素にアクセシブルな名前を提供できるようにします。

aria-label非表示の名前を指定できます。

例 — 非表示の名前の指定

<section aria-label="Explanation">

この属性は、新しいセクションを示すために空白のみが使用されている電子出版で役立ちます(例:見出しのない前付セクション、索引または参考文献のエントリのグループ)。明示的な見出しがないと、支援技術でsectionをナビゲートできないため、これらのセクションに名前を付けることが重要です。

aria-labelledby属性は同様の目的を果たしますが、名前を(非表示にできる)別の要素に含めることができます。 aria-labelledby属性の値は、名前を含む要素の ID です。

例 — 表示名を指定する

属性の値はフラグメント識別子ではないことに注意してください(つまり、ハイパーリンクのように、先頭にハッシュ記号 ( # ) が含まれていません)。

<div role="note" aria-labelledby="note-hd">
<p id="note-hd" class="hd">Warning!</p>
…
</div>

ラベルが複数の要素に分割されている場合、 aria-labelledby属性は複数の要素を参照する場合があります。

コンテンツのセクションに明示的な見出しがある場合には、 aria-labelledby属性を必ずしも使用する必要はありません。

例 — 明確な見出しのあるセクション

<section>
<h2>Definitions</h2>
…
</section>

支援技術は、最初の見出し要素をセクションに関連付けます。ただし、古いブラウザや支援技術では、見出しを明示的に関連付けると、役立ちます。

presentationロール

よくある誤解として、要素にpresentationロールを追加すると、支援技術からコンテンツを隠すことができる、というものがあります。これは間違いです。

この誤解は、この役割が、ユーザーが遭遇する必要のない画像に適用されることが多いために生じます。

例 — 視覚的なスペースをあけるために使用される画像

<img src="spacer.href" alt="" role="presentation"/>

実際、コンテンツが存在せず、画像は無視しても問題ないことを支援技術に知らせるのは、空のalt属性です。

任意の要素にrole="presentation"を設定すると、そのセマンティクスのみが削除されます。要素の内容は変更されません。

注記

ARIA ワーキング グループは、無視されるのはコンテンツではなく要素のセマンティクスであることをより適切に反映するために、 presentationロールをnoneに置き換える方向に動いています。

スクリプトテクニック

JavaScript にはコンテンツを非表示にする独自の新しい機能はありませんが、開発者はこのページで説明したすべてのテクニックを使用してドキュメントを操作し、コンテンツを非表示にすることができます。たとえば、開発者はhidden属性を動的に追加および削除したり、要素に CSS クラスを割り当てたりすることができます。そしてもちろん、ARIA はスクリプトによって変更できるように設計されています。

例 — 属性とクラスの設定

次の例は、JavaScript のsetAttribute関数を使用して要素にhidden属性を追加し、 classList.addを使用してクラスhideを追加する方法を示しています。

   /* set the hidden attribute */
   document.getElementById('hideyho').setAttribute('hidden','');
   /* set a css class */
   document.getElementById('hideyho').classList.add('hide');

もともとのテクニックを直接使用する場合と比べて JavaScript が優れている点は、コンテンツを非表示にするときに段階的な拡張が可能であることです。ユーザーの好みに応じて、コンテンツのオン/オフを切り替える必要がある場合があります。

たとえば、プログラミングに関する本には複数の言語による例題が掲載され、ユーザーは自身が最も使いやすい言語のみを選択して有効にすることができます。HTML または CSS のテクニックを使用して 1 つの言語をデフォルトで非表示にすると、スクリプトのサポートがないと、それらの例題がユーザーにまったく表示されなくなる可能性があります(つまり、選択を切り替えるスクリプトが機能しない場合)。代わりに、ページの読み込み時に JavaScript を使用すると、スクリプトが利用できない場合にユーザーに対して何も非表示になりません。情報を失うことなく、スクリプトは適切に終了します。

同様に、教科書の問題の答えがスクリプトを使用してのみ明らかにされる場合、どのユーザーもその答えにアクセスできません。

例 — プログレッシブエンハンスメント

次の例では、スクリプトをサポートしていないリーディングシステムで、details要素を使用して回答を非表示にします。スクリプトがサポートされている場合、 details要素は非表示になり、代わりにラジオ ボタンのセットが有効になり、回答が正しいかどうかに関するメッセージが動的に生成されます。

デモの後には、質問をリセットしたり、動的バージョンと静的バージョンを切り替えたりするためのボタンがあります。

マークアップ:

<fieldset>
   <label>Which of the following is a liquid?</label>
   <ul class="q">
      <li>
         <input type="radio" name="q1-ans" value="a"
            onclick="revealResult(true)" hidden="hidden">
         A - Water
      </li>
         
      <li>
         <input type="radio" name="q1-ans" value="b"
            onclick="revealResult(false)" hidden="hidden">
         B - Ice
      </li>
         
      <li>
         <input type="radio" name="q1-ans" value="c"
            onclick="revealResult(false)" hidden="hidden">
         C - Steam
      </li>
   </ul>
   <div id="q1-result" aria-live="assertive" hidden=""></div>
   <details id="q1-static-ans">
      <summary>Answer</summary>
      <p>A - Water</p>
   </details>
</fieldset>

<script>
document.onload = configureTest();

function configureTest() {
  document.getElementById('q1-static-ans').classList.add('hidden');
  document.getElementById('q1-result').removeAttribute('hidden');
  var q1_ans = document.getElementsByName('q1-ans');
  q1_ans.forEach( function(checkbox) {
    checkbox.removeAttribute('hidden');
  });
}

function revealResult(correct) {
  var res_elem = document.getElementById('q1-result');
  var result = correct ? 'Correct!' : 'Sorry, try again!';
  res_elem.textContent = '';
  res_elem.appendChild(document.createTextNode(result));
}
</script>

デモ

関連リンク