Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 12588] ファイルの概要

このコミットは、Go言語の公式ドキュメントツールであるgodocのレイアウトを、ほとんどのページで「elastic layout」(伸縮性のあるレイアウト)に変更するものです。これにより、コンテンツがブラウザの幅に合わせて柔軟に表示されるようになり、様々な画面サイズでの視認性が向上します。特に、フロントページ(タイトルがないページ)とそれ以外のページを区別し、フロントページは従来のレイアウトを維持しつつ、他のページに伸縮性のあるレイアウトを適用するロジックが導入されています。

コミット

commit 2b8bc93f323bd5e161f70cc2a730dcd206b38a00
Author: Andrew Gerrand <adg@golang.org>
Date:   Tue Mar 13 10:17:10 2012 +1100

    godoc: use elastic layout for most pages
    
    We use the absence of a Title to detect the front page.
    I can't find other pages without titles, so this seems reasonable.
    
    R=golang-dev, bradfitz, gri
    CC=golang-dev
    https://golang.org/cl/5797076

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/2b8bc93f323bd5e161f70cc2a730dcd206b38a00

元コミット内容

godoc: use elastic layout for most pages

We use the absence of a Title to detect the front page.
I can't find other pages without titles, so this seems reasonable.

R=golang-dev, bradfitz, gri
CC=golang-dev
https://golang.org/cl/5797076

変更の背景

この変更の主な背景は、godocが生成するドキュメントページの表示を、より現代的で柔軟なものにすることです。従来のレイアウトは固定幅であった可能性があり、様々なデバイスやブラウザのウィンドウサイズに対応しきれていなかったと考えられます。

「elastic layout」を導入することで、コンテンツがブラウザの幅に合わせて自動的に調整され、ユーザーエクスペリエンスが向上します。特に、コードのドキュメントは内容が多岐にわたり、長い行や多くの要素を含むことが多いため、固定幅では表示が崩れたり、スクロールが頻繁に必要になったりする問題がありました。

また、コミットメッセージにある「We use the absence of a Title to detect the front page.」という記述から、godocのフロントページ(ホームページ)は特別な扱いを受け、従来の固定幅レイアウトを維持しつつ、それ以外の「タイトルを持つ」ページにのみ新しい伸縮性レイアウトを適用するという意図が読み取れます。これは、フロントページが特定のデザイン要件や情報配置を持っているため、そのレイアウトを大きく変更したくなかった、あるいは変更する必要がなかったためと考えられます。

前提知識の解説

GoDoc (godoc)

godocは、Go言語のソースコードからドキュメントを生成し、HTTPサーバーとして提供するツールです。Goのコードに記述されたコメント(特にエクスポートされた識別子に対するコメント)を解析し、自動的にAPIドキュメントやパッケージの概要を生成します。開発者はgodocサーバーをローカルで実行することで、Goの標準ライブラリや自身のプロジェクトのドキュメントをブラウザで閲覧できます。

Webレイアウトの種類(固定幅 vs. 伸縮性/流動性レイアウト)

  • 固定幅レイアウト (Fixed Layout): ウェブページの幅がピクセル単位で固定されているレイアウトです。例えば、width: 960px;のように指定されます。

    • 利点: デザインの再現性が高く、どの環境でも同じ見た目を保証しやすい。
    • 欠点: 画面サイズが異なるデバイス(スマートフォン、タブレット、大型モニターなど)で表示が最適化されず、横スクロールが発生したり、余白が過剰になったりする問題があります。
  • 伸縮性/流動性レイアウト (Elastic/Fluid Layout): ウェブページの幅がパーセンテージやautomax-widthなどの相対的な単位で指定され、ブラウザのウィンドウサイズに合わせてコンテンツが伸縮するレイアウトです。

    • 利点: 様々な画面サイズに柔軟に対応し、ユーザーの閲覧環境に合わせた最適な表示を提供できます。レスポンシブデザインの基礎となる考え方の一つです。
    • 欠点: レイアウトが柔軟な分、デザインの崩れや要素の重なりが発生しないように、より慎重なCSS設計が必要です。

このコミットでは、godocのページを固定幅から伸縮性レイアウトへと移行させることで、ユーザーの閲覧体験を向上させることを目指しています。

CSSセレクタの基礎

