ラベル html・css の投稿を表示しています。 すべての投稿を表示
ラベル html・css の投稿を表示しています。 すべての投稿を表示

2026年4月27日月曜日

Schema.org(構造化データ)を学ぶ

現在Googleが推奨する構造化データを学んでみた話

タイトル通りですが基本的に一般人は気にする必要はないです。理由は3つほど

  • ・検索のページランク自体には直結しない
  • ・なのに記述を間違えると怒られる
  • ・リッチリザルトは実務系しか強化されていない

リッチリザルトと構造化データの関係

リッチリザルト レポートの概要
「https://support.google.com/webmasters/answer/7552505?hl=ja」

構造化データ自体はだいぶ前から存在しており、情報を構造化して機械が理解しやすい様にすると考えれば基本的には十分です。

リッチリザルトは構造化データの「対象となる一部」から検索結果の見た目を強化する機能です。
これ自体はページランクに影響しないが検索結果が装飾される事でクリック率が上がり結果的にSEOに繋がる。

つまり、「構造化データ」は様々な情報を整理できるがそもそもリッチリザルトは一部しか対応してないので一般人が使うような内容には影響がないというわけです。

Schema.orgってなに?

構造化データを定義(Structured Data)している所です。
構造化データを定義を入れる時にこのサイトに構造情報があるという「"@context": "https://schema.org",」を指定します。
ですが現状ここしか指定出来ません。保証される構造情報を提供してるのがここしかないからです。

元々は Google・Microsoft・Yahoo・Yandex が共同で立ち上げたプロジェクトですが現状はほぼgoogleの影響で決まります。
そのためgoogleが構造化を推奨を強くしているわけです。

余り良くない事もあります。

リッチリザルトが実務ベースが強く、構造化データは多くの情報を定義出来るにお金になるProduct(商品)、JobPosting(求人)、LocalBusiness(店舗)、Recipe(レシピ)と言った所しかリッチリザルトされません。
FQAなども信頼の高いサイト以外は無意味になったし、How-toも廃止。
百歩譲ってリッチリザルトが実利を取るのはいいですが、構造化データ自体10年以上ほぼ変わらない構造化データなどがあります。