CSS(Cascading Style Sheets)は、HTML要素のスタイルを定義するための言語です。セレクタは、スタイルを適用するHTML要素を指定するために使用されます。

  • IDセレクタ (#): #idName の形式で、特定のid属性を持つ要素を選択します。HTMLドキュメント内でidは一意であるべきです。 例: div#page は、id="page"を持つdiv要素を選択します。

  • クラスセレクタ (.): .className の形式で、特定のclass属性を持つ要素を選択します。一つのクラスは複数の要素に適用でき、一つの要素に複数のクラスを適用することも可能です。 例: div.container は、class="container"を持つdiv要素を選択します。

  • 子孫セレクタ ( ) と直接の子セレクタ (>):

    • 子孫セレクタ ( ): スペースで区切られたセレクタは、最初のセレクタにマッチする要素のすべての子孫(直接の子、孫、ひ孫など)の中から、2番目のセレクタにマッチする要素を選択します。 例: div#topbar .container は、id="topbar"を持つdiv要素の子孫であるclass="container"を持つ要素を選択します。
    • 直接の子セレクタ (>): >で区切られたセレクタは、最初のセレクタにマッチする要素の直接の子の中から、2番目のセレクタにマッチする要素を選択します。 例: div#topbar > .container は、id="topbar"を持つdiv要素の直接の子であるclass="container"を持つ要素を選択します。 このコミットでは、div#topbar .containerからdiv#topbar > .containerへの変更があり、これはセレクタの適用範囲をより厳密に、直接の子要素に限定することを意味します。

GoのHTMLテンプレート (html/template)

Go言語には、HTMLを生成するための標準ライブラリhtml/templateがあります。このライブラリは、Goのデータ構造をテンプレートに渡し、そのデータに基づいてHTMLを動的に生成する機能を提供します。

  • 条件分岐 ({{if .Title}} ... {{end}}): テンプレート内で{{if .FieldName}}という構文を使用すると、渡されたデータ構造(この場合は.、つまり現在のコンテキスト)のFieldNameフィールドが真と評価される場合にのみ、ifブロック内のコンテンツがレンダリングされます。 このコミットでは、.Titleの有無をチェックしています。Titleフィールドが空文字列やnilの場合、Goのテンプレートエンジンでは偽と評価されます。これにより、ページにタイトルがあるかどうかで異なるHTML構造やクラスを適用するロジックが実現されています。コミットメッセージにある「We use the absence of a Title to detect the front page.」は、このテンプレートの条件分岐と密接に関連しています。

技術的詳細

このコミットは、CSSとHTMLテンプレートの両方に変更を加え、godocのレイアウトを動的に制御しています。

  1. CSS (doc/style.css) の変更:

    • div#topbarheight: 64px;が追加され、トップバーの高さが固定されました。
    • div#pagediv#topbar .containerのセレクタがdiv#page, div#topbar > .containerに変更されました。これにより、topbar内のcontainerクラスを持つ要素が、topbarの直接の子である場合にのみスタイルが適用されるようになります。
    • padding: 0 20px;div#pagediv#topbar > .containerに追加され、左右に20pxのパディングが設定されました。
    • 新しいCSSルールdiv#page.wide, div#topbar > .wide { width: auto; }が追加されました。これは、pageまたはtopbarの直接の子である要素がwideクラスを持つ場合、その幅を自動調整(伸縮性)するように指示します。
    • div#menufloat: right;min-width: 590px;が追加されました。これにより、メニューが右にフロートし、最小幅が設定されます。
  2. HTMLテンプレート (lib/godoc/godoc.html) の変更:

    • div#topbar内のdiv.container要素に、Goテンプレートの条件分岐が導入されました: <div class="container{{if .Title}} wide{{end}}"> これにより、もし現在のページに.Title(タイトル)が存在すれば、containerクラスに加えてwideクラスが動的に追加されます。
    • 同様に、div#page要素にも条件分岐が導入されました: <div id="page"{{if .Title}} class="wide{{end}}"> これにより、ページにタイトルがあればpage要素にもwideクラスが追加されます。
    • <div id="heading"><a href="/">The Go Programming Language</a></div>のHTML構造が変更され、<form>タグの外に移動しました。これはレイアウトの調整のためと考えられます。

これらの変更により、godocは以下のように動作します。

  • フロントページ(タイトルがないページ): {{if .Title}}が偽と評価されるため、wideクラスは追加されません。したがって、div#pagediv#topbar > .containerは従来の固定幅(width: 900px;)を維持します。
  • その他のページ(タイトルがあるページ): {{if .Title}}が真と評価されるため、wideクラスが追加されます。これにより、div#page.widediv#topbar > .wideのCSSルールが適用され、これらの要素の幅がwidth: auto;となり、ブラウザの幅に合わせて伸縮する「elastic layout」が実現されます。

コアとなるコードの変更箇所

diff --git a/doc/style.css b/doc/style.css
index 1d8ccd0ead..d5b305984a 100644
--- a/doc/style.css
+++ b/doc/style.css
@@ -129,19 +129,25 @@ div#heading a {
 
 div#topbar {
 	background: #E0EBF5;
+	height: 64px;
 }
 
 body {
 	text-align: center;
 }
 div#page,
-div#topbar .container {
+div#topbar > .container {
 	clear: both;
 	text-align: left;
 	margin-left: auto;
 	margin-right: auto;
+	padding: 0 20px;
 	width: 900px;
 }
+div#page.wide,
+div#topbar > .wide {
+	width: auto;
+}
 div#plusone {
 	float: right;
 }
@@ -182,6 +188,8 @@ div#blog .read a {
 }
 
 div#menu {
+	float: right;
+	min-width: 590px;
 	padding: 10px 0;
 	text-align: right;
 }
diff --git a/lib/godoc/godoc.html b/lib/godoc/godoc.html
index 62deed745b..7efed83b92 100644
--- a/lib/godoc/godoc.html
+++ b/lib/godoc/godoc.html
@@ -15,10 +15,9 @@
 </head>
 <body>
 
-<div id="topbar"><div class="container">\n+<div id="topbar"><div class="container{{if .Title}} wide{{end}}">\n 
 <form method="GET" action="/search">\n-<div id="heading"><a href="/">The Go Programming Language</a></div>\n <div id="menu">\n <a href="/doc/">Documents</a>\n <a href="/ref/">References</a>\n@@ -27,13 +26,12 @@\n <a href="/help/">Help</a>\n <input type="text" id="search" name="q" class="inactive" value="Search">\n </div>\n+<div id="heading"><a href="/">The Go Programming Language</a></div>\n </form>\n \n </div></div>\n \n-<div id="page">\n-\n-<div id="content">\n+<div id="page"{{if .Title}} class="wide"{{end}}>\n 
 {{with .Title}}\n   <div id="plusone"><g:plusone size="small" annotation="none"></g:plusone></div>\n@@ -52,8 +50,6 @@\n \n </div>\n \n-</div>\n-\n <div id="copyright">\n Build version {{html .Version}}.\n Except as noted, this content is licensed under a\n```

## コアとなるコードの解説

### `doc/style.css` の変更点

1.  **`div#topbar` の高さ固定**:
    ```css
    div#topbar {
    	background: #E0EBF5;
    +	height: 64px;
    }
    ```
    トップバーの高さが`64px`に固定されました。これにより、トップバーの視覚的な安定性が向上し、レイアウト全体の基準点となります。

2.  **セレクタの変更とパディングの追加**:
    ```css
    div#page,
    -div#topbar .container {
    +div#topbar > .container {
    	clear: both;
    	text-align: left;
    	margin-left: auto;
    	margin-right: auto;
    +	padding: 0 20px;
    	width: 900px;
    }
    ```
    `div#topbar .container`が`div#topbar > .container`に変更されました。これは、`topbar`の**直接の子**である`container`クラスを持つ要素にのみスタイルを適用することを意味します。これにより、CSSの適用範囲がより厳密になり、意図しない子孫要素へのスタイル適用を防ぎます。また、左右に`20px`のパディングが追加され、コンテンツが端に寄りすぎるのを防ぎ、視認性を向上させています。`width: 900px;`は、`wide`クラスが適用されない場合のデフォルトの固定幅です。