例えばVideoGameなどの構造はボードゲームなどの物理ゲームをベースに作られほぼ更新がありません。
ゲームアイテムの説明をするページを作る時にgameitemというプロパティはあるがメインに置くカテゴリが無いです。
存在しないアイテムなどの場合は「"mainEntity": {"@type": "Thing","name": "ゲームのアイテム名",」のようにThingしかないです。
また、同様にその説明に入れる情報は階層としてPropertyValueにするしかありません。

更に2026年今現在のAIに構造化データを作らせるとProductなどとあり得ない提案をして来たりします。
しかしそれらは実際の商品に対するものなのでゲームアイテムがリッチリザルトなどされるとショップを偽装するサイトとして評価が下がります。
ここらへんが最初に書いた通りの「一般人は気にする必要はないです」という事です。
あと記述も厳密でhtmlと違いカンマ一つ違うだけでエラーします。
変に構造化データを入れてページの信頼を落とすより、構造化を入れない方が大半の一般人には正しいです。

当然ある程度は構造化データに更新を求めて提案がされていますが主にgoogleがそれを取り合っていない為、構造化の追加もされてないのが今現在です。閑話休題。

構造化の構造について

さて話を戻して構造データについて。

Thing (最上位:すべての基本)
┃
┣━ Action (動作:検索、購入、予約など)
┃
┣━ CreativeWork (著作物・創作物)
┃   ┣━ Article (記事)
┃   ┃   ┗━ NewsArticle (ニュース記事)
┃   ┣━ Recipe (レシピ)
┃   ┣━ WebPage (ウェブページ)
┃   ┗━ Movie (映画)
┃
┣━ Event (イベント)
┃   ┣━ BusinessEvent (ビジネスイベント)
┃   ┗━ EducationEvent (教育イベント)
┃
┣━ Organization (組織)
┃   ┣━ Corporation (企業)
┃   ┗━ LocalBusiness (地域のお店・施設)
┃       ┣━ FoodEstablishment (飲食店)
┃       ┃   ┗━ Restaurant (レストラン)
┃       ┗━ Store (小売店)
┃
┣━ Person (人物)
┃
┣━ Place (場所)
┃   ┗━ AdministrativeArea (行政区画:市町村など)
┃
┣━ Product (製品・商品)
┃
┗━ Intangible (無形のもの)
    ┣━ ListId (リストの識別)
    ┃   ┗━ ItemList (リスト全般)
    ┃       ┗━ BreadcrumbList (パンくずリスト)
    ┣━ Enumeration (列挙型:在庫状況など)
    ┣━ Language (言語)
    ┗━ StructuredValue (構造化された値:評価、価格など)
        ┣━ AggregateRating (合計評価)
        ┗━ PriceSpecification (価格詳細)
    

全部ではありませんが主要なツリー構造はこういう感じです。
共通プロパティは「name (名前), url (URL), image (画像), description (説明)
これらを使ってサイトの構造を定義します。初手は

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  ...内容
</script>

これです。
ページの情報はhtmlのその一つであっても個々に見ようとするので基本的には「"@graph": [...]」が必要になります。
更に言えばgraphで繋いでも情報が分散するのでidが必要になります。
面倒臭そうに見えますか?はい、実際に面倒臭いです。

ページ構造で必要なのは主に

  • パンくずリスト(最低限これだけあればいい)
  • メインコンテンツ(mainEntity)

形式的には

  <script type="application/ld+json">
  {
    "@context": "https://schema.org",
    "@graph": [
      {
        "@type": "BreadcrumbList",
        "itemListElement": [
          {"@type": "ListItem", "position": 1, "name": "top", "item": "url"},
          {"@type": "ListItem", "position": 2, "name": "階層", "item": "url"},
          {"@type": "ListItem", "position": 3, "name": "現在", "item": "現url"},
        ]
      },
      {
        "@type": "コンテンツのタイプ",
        "url": "現url",
        "name": "ページのタイトル",
        "description": "ページの説明",
        "mainEntity": {
          ...内容
        }
      }
    ]
  }
  </script>

基本一般人が使うのはBreadcrumbList (パンくずリスト)とArticle (記事)ぐらいだと思います。
もうちょっと構造を複雑にしてみましょう。

  <script type="application/ld+json">
  {
    "@context": "https://schema.org",
    "@graph": [
      {
        "@type": "WebSite","@id": "サイトのurl#website",
        "url": "サイトのurl",
        "name": "サイトの名前",
        "description": "サイトの説明",
        "inLanguage": "ja-JP"
      },{
        "@type": "BreadcrumbList","@id": "#breadcrumb",
        "itemListElement": [
          {"@type": "ListItem", "position": 1, "name": "top", "item": "url"},
          {"@type": "ListItem", "position": 2, "name": "階層", "item": "url"},
          {"@type": "ListItem", "position": 3, "name": "現在", "item": "現url"},
        ]
      },{
        "@type": "WebPage","@id": "現ページurl#webpage",
        "url": "現ページurl",
        "name": "ページのタイトル",
        "description": "ページの説明",
        "isPartOf": { "@id": "サイトのurl#website" },
        "breadcrumb": { "@id": "#breadcrumb" },
        "about": {関連の情報},
        "mainEntity": {"@id": "現ページurl#main-categories"},
        "hasPart": [ { "@id": "現ページurl#submenu" }]
      },{
        "@type": "ItemList","@id": "現ページurl/#main-categories",
        "name": "攻略主要カテゴリ","description": "攻略主要カテゴリの説明",
        "itemListElement": [
          {"@type": "ListItem","position": 1,"name": "メインリンク1","url": "url"},
          ...略
          {"@type": "ListItem","position": 8,"name": "メインリンク8","url": "url"}
        ]
      },{
        "@type": "ItemList","@id": "現ページurl#submenu",
        "name": "サブ","description": "サブの説明",
        "itemListElement": [
          {"@type": "ListItem","position": 1,"name": "サブリンク1","url": "url"},
          ...略
          {"@type": "ListItem","position": 5,"name": "サブリンク5","url": "url"}
        ]
      }
    ]
  }
  </script>

・トップの指定。url#websiteは各ページ統一が必要

・isPartOfでどれに属するかを指定

・aboutで関連の情報を追加

・mainEntityをidで指定

・hasPartを使い同様にこのページ内に付属するコンテンツを指定

これくらい出来れば基本的には良いんじゃないかなと思います。

2026年4月5日日曜日

htmlタグの構造

htmlの正しい構造について考える

今回はhtmlの正しい構造について説明します

<body>
<header>
<nav>
  <ul>
    <li>メニュー項目</li>
  </ul>
</nav>
</header>
<main>
<h1>記事のタイトル</h1>
<p>ここにはリード文が入ります。</p>
<section>
<h2>章のタイトル</h2>
<p>文章の段落。</p>
<h3>小見出し</h3>
</section>
<aside>
<p>補足情報など</p>
</aside>
</main>
<footer>
<p>&copy; サイト名</p>
</footer>
</body>

header「ヘッダー」

大抵のサイトでは上部に固定するメニュー部分と考えて良いです。
ここにH1を入れるという考えも一応ありますが、基本的にはページを跨ぐ不変的メニューエリアである場合が多いし、h1を混ぜるのは非推奨です。
H1をここに入れたらページ毎にヘッダー内に書き換えが発生するので面倒です。

また、古いサイトなどにあるロゴなどにh1を指定するような事は止めてください。
H1は後で説明しますがページ全体の主題なので正しくありません。

ヘッダーとかはそもそな話、htmlの構造としてありまりにもヘッダーメインフッターという構造だったため必要になってHTML5で実装されたものです。
そういう意味では昔は本当にシンプルな文章しか想定してなかったのが今はナビが必要になった結果ですね。

nav「ナビゲーション」

主にリンクを纏めるのに使いますがnavタグがありすぎてもダメなのでおおまかにはヘッダー配下にナビを置いてメインメニューの固まりとして使うのが大半だと思います

ul・li「リストタグ」

正直な所「ヘッダー>ナビ>リスト>リンク」という構造はほぼ固定です。
少しかっこよく言えばデファクトスタンダードです。

奇抜なデザインにしたいという願望が無い限りは安定でこの形です。
リストタグ自体は説明文系を挟まない端的な単語の列挙に使います。
ただ逆に言えばリンク群を配置するという時は単語列挙となり結果的にリストになります。

なのでそれが一番最初に使う位置としてはヘッダーナビリンクという感じこの上部で紹介。
構造としてはほぼほぼ定着しています。

リストかテーブルか?と悩んだ時はそれに補足する内容があるかで考えて下さい。
そして、補足や関連する内容が小さければテーブル、文章のような大きさならhタグ系になります。

main「メインコンテンツ」

ページ全体のメインとなる部分をこの部分に入れます。
ヘッダーにH1を入れた場合は

H1「主題」

ページ全体の何が書いてあるかという主題です。
idと違ってH1を複数使う事に対して絶対的な禁止とまではならないものの、事実上ページには1つだけ使ってください。
また、Hタグは階層的に1・2・3...と必ず階層構造が必要です。
H1から飛んでH3など飛んだりはしませんし、H1タグの上にH2タグを配置したりもしません。話の重要度とかの数値ではなくあくまでも文章構造による連番の階層構造です。

H1~H2の間「リード文」

Hが各構造のタイトルではあるが、H1の直下は実は基本的に内容を入れる所ではない。
本当に内容が1つしかなく章を分ける必要がない。またはツール等のでタイトルしかないような場合を除けば情報を表示し始めるはH2からというのが正しい構造。
その為、H1~H2の間はこのページではこういう内容について記述しますという端的な説明と目次を入れるの基本的な構造となります。

p「段落」

最初にpタグを入れるのがリード文の部分だと思うのでここで紹介。
1つの文章の区切りがpタグです。改行はbrを使ってください。ある程度長い文章の文節がこのpタグで区切るという感じです。

文章全般は全てpタグです。pタグが無くてもhtmlに文章は乗せれますが調整したくなった時にcssで調整できなくなるのでやめましょう。
ブログとかだと改行(br)しか存在してない場合もありますが、本来は文章の区切り区切りおきにpタグで区切りのが正しいです。
また、タグを直接見てる側としてはpで区切ってれば分の移動が楽。

section「セクション」

大きな章の区切りに使います。
大きな区切りであれば一応使ってよいという事にはなっていますが、基本的には直下にHタグがほぼ必須と言えます。
ただし、H1自体はページ全体を表すものなので通常sectionでは囲みません。
また、基本的な章の大きな区切りはH2であり、H3以降は細分化する内容となる為基本的な利用方法としては <section><h2></h2><h3></h3>...</section> という構造になります。
明らかに情報量が多いH3などがあれば別ですが基本的にはH2とセットという認識でOKです。

H2「章」

実際の内容を書くのはこのH2からという事になります。
主題のおおまかな内容をH2で区切り更に細かい分類がある場合はH3を使います。
ただし、区分されるものが簡潔で補足するような文章などが無い場合はリストタグを使ってください。

H3~H4「項・細目」

章を更に分割して説明が長くなる場合は分割します。
<section><h2></h2><h3></h3>...</section>
<section><h2></h2><h3></h3><h4></h4>...</section>
みたいな感じにセクション内で個々に深堀りする構造が基本です。

article「アーティクル=記事」

基本的には一旦使わないでので大丈夫です。
ブログやニュースや掲示板などサイト内で更に記事として独立する内容を入れる時に使います。
body内bodyみたいな気持ちです。1ページが独立してしまう記事などはbody直下をarticleで囲んで普通のhtmlみたいに書くと思って問題ないです。
先ずは基礎がないと使う事がないので一旦存在しているという程度に今は認識してください。

aside「アサイド=関連」

メインの文脈からは外れるが、関連性のある補足情報に使用します。
用語解説、関連記事へのリンク、サイドバーなどに使います。
あとは関連が薄いものとして広告などのエリアとしても使われるけどあれは補足じゃないしどうなんだろうか・・・と思っているものの、簡単に言えば隔離エリアとして許されている。

footer「フッター」

基本的には最低限入れるのはコピーライト。
あとはいわゆるフッターメニュー。大抵の場合サイト内循環を促すのに大量のメニューがある。

div「意味を持たないタグ」

divが過去にも説明しているが事実上のデザインタグ。無色透明の箱だと思って良い。
好きなサイズをつくり好きなようにサイズを変更し好きなように着色変更する。
タグで足りない要素全てdivとspanが担っている。

span「意味を持たないタグ」

インラインタグで改行されません。
つまり、文章などの装飾タグです。
インラインで行う足りないタグの全ての担っている。

<body> (ページ全体)
<header>
<nav> (ナビゲーション)
<ul> <li> (メニューのリスト)

※H1を入れるのは非推奨。共通メニューを置く場所。

<main> (メインコンテンツ)
<h1> (ページに1つだけの主題)
H1~H2の隙間 (リード文:内容の端的説明。必要なら+目次)
<section> (意味のある章の区切り)
<h2> (章のタイトル。ここから内容が始まる)
<p> (文章の段落。1つの意味のまとまり)
<h3> (さらに細かい項目の区切り)
<section> (意味のある章の区切り:このように複数でもよい)
<h2> (章のタイトル。ここから内容が始まる)
<p> (文章の段落。1つの意味のまとまり)
<h3> (さらに細かい項目の区切り)
<aside> (補足情報・サイドバー・広告など)
<footer> (コピーライトや補助メニュー)
</body>

2026年1月28日水曜日

Webデザインの歴史をまとめてみる

今回はウェブデザインを纏めてみるお話。phpやリアクトなど動的な技術的は一旦置いておいて原始的なタグの推移のお話。

ウェブページデザインの歴史(主なタグ・技術の変遷)

時期 主なレイアウト/デザイン手法 使われていた主なタグ・技術 特徴・問題点・背景 代表的な見た目例
1991〜1995年 ほぼ純粋な文書構造 <h1>〜<h6>, <p>, <br>, <hr>, <a>, <ul>, <pre> デザインという概念がほぼ存在しない。ブラウザのデフォルト表示に頼る 白背景+黒文字、青いリンク、文字ばかり
1993〜1998年頃 画像+テーブルレイアウトの夜明け <img>, <table>, <tr>, <td>, bgcolor, background, <font> Netscapeの<center>, <font color>, sizeなどが乱発。テーブルで無理やりレイアウト 派手な背景GIF、Under Constructionアイコン、カウンター
1998〜2004年頃 テーブルレイアウト全盛期 <table>, <tr>, <td>, 入れ子テーブル、spacer.gif 最も汚いHTMLが量産された時代。メンテナンス性最悪。CSS1は存在するが普及せず 3Dボタン、ドロップシャドウGIF、フレームサイト
2004〜2010年頃 CSSレイアウト移行期(table → float) <div>, float:left/right, margin, padding, position CSS Zen Gardenで一気に認知。tableレイアウトは「悪」とされるようになる Web 2.0(丸角、グラデーション、ドロップシャドウ)
2007〜2012年頃 スキューモーフィズム+擬似CSS3 CSS3(border-radius, box-shadow, gradient, text-shadow) iPhone登場後、リアル質感が流行。Flash衰退の始まり リアルなレザー、ステッチ、金属質感、グラデボタン
2010〜2015年頃 レスポンシブデザインの確立 @media クエリ, max-width, flexible images, fluid grid Ethan Marcotteの「Responsive Web Design」論文(2010)が決定打 スマホ対応で崩れないレイアウトが必須に
2013〜2018年頃 フラットデザイン全盛期 flexbox (display:flex), フラット色、アイコンSVG iOS7でスキューモーフィズム終了宣言。ミニマリズム+大胆な色 ドロップシャドウほぼ消滅、フラット2.0(微妙な影)
2014〜現在 グリッドレイアウトの本格普及 display: grid, grid-template-columns, gap 2017年頃から主要ブラウザが一斉対応。float卒業の最終兵器 複雑なカード配置、マガジン風レイアウトが容易に
2017〜現在 CSS変数、カスタムプロパティ、コンテナクエリ --変数名, calc(), @container テーマ切り替え、ダークモードが劇的に楽に。設計思想が大きく変わる デザインシステム対応が容易に
2020〜現在 ニューモーフィズム / Glassmorphism / 3D風 backdrop-filter: blur(), filter: drop-shadow(), 3D変形 ミニマリズムの飽き+立体感回帰。GPUアクセラレーション前提 フロストガラス、ソフトUI、微妙な奥行き表現
2022〜2026現在 変数・論理演算・scroll-driven animation @property, color-mix(), animation-timeline: scroll() ほぼJavaScript無しで複雑なアニメ・配色・レイアウトが可能に スクロールで動く高度な演出、AI生成背景など

結局は「格子」へ回帰:ウェブデザインの螺旋進化

歴史は繰り返すとはよく言ったもので、ウェブの歴史を俯瞰すると画面を「情報の格子(グリッド)」として整理するのが、人間にとって最も直感的だという結論に、何度も戻ってきている。 初期の<table>乱用から始まり、floatの混沌、Flexboxの柔軟性、そしてCSS Gridの完成形へ——不自由を解消しながら、結局「2次元の骨組み」が最適解だったという皮肉な軌跡になっている。

1. 「脱テーブル」運動と、制御の難しいfloat時代

2000年代前半、<table>によるレイアウトは「構造を破壊する悪」とされ、CSS floatへの移行が強く推奨されました。
つまり、タグはそのタグ名の意味に合わせて正しく使おうというだけの話です。
tableはデータ一覧など表を作るものであってデザインに使うのは正しくないとシンプルな理由ですね。
次に注目されたのはfloatで、floatは自動折り返しが可能で理論上優れていましたが、現実は「浮遊」の名にふさわしく扱いが難しかった。

floatの致命的な落とし穴

要素を「浮かせる」性質上、後続コンテンツが下に潜り込みやすく、崩壊を防ぐためのclearfixハック(空divや::after偽要素)が必須に。1つ忘れただけでページ全体が崩れる——当時の開発者の悪夢だった。

2. スマホ革命と、Flex → Gridへのスムーズ移行

2007年のiPhone登場で「m.ドメイン」の二重管理が限界を迎え、2010年にレスポンシブデザインが提唱されます。
現代の人には分からないと思いますが「m.ドメイン」というのはガラケーなどのかなり小さな画面向けに1つのサイトに対してPC用と携帯用の実質2つサイト作っていたのです。
スマホが普及するにつれ、ある程度画面幅が確保された事で、1つのサイトが幅によって自動でコンテンツ表示を調整する方が良いという考えに至ったという事です。
この画面幅によって自動的に最適化しようというのがレスポンシブデザインです。

float自体はコンテンツを自動改行でき、レスポンシブとも相性が良かったのである程度続きますがデザイン方法が直感的ではないため苦しめられた人も多かったと思います。
Flexbox(2012年頃本格普及)はfloatの不安定さを解消し、方向性の並べ替えを簡単に実現できました。
ただ、Flexは1次元でのデザインとなるので少し機能面不足があり続けて作られたのがGridという概念です。
ただ、出始めは一部ブラウザが対応してないなどで利用が限られました。

いやまぁ、大抵のタグ問題はIEが最新のタグに対応出来ないという問題が多かったと思います。
そして、根幹的な最大の問題はWindowsのデフォルトブラウザだったせいで切り捨てるの難しかったという側面も大きい。

そして2017年以降、CSS Gridの主要ブラウザ完全対応により、2次元レイアウトが本格的に可能に。
floatやclearfixのような「回避策」はほぼ不要となり、2026年現在、レイアウト目的のfloatは絶滅危惧種と言えます。

3. 最大の皮肉:本物の表データでさえ<table>を避ける現代

Gridが成熟した今、面白い逆転が起きている。
かつて「脱テーブル」を叫んだ私たちが、今度は「本当に表形式のデータすら、<table>を使わずdiv+Gridで作りたがる」という矛盾を抱えている。
Tableタグは柔軟性が低くそのままではレスポンシブでもはみ出やすい。
例えば、幅を単に100%にすると幅に収まるが表が超縦長になる。
なので、Tableはdivで囲んでoverflowとセット、角を丸める等にしてもdivで囲んだ方良い。
ただ、それなら最初からdivで表にしようと思うのは自然な考えだと思います。

なんならリストだったり、ボタンも意味タグを使うよりも柔軟にできるdivを使う場合もあると思います。
こうなってしまうと全てがdivでclassを見なければ何を意味するのが構造が理解しにくい。
個人的には意味タグを優先して使うがWebツールなどの場合はどうしてもdivで代替する事はやはりある。

なぜdiv+Gridを選ぶのか

React/Vueなどのコンポーネント駆動開発では、<table>の厳格な親子構造よりdivの方が柔軟。レスポンシブで「列をカードに変形」「仮想スクロール」「ソート・フィルタUIのカスタム」が容易だからだ。TanStack Tableなどのライブラリも、内部でdivベース+ARIAを駆使している。

アクセシビリティの再来する代償

見た目は表でも、divの塊ではスクリーンリーダーに「行・列の関係」が伝わりにくい。かつてのtableレイアウトと同じく、意味の欠落が起きている。2026年現在、WCAGも「真の表データは<table>を推奨」と再確認しつつ、開発現場では「利便性>セマンティクス」のトレードオフが続いている。


デザインは歴史を繰り返しながら少しずつ上に

意味の違う「箱(table)」→扱いの難しい「浮遊(float)」→デバイス分断の時代を経て、ウェブは再び「進化した格子(Grid)」に戻ってきた。
 Flexboxでfloatは減り、Gridでfloatはほぼ消滅。過去の不便を解消しながら、「情報の2次元整理」という本質だけは変わらず残る。

2026年の今、Subgridやmasonryレイアウト、container queriesが加わり、Gridはさらに脳に優しいツールへ進化中。結局、人間は「視覚的な格子」を愛している——歴史は螺旋状に、しかし確実に上へ進んでいる。

2026年1月20日火曜日

サイトデザインを更新するぞ

サイトデザイン更新

時間があるうちにサイトのデザインを更新する事にしました。
前の状態はこんな感じ。

■Twitterウィジェット

画面中央左の空きはTwitterのツイートウィジェットです。
仕様が変わった事で見てるブラウザでログインしてない限りは表示されなくなりました
逆に言えば、仕様が変わっても𝕏にログインさえしてればツイートがちゃんと表示されるんですがブラウザにログインセッションがないとガラ空きになってしまう。
スマホアクセス時はバッサリツイート表示を消してたのでまぁそもそも別にいらないかな。

■更新履歴

内部スクロールに詰めてたけど数個だけ表示してあとはmoreで履歴ページにまとめよう。

■リンク周り

一旦整理するのに大半を除外。

■ヘッダーとフッター

遥か昔に更新が面倒なのでもともとヘッダーとフッターはjavascriptで生成して埋め込んでいました。
ですが昔のクローラーはjavascriptを全く読まないのでサイトの奥へリンクを読みにいけないためSEO的にダメという事でhtml側に書くようにした経緯があります。
メニューを更新したくなかったからメインメニューを減らしたんですよ。

現在のサイトデザイン

まぁ暫定ですが一旦更新したのがこちら


モダンとは何かが良く分からないけどまぁ色々モダンに寄り添うようには頑張ったはず。

■サイトのトップ

最近の流行りというかなんというかサイトを開いたら「ヒーローイメージ」という画像をバァンと出して、キャッチコピーなどをドカンと入れるのが主流(たぶん)。
勿論サイトの種類に寄りますが折角絵を描いてるしそれに倣う事にしました。
とは言え最近絵を描いてなかったから幅2000~3000pxの絵があまりなくて、今回はオリキャラのロロさんじゃなくて、闇玉藻をバァンと配置しました。
超いにしえのサイトが中央に「入口」みたいなリンクがあるのを彷彿とさせるというのはデザインが一周回ったという可能性がある。

■サイトの横幅

前回の横幅サイズは1000pxにしていました。
今回の横幅は1280pxです。
2025年前後で現在PCディスプレイの解像度は1920px、1536pxの幅が多いです。
マックスサイズで開く事はあまりないのでそれより狭い幅が良いかと。
指標的なものは余りありませんがTailwind CSSのコンテナ幅で2xlが1536px、xlが1280pxという感じなので広げ過ぎても情報が横に伸びるため今回は1280pxにしました。

■基本メニュー

TOPは100vh-数十ピクセルで上下を黒線で映画画面な形にする事で引き締めてあります。
なので必ずスクロールが必要でヒーローイメージで1ページを占有させたので基本メニューはその下に全部あります。
機能面で言えば機能性が悪いです。
まぁでも自分のサイトの構成上メイントップよりサイト内サイト構成になってるのでそちらに直接アクセスする方が多いだろうから別にいいかなって割り切った。

■モダンって何だろうね・・・

grokにモダンっぽいを聞いたらメニューをガラス表現のトップ追従とかがモダンっぽいと言ってたんだけどエフェクトでわざわざ重くすることはないなと。
appleが良くやってます見栄えが良くなりますってメッチャ推してきたけど保留。
いやまぁモダン的な動きを付けるとどれも重くなるだけなんだけどさ。
個人的には情報を見る時に注視してる外で物が動くのが嫌なのでサイト内で動的な所は少ないです。
メニューが少し遅く表示されるのはReactの読み込みをラグを体感させないためにそうしています。遅れてぱっと出るとガク付きを感じますが、元を0%表示からゆっくり出す事でで読み込みラグがあってもメニューの表示がそういう演出に見える様にしました。

■ダークモード

現在サイトを見てる人の大半はダークモードで見てる割合が5割を超える
トグルで切り替え付けた方がベターだとは思ったけど面倒になったのでサイト全体を強制ダークベースにしました。

■ヘッダーとフッター

最近はベタhtmlの方が確実とはいえ生成コンテンツ部分も読むみたいなので今回はReact18でヘッダーとフッターを作る様に変更。
React19だとsrcでjsxが変換できないため18です。割とお試し実装なのでCDN経由。使えなくなりそう時はちゃんと実装します。
現在はバベル経由でwebで直ビルド。
一応jsが無効な時用に最低限のヘッダーはindexへのリンク、footerはコピーライトだけが残る様にベタcssで入れてあります。

■cssフレームワーク

今回はメインのcssはスカスカにしてあります。
こちらも結構お試しの感覚でCDNでTailwind を入れています。
今でもコード見るとやはりごちゃごちゃして汚く感じるものの確かにsrcのcssと往復しなくていいのはデザインいじりが捗ります。
まぁただ前回の記事でも話した通りTailwind の真価がでるのはReactなどのコンテンツに押し込んで使った時なのでベタhtmlに書いている今回の場合はそりゃあそう感じるのは仕方ない。

■レスポンシブの対応方法

TWのmdでちょこちょこメディアクエリを入れてる所はありますが基本的には最低と最大幅のコンテンツdivを作って自動折り返し。
今回は幅広めなので指定数で幅が狭くなったら1列にするという形ではなくて、幅があるだけ横にアイテムを詰めて、狭くなるだけアイテム列が減っていく形にしてあります。

2025年4月27日日曜日

onclickを廃止した話

「Hey!Scripting Cat!モジュール読み込みにしたらボタンのonclickで関数が実行できなった!どうすればいい?」

なるほど良くある話ですね。HTML の onclick 属性は、イベント発生時にグローバルスコープで評価されるため、モジュールスコープ内で定義された関数を直接参照しようとすると、その関数が見つからず実行できません。

じゃあonclickが使えなくなるのかと言えばそうではありません。

モジュール読み込みでボタンから関数を実行する方法

web上のjavascriptにはグローバル領域に直接スクリプトを読み込む方法とモジュール(module)で読み込む方法の主に二種類があります。
今回の目標はボタンを押して関数を実行する事が目的です。
工程は2つあります「ボタンを押す」「関数実行」。これを実現する方法は2つ存在します。


1.window.領域に関数を持ってくる(非推奨)

今までの感覚を変更しないのであれば一番簡単です。
変更するのは関数側です。

■js
function moduleFunction() {console.log('関数実行');}
window.moduleFunction = moduleFunction;

これだけです。htmlも変更不要で簡単ですね。
現在onclickが動かないというのはつまりグローバル領域に関数が居ない為です。
じゃあ何処にいるのかというとモジュールスコープ領域に居ます。

つまり、window.関数名に現在の関数名を代入すればモジュール内の関数をhtml側からonclickで実行できます。折角モジュール読み込みするのであれば(スコープを気にし始めたのなら)一応非推奨ではありますが他の関数等はモジュールにいるので今までの通りの方法「<script src="script.js"></script>」でただjsを読み込むだけより全然良いと思います。
onclickが出来ないならレガシーな通常読み込みに戻そうと考えてしまうより一旦はこの方法で良いと思います。モダンへの入り口は広い方がいい。


モジュールに移行する理由

個人や小規模なサイトであれば必ずしもモジュール読み込みの形式にする必要はありません。ただ、そもそもモジュールで読み込む方法が生まれたという事は理由が、つまり利点があるから実装されました。

最大の理由はおそらく名前の衝突です。グローバルスコープに全ての変数や関数があると衝突して正しく動かなくなる可能性高くなります。

<script type="module" ></script>で直接モジュール領域を作ったり
<script type="module" src="script.js"></script>モジュール読み込みを行うとグローバルスコープを侵さずに衝突しない領域を作ることができます。

次に個々に領域を分断した事でそれをつなぐインポートとエクスポートが便利だからです。
これも結局はスコープの制御がしやすいという話に帰結します。


2.addEventListenerでボタン待ちをする

さて、次はよりモダンな方法です。
まずはボタンにidを付けます(他にも方法はある後述)。
■html
<button id="mybutton">ボタン</button>
■js
function moduleFunction() {console.log('関数実行');}
document.getElementById("mybutton").addEventListener('click', moduleFunction)

これだけです。それほど難しくはなりません。


モジュールのトップレベルのコードは、モジュールが最初に読み込まれ、評価される際に一度だけ実行されます。このタイミングで addEventListener を呼び出すことで、ボタン要素にクリックイベントのリスナーが登録され、ボタンがクリックされるのを待機する状態になります。

これによってボタンが押されるとidで対象のボタンが特定されクリックが実行されたことでmoduleFunctionを実行できます。
少し注意点としては「addEventListener('click', moduleFunction)」の関数名部分(この場合「moduleFunction」)には「()」をつけてはいけません。
関数登録に括弧が付くとその位置で即時関数が実行されてしまいます。

※ボタンを特定する他の方法
id 以外に、nameやclassやタグ名で要素を取得できます。
・class(例: document.querySelector('.mybutton'))
・タグ(例: document.querySelectorAll('button'))


引数を渡したい場合

括弧が無ければじゃあ引数渡せないのかというとそうではなく
document.getElementById("mybutton").addEventListener('click', ()=>{moduleFunction(1)})
とすれば引数を渡す事が出来ます。
これでonclickとはさよならできますね。

関数に飛ばさず直接処理する場合

document.getElementById("mybutton").addEventListener('click', ()=>{ここに処理を記述する})

こうするだけでOK。
さらっと流してるアロー関数部分は前の記事を参照してください。(https://blackstraycatreboot.blogspot.com/2025/04/blog-post.html)
要するに先ほどアロー関数に関数名を記述してるのは無名関数にする事で処理領域を確保して、この領域で改めて関数にキックしてたわけです。
ですから、ここに関数を記述せずに処理を記述すればOK!



余談

ちなみに「addEventListener」は実行時にイベントオブジェクトを渡します。
この場合、'click' イベントに対するリスナーなので、event は クリックイベント に関する情報を保持します。
今回のclick イベントの場合はeventの型はMouseEvent オブジェクト。
MouseEvent は Event クラスの派生型で、クリック固有のプロパティ(例: マウス座標)を含みます。


function moduleFunction(arg, event) {
  console.log(`引数: ${arg}`);
  // イベントオブジェクトの詳細を確認
  console.log(`クリックされた要素:`, event.target);
  console.log('イベントオブジェクト:', event);
  console.log('type:', event.type); // "click"
  console.log('target:', event.target); // <button id="mybutton">...
  console.log('clientX/Y:', event.clientX, event.clientY); // 例: 150, 200
  console.log('ctrlKey:', event.ctrlKey); // 例: false
}
document.getElementById('mybutton').addEventListener('click', (event) => {
  moduleFunction(1, event); // event オブジェクトを渡す
});

こういった情報取得も可能です。
ただまぁ今回は「ボタンを押す」「関数実行」が主題なので今回はこれで終了。

2025年4月22日火曜日

script type="module"に変更して外部ファイルを読み込む

今回のお題はメインとなるjsの可読性を上げようかなって話
まぁそういう意味では前回の「document.getElementById」を毎回書くのを止めようかなって話と同じですね。

javascriptで長いコードを外部化する方法

まず、古来からのjavascriptの読み込み方法というのは

<script type="text/JavaScript" src="./main.js"></script>

こんな感じです。
ですがこの読み込み方法では外部ファイルjsを参照出来ません。
jsのファイルの読み込み方法から変更する必要があります。

<script type="module" src="main.js"></script>

この様にタイプの指定をmoduleという指定方法でjavascriptを読み込みます。

①従来の読み込み方法

違いとしては古来の方法は「window.」というブラウザのグローバル空間で定義されていています。例えば
window.a=10
var a=10
と、どちらで定義しても同じです。「window.」のプロパティの形で登録されていて暗黙的に省略してるだけです。
通常の関数もそうです。

function aaa() { console.log("こんにちは");}
console.log(window.aaa); // 関数 aaa
aaa(); 


じゃあ、node.jsの場合は?となる人も居るかと思いますがnodeでは「global.」オブジェクトに定義されます。ですので、

global.myVar = 10;
console.log(global.myVar); // 10
console.log(myVar); // 10

nodeではこんな感じになります。


話しを戻して、例えば、
<script type="text/JavaScript" src="./main1.js"></script>
<script type="text/JavaScript" src="./main2.js"></script>
と、二つ読み込んだ場合はどちらにコードを記載してもどちらかでも変数にも関数にもアクセスできます。
main1に「function a(){ console.log("test");}」と記述しているならば、main2で「a()」と書くだけでアクセスできます。

ファイル自体は分かれていても、コードの処理領域・スコープが同じなのです。

更に言えば読み込んでいるhtml側もそうです。
例えば、
<button onclick="a()">ぼたん</button>
はボタンを押すだけで「a()」を実行できます。

②モジュールの読み込み方法

次にmoduleですが、こちらは処理領域がjsのファイル内に閉じられています。
<script type="module" src="main1.js"></script>
<script type="module" src="main2.js"></script>

古来の方法通り普通にhtmlに読み込んでるように見えますがhtml側とモジュール側では領域が断絶されています。jsのトップレベルにあるコードは実行されますがそれだけです。

例えばmain1.jsに「function a(){ console.log("test");}」記述されている時に
html側から「<button onclick="a()">ぼたん</button>」を押しても実行出来ません。
「window.」領域にモジュールの内容がいない為html側からアクセスできません。
対応については順番に説明します。

②-1:モジュールのスコープ

例えば、main1.jsに「var b=10」を定義した場合、この変数bを使えるのはmain1.jsだけです。html側からも他のjsファイルもアクセス出来ません。
関数を定義した場合も同様で、「const c = (x) => x+1」のように定義した場合、html側からも他のjsファイルからもアクセス出来ません。


②-2:他のjsファイルへのアクセス

htmlとのやり取りの前に先に他のjsとのやり取りを先に説明します
現状ではmain1.jsは完全に独立していて他のjsに影響されないしmain1.jsも他のjsへは影響を与える事は出来ません。
どうするかというと、他のjsへアクセスするにはエクスポートとインポートが必要になります。
インポートはエクスポートされているものしか参照出来ません。
つまりjsのファイル間で合意が必要になります。「使って良い処理を出す側」と「使いたい処理を受ける側」これが一致して初めて外部のファイルを参照して利用できます。
インポート側が一方的に好きな変数や関数を参照出来ないという事です。
この方式はコーディング的にスコープ周りは強固ですが面倒臭いのは否めない。


②-2-1:エクスポートする側

まず、エクスポートして貰わないとそもそもインポートも出来ない形式なので先にエクスポートの方法について。

1.外部参照させたい変数や関数の頭全てに「export 」を記述する方法
export const aa=1
export const bb=2
const cc=3
export function dd() {}
export function ee() {}
function ff() {}
「export 」が付いていないものは外部からは参照出来ません。
コードを流してみた時に頭に「export 」があるかどうかで外部から見れるかが直ぐに分かります。

2.一番最後に「export 」対象を列挙する方法①
const aa=1
const bb=2
const cc=3
function dd() {}
function ee() {}
function ff() {}
export { aa, bb, ee,ff};//まとめて指定
こちらは最後に対象の変数や関数を指定する方法です。各定義の頭に「export 」を付ける必要はありません。既存のコードがある場合は全ての対象にexport を付けなおす必要はないので楽かもしれません。
逆に言えば流し見した時にどれがエクスポート対象かは分かりません。最後のリストから名前で検索して内容を確認する必要があるかも。
また、ある程度量がある場合列挙するのがそれはそれで面倒かもしれない。

3.一番最後に「export 」対象を列挙する方法②「デフォルトエクスポート」
const aa=1
const bb=2
const cc=3
function dd() {}
function ee() {}
function ff() {}
export { aa, bb, ee,ff};//まとめて指定
export default { bb, dd, ee,ff}; // デフォルトエクスポート
モジュールにつき1回だけ可能な指定方法、手間的には対象を列挙①と変わりません。
インポート時に楽が出来るかどうかの違いです。詳細はインポート側で説明。

②-2-2:インポートする側

さて、エクスポート対象が決まったらやっとインポート側で参照できるようになります。
エクスポート側では対象全てをエクスポートするみたいな事は出来ませんがインポート側は多少は柔軟でエクスポートを一括で取り込むことも可能

1.エクスポートされた変数関数をそのまま使えるようにする
import { aa, bb, dd } from './db.js';
console.log(aa);
console.log(dd());
エクスポートされた変数や関数の名前を指定して名前を変えずそのままそれを使えるようにします

2.一括取り込み①「export default」読み込み
import datas from './db.js'; 
console.log(datas.aa);
console.log(datas.dd());
オブジェクトの様に一括で取り込み、プロパティの様に対象全てを利用する事が出来ます。
オブジェクト名は好きな名前を付ける事が出来ます。
記述時に「{}」が不要な所は注意
モジュール1つにつき1回だけ可能。

3.一括取り込み②名前空間で「*」全指定する
import * as datas2 from './db.js';
console.log(datas2.aa);
console.log(datas2.dd());
エクスポート対象を*で全て対象にしてasで名前を付けて纏めています
こちらもオブジェクトとプロパティの様に対象対象全てを利用できます

4.エクスポートされた変数関数の名前を変更して取り込む
import { aa as zz, dd as yy} from './db.js';
console.log(zz);
console.log(yy());
エクスポートされた変数や関数の名前を指定した後にasで変数関数の名前を変更して取り込みます。

5.一旦全て取り込んで個別に取り出す(分割代入)
import * as datas2 from './db.js';
const { aa, dd } = datas2 ;
console.log(aa);
console.log(dd());
一旦全て取り込むのは既に紹介しましたがオブジェクトとプロパティのようなアクセスでした。分割代入を使えば元の名前で変数関数を取り出して使う事ができます。

html側からアクションを起こす方法

コード側のやり取りの説明が終わったので今度はhtmlからのアクションはどうするのかについてです。
「window.」空間外にjavascriptがいる為アクセス出来ません。しかもjsと違ってhtml側からではインポートの構文が使えません。解決方法は主に2つ。

①「window.」空間に来てもらう

html側からアクセス出来ないのは「window.」空間に対象の変数も関数も居ない為アクセスできないのですから、js側で「window.」に定義してhtml側の空間に下りてきて貰えばいいのです。
■js(module)
function dd() {}
window.dd=dd;
■html
<button onclick="dd()">ボタンをクリック</button>
こうする事でモジュール空間にあった変数や関数を「window.」空間に定義してhtml側からでもアクセスできるようになります

②イベントリスナーでjs側からhtml側アクション待ちで待機する

■js(module)
function dd() {}
document.getElementById("pp").addEventListener("click", dd);
■html
<button id="pp">ボタンをクリック</button>
onclickと違い一方方向にアクションが進んでいくのではなくjs側で待ち状態にしてhtml側のアクションの後にjs側でアクションされた対象を特定して実行する
どのボタンかの特定が必要に足る為idなどの識別子は必ず必要になる。

③「window.」空間の上にオブジェクトの空間を挟む

■js(module)
function dd() {}
window.obj1= window.App || {};
window.obj1.dd= dd;
■html
<button onclick="obj1.dd()">ボタンをクリック</button>
これは①のちょっと安全版みたいなもので完全なグローバル空間の「window.」の上にオブジェクトを作成して、一階層浮かせたグローバル空間で処理をする方法です。
一階層浮かせているのでonclickで実行する時にオブジェクト名も必要になります。

━━━━━━━━━━━━━
■終わりに
現状のjavascriptの一部を分離するために色々と調べたんだけど今から分割するのは手間が掛かり過ぎるかも・・・うーん困った。
調べる前は外部ファイルに定義して必要なものだけ引っ張ってこればいいのかなと思っていたけどエクスポートとインポートが相互で処理が必要で思ったより簡単ではなかった。
修正するかもしれないけど一旦保留にして次何か作る時はちょっとモジュール思考で考えてみよう。

2024年12月9日月曜日

Grid Layout(display: grid)でのグリッドデザイン

 さて、前回「タグの意味とデザインタグ」という記事を書きました。
webデザインを行う時にdivとspanこの二つが何のためのタグなのかと、ちゃんとしたデザインタグというものは存在せずタグとして使用用途として無色であるdivとspanが結果的にデザインのタグに使われている。

・・・という感じの内容でした。
今回は、divに新しく追加された・・・いや2011年ごろからの実装なので全然はるか前なのですがこれまでよりデザインに特化した方法について説明します。

実は家にあるDWはCS4なので対応してなかったからずっと放置していたんですが、ついに手を付け始めました。

概念としてはdivをtableの様に格子状に管理してデザインするというものです。
まぁ実際問題として、いにしえのtableデザインは扱いやすかったという事ですね。

floatで浮かして並べて、clear:both; で浮かすのをやめるみたいな構造は確かに分かりにくい。少なからずDWでtableの格子を繋げたり切ったりする方がデザイン的に直感的に見えてしまう。

display: gridはこの格子デザイン概念の良い所だけを得られます。
しかも、子要素のdivはグリッドの好きな位置へ移動でき、逆順にするなども容易。
レスポンシブなデザインとも親和性が高い。

gridの格子概念を理解する

基本構造は簡単です。親要素のdivを指定すると、中のdivを全てグリッドに並べてくれます。
親のdivはgridの列を指定すれば良いだけです。
行(row)の概念もありますが、まずは列がどのように処理されるか分かれば理解できると思います。

「display:grid;grid-template-columns: 20px 20px 20px;」


<div style="display:grid;grid-template-columns: 20px 20px 20px;background-color:#eee">
<div style="background-color:#FAA">1</div>
<div style="background-color:#AFA">2</div>
<div style="background-color:#AAF">3</div>
<div style="background-color:#AAA">4</div>
</div>

1
2
3
4
この様になります。
親divの幅指定が内部全てに反映されます。
また、幅指定を3つだけしたので4つめからは次の行となります。

今回はpxで指定しましたが今回は新たな単位を覚えましょう。
「fr」です。

今まで固定幅は「px」、割合を指定する時は「%」を使っていました。
今回新たに「%」に変わる割合指定方法です。
frはfraction(分数)の略で、等分したときの割合です。
水溶液とかと一緒です。一般的な例でいればカルピスと水の割合は「1:5」みたいな。
上記の例をpxからfrに置き換えてみます。
「display:grid;grid-template-columns: 1fr 1fr 1fr」

<div style="display:grid;grid-template-columns: 1fr 1fr 1fr;background-color:#eee">
<div style="background-color:#FAA">1</div>
<div style="background-color:#AFA">2</div>
<div style="background-color:#AAF">3</div>
<div style="background-color:#AAA">4</div>
</div>
1
2
3
4
さてするとどうでしょうか幅指定は「1:1:1」等幅なのでこのようになります。
じゃあ今度は末端の幅を2frにしてみます。
<div style="display:grid;grid-template-columns: 1fr 1fr 2fr;background-color:#eee">
<div style="background-color:#FAA">①</div>
<div style="background-color:#AFA">②</div>
<div style="background-color:#AAF">③</div>
<div style="background-color:#AAA">④</div>
</div>
この様になります。
「1:1:2」の割合となるので①と②は同じ幅、③は2倍となります。
今までは3分割するなら「33%」で、「1:1:2」の比率にするなら「25%・25%・50%」みたいな割合を自分で計算してパーセントにしていましたがfr指定の登場で分割割合だけ指定すれば良くなったという事です。

また、1frは使用可能な領域の余りを等分します。
ですので、左を30pxで固定して残りを可変としたい場合は「30px 1fr」と指定します。
<div style="background-color: #eeeeee; display: grid; grid-template-columns:30px 1fr;">
<div style="background-color:#FAA">①</div>
<div style="background-color:#AFA">②</div>
<div style="background-color:#AAF">③</div>
<div style="background-color:#AAA">④</div>
</div>

このように一部分を固定して残りを可変にする事も可能。

2023年8月15日火曜日

タグの意味とデザインタグ

タグの意味とデザインタグ

タグ 意味 要素
h1大見出しブロック要素
p段落ブロック要素
ulとli箇条書きブロック要素
table表(一覧)ブロック要素
div意味を持たないブロック要素
span意味を持たないインライン要素

さて、少しだけピックアップしましたが、例えばタイトルなどはh1タグを使います。
段落を区切る場合はpタグ、箇条書きならulタグを使います。

tableタグはデザインで避けられがちでdivで無理やり表にしている人もいますがある程度のデータ量があるならばそれはtableタグで纏めるべきです。

単一の情報を並べるだけなら箇条書きだし、2つ以上の情報の掛け合いによって意味をなすデータであるならば表であるべきです。

htmlは意味のあるタグはその意味の通りに使おう。
というのが前提の元に考えられています。

なので基本的に特定のタグを使う場合は「~タグ」は「こう使うべき」と明確に決まっています。

我々がデザインする上で実はデザインタグというものは存在していません
現在デザインするのにdivが意味を持たないブロック要素であるからこれを使っています。

また、現在はCSS(Cascading Style Sheets/ カスケーディングスタイルシート )で文章と装飾は分けるのを基本にしています。
同様にjs(javascript)で動的操作や動的機能を分けるのを基本とする。

こうする事で、本来の『情報』と『デザイン』と『機能』を分離して考える事が出来ます。
ウェブを巡回しているクローラーなどは正しい意味の通りにタグが使われている事で正しく文章の内容、文章の重要度や順序を正しく判定する事ができます。

このように整理されてきた結果html上で直接デザインに影響するcenterタグなどいくつかのタグは徐々に非推奨や廃止の方向に向かっています。

これらは結果的にメンテナンス性を上げ、人間にとっても見やすい表示になると考えられています。

ブロック要素とインライン要素

ブロック要素というのは、コンテンツの内容が一つの塊という事です。
基本的に幅100%で左右に自動改行される要素です。
(まぁ左右改行というよりどちらかと言えばこの範囲が100%で両端まで潰すために上下に押し出すイメージです。)
ブロックですので、高さや幅を指定する事が出来ます。

逆にインライン要素というのはコンテンツの一部に配置される要素であり、文中の一部を強調表示したりする様に情報の途中に一部変化を加えるものです。
ですのでインライン要素では改行要素は付きませんし高さや幅を指定出来ません

divとspanの違い

まず根源的な話をすればこの二つの違いは
「div=display: block」
「span=display: inline」
のたったこれだけです。

どちらも意味を持たないタグであるため、divにdisplay: inlineした場合はspanと同じ様に扱えます。
ただ、このように設定されているという事は、divはコンテンツの一つのデータのブロック単位である事をさしており、逆にspanはコンテンツの一部の変化に使うべきものです。

divにdisplay: inlineを指定するなら最初からspanを使うべきであり、逆にspanにdisplay: blockを指定するなら最初からdivを使うべきです。

つまりどちらも意味を持たないタグとはなっていますが
・divはコンテンツのブロック単位で使うタグ
・spanはコンテンツの一部で使うタグ
と言う最低限の意味を持っている事になります。

div内のdivを中央揃え

内側のdivに「style="width:100px;margin:0 auto;"」を追加するだけで良いです。
幅は任意に変えて下さい。これは他のブロック要素も同様です。

仕組みとして二つの要素があります

  • 「幅を指定」
  • 「左右の余白を自動調整」

divは幅100%がデフォルト設定です。
ですので幅を指定して左右に余白を作ります

インライン要素の場合、たとえばテキストなどは外側の親要素に「text-align:center; 」を指定しますがdiv内のdivを中央に寄せる場合は違います。

<div><span>内容</span></div>
である場合は
<div style="text-align:center"><span>内容</span></div>

<div><div>内容</div></div>
の場合は外側のdivに指定は不要です。

<div>余白自動調整<div style="width:100px; margin:0 auto;">内容</div>余白自動調整</div>

内部のdiv自身が左右の余白を自動調整することで結果的に中央にコンテンツが配置されます。

ボックス構造

マージン (margin)
枠線 (border)
余白 (padding)
コンテンツ
余白(padding)
枠線(border)
マージン(margin)

コンテンツとそれを囲む枠線は認識しやすいと思います。
・余白は枠線とコンテンツの間部分:無色透明
・マージンはこのボックスと外側の間部分:無色透明

指定 指定範囲/指定方法
margin
padding
・値が1つ:上下左右
・値が2つ:上下 / 左右
・値が3つ:上 / 左右 / 下
・値が4つ:上 / 右 / 下 / 左
margin:10px 20px;
border-style
solid (実線)dashed (破線)dotted (点線)double (二重線)
border-color

■色の指定方法

・「red」等:文字指定
・「#FF0000」等:#RGB指定
・「rgb(255,100,10)」等:数値指定

例えば「margin:10px 10px;」と指定した場合
つまり「margin:[上下10px余白] [左右10px余白]」と指定されます。

2023年7月17日月曜日

viewportに挑戦した話

今回はタイトルの通りviewportに挑戦した話です。
アクセス解析は忍者ツールズの埋め込みとGoogle Search Consoleを使っています。
Google Search Consoleはサイトのダメ出しもしてくれます。

スマホでみても拡大すりゃいいんじゃないと思っていたのでサーチコンソールのモバイルユーザビリティが全て警告なのをしばらく放置していたのですがついにメスを入れる事にしました。

具体的には
ページがモバイルで利用できない理由
以下の問題があるページでは、良好なページ エクスペリエンスが実現されません。
  • テキストが小さすぎて読めません
  • クリック可能な要素同士が近すぎます
  • ビューポートが設定されていません
  • コンテンツの幅が画面の幅を超えています
たぶん、単にサイトを作ってる人はこうなるんじゃないかなと思います。

問題1:テキストが小さすぎて読めません

現在推奨されてるフォントサイズはおおよそですが14px~18pxで自サイトでのサイズはだいたいが12pxなので確かに小さいのかと思ったのですが根本的な問題はそこじゃありません。
勿論フォントサイズを大きくすればこの警告は消せるのですがこんどはPCで大きくなりま過ぎます。

この警告が言いたいのはPC向けに作られている場合、スマホなどで表示するとコンテンツ幅で表示するので「サイトを開いた際に拡大しないと文字が読めない」これです。


問題2:クリック可能な要素同士が近すぎます。

これはほぼ上記に付随します。PC向けサイトを普通に作って入れる場合はそんなクリックし辛いとかはまずないです。
上記同様にこの警告が言いたいのは「サイトを開いた際に拡大しないとリンクエリアが小さくなりすぎて隣接するリンクが2つ以上あると押し間違いしちゃう」こんな感じです。

問題3:ビューポートが設定されていません

これは上記二つを解消するものです。
ビューポートを設定するとサイトに入った瞬間にスマホなどで適切な画面幅で表示されます。
タグを入れるとぱっと見は「最初からズームで表示されている状態」になるだけです。
ただこのビューポートを設定したこの状態は「この範囲がスマホ等の適切な見える範囲だよ」って意味です。

問題4:コンテンツの幅が画面の幅を超えています

これはビューポートを設定した時に「ウェブページが画面はみ出てる」って意味です。


問題1・2・3解決方法

これ自体は簡単です。
ビューポートタグを全てのページに入れるだけです。
ビューポートを設定すると画面スマホ等で見た時にその適切な範囲で表示されます。
するとフォントサイズが12pxでも十分に見える文字サイズですし、リンクも近すぎるっていう状態でもなくなります。

「ただしユーザーに拡大縮小させてはいけない」ので第四の問題となります。

問題4の解決方法

モバイルユーザビリティを凄く簡単に言えば「拡大縮小しないで見えるサイトにして」って事です。
さらに言えば幅400前後のサイトにしてって事です。

ビューポートタグを全てのページに入れて拡大縮小しないで見ようとすればコンテンツの幅がはみ出てますよね。それがダメなのです。

普通の幅固定のPCサイトであれば1000~2000pxとかの幅があると思いますがスマホでの場合はスマホのスタイルに書き換える。
具体的には

@media screen and (min-width:481px) {
.a{PC用すたいる}
}
@media screen and (max-width:480px) {
.b{スマホ用すたいる}
}

こんな感じです。
「@media screen and (max-width:480px) 」は最後に読み込ませます。
共通のスタイルを上書きする事が出来ます。
ただし空定義で設定を無効は出来ません。あくまでも上書きです。
もしもPCの時のみの設定がある場合は「@media screen and (min-width:481px) 」に居れればOKです。

スタイルシートは後に来るのが上書きです。
読み込みも後にする必要があります。