3.  **`wide`クラスの導入**:
    ```css
    +div#page.wide,
    +div#topbar > .wide {
    +	width: auto;
    +}
    ```
    この新しいCSSルールが、伸縮性レイアウトの核心です。`div#page`または`div#topbar`の直接の子要素が`wide`クラスを持つ場合、その`width`が`auto`に設定されます。`width: auto;`は、要素が親要素の利用可能な幅いっぱいに広がることを意味し、これによりコンテンツがブラウザのウィンドウサイズに合わせて伸縮する「elastic layout」が実現されます。

4.  **`div#menu` のフロートと最小幅**:
    ```css
    div#menu {
    +	float: right;
    +	min-width: 590px;
    	padding: 10px 0;
    	text-align: right;
    }
    ```
    メニュー要素が右にフロートするようになり、最小幅が`590px`に設定されました。これにより、メニューが他の要素と重なることなく、特定の幅を確保しつつ右寄せで表示されるようになります。

### `lib/godoc/godoc.html` の変更点

1.  **`topbar`内の`container`への条件付き`wide`クラス適用**:
    ```html
    -<div id="topbar"><div class="container">
    +<div id="topbar"><div class="container{{if .Title}} wide{{end}}">
    ```
    `div.container`要素にGoテンプレートの条件分岐`{{if .Title}} wide{{end}}`が追加されました。これは、Goテンプレートに渡されるデータコンテキストに`Title`フィールドが存在し、かつその値が真と評価される場合(つまり、ページにタイトルがある場合)にのみ、`wide`というクラス名がHTMLに出力されることを意味します。これにより、タイトルを持つページ(フロントページ以外)では、`container`要素が`wide`クラスを持つことになり、CSSで定義された`width: auto;`が適用されます。

2.  **`heading`要素の移動**:
    ```html
    <form method="GET" action="/search">
    -<div id="heading"><a href="/">The Go Programming Language</a></div>
     <div id="menu">
     ...
     </div>
    +<div id="heading"><a href="/">The Go Programming Language</a></div>
    </form>
    ```
    `heading`要素("The Go Programming Language"というリンク)が`<form>`タグの内側から外側へ移動しました。これは、CSSのフロートやレイアウトの調整に伴うHTML構造の再配置であり、視覚的な表示順序や要素の包含関係を最適化するための変更です。

3.  **`page`への条件付き`wide`クラス適用**:
    ```html
    -<div id="page">
    -
    -<div id="content">
    +<div id="page"{{if .Title}} class="wide"{{end}}>
    ```
    `div#page`要素にも同様に`{{if .Title}} class="wide"{{end}}`という条件分岐が追加されました。これにより、タイトルを持つページでは`page`要素にも`wide`クラスが適用され、ページ全体のコンテンツ領域が伸縮性を持つようになります。

4.  **不要な`</div>`の削除**:
    ```html
    </div>
    
    -</div>
    -
     <div id="copyright">
    ```
    HTML構造の変更に伴い、不要になった`</div>`タグが削除されました。これは、HTMLの整合性を保つためのクリーンアップです。

これらの変更は、`godoc`が生成するドキュメントの表示を、より現代的で適応性の高いものにするための重要なステップです。特に、Goのテンプレート機能とCSSの組み合わせにより、フロントページとそれ以外のページで異なるレイアウトを動的に適用する巧妙な仕組みが実現されています。

## 関連リンク

*   Gerrit Change-ID: [https://golang.org/cl/5797076](https://golang.org/cl/5797076)

## 参考にした情報源リンク

*   GoDoc: [https://pkg.go.dev/golang.org/x/tools/cmd/godoc](https://pkg.go.dev/golang.org/x/tools/cmd/godoc)
*   Go html/template package: [https://pkg.go.dev/html/template](https://pkg.go.dev/html/template)
*   CSS `width: auto`: [https://developer.mozilla.org/ja/docs/Web/CSS/width](https://developer.mozilla.org/ja/docs/Web/CSS/width)
*   CSS `float` property: [https://developer.mozilla.org/ja/docs/Web/CSS/float](https://developer.mozilla.org/ja/docs/Web/CSS/float)
*   CSS child combinator (`>`): [https://developer.mozilla.org/ja/docs/Web/CSS/Child_combinator](https://developer.mozilla.org/ja/docs/Web/CSS/Child_combinator)
*   CSS ID and Class Selectors: [https://developer.mozilla.org/ja/docs/Web/CSS/Selectors](https://developer.mozilla.org/ja/docs/Web/CSS/Selectors)