
久しぶりにWeb制作に関しての記事、HTMLとCSSの書き方について記述していきたいと思います。
2026年現在、私が制作で使うベースにしているものですが、正直あまり参考にならないとは思いますので、「こういう考え方、やり方でもやっていけるんだな」と1つの考え方として誰かの参考になったら嬉しいです。
サンプルがあった方がわかりやすいと思いますので、サンプルサイトを使いながら話したいと思います。
1.サンプルコード
index.php
コードを見るHTML
Copied
COPY
<?php
$pageTtl = "HOME";
$description = "このページの説明";
$pageClass = "p-home";
$pageCssName = "p-home";
$curPath = './';
?>
<?php include($curPath . '_inc/head.php'); ?>
<?php include($curPath . '_inc/header.php'); ?>
<main>
<div class="p-h_mainVisual">
<div class="logoArea">
<h2 class="logo"><img src="./_lib/images/home/mv-logo-wh.png" width="196" height="66" alt="Sample"></h2>
<p class="">Everything is practice.</p>
</div>
</div>
<article class="l-mainContents">
<section class="l-sec p-h_about">
<div class="l-w980">
<h2>You’ll never find a rainbow<br>if you’re looking down.</h2>
<p>The first and best victory is to conquer self.<br>Whatever is begun in anger ends in shame.<br>Kites rise highest against the wind – not with it.</p>
<div class="imgWrap">
<img src="./_lib/images/home/ab-img1.png" width="350" height="350" alt="黒猫">
</div>
</div>
</section>
<!-- /p-h_about -->
<section class="l-sec p-h_project">
<h2 class="sec-ttl"><span>PROJECT</span></h2>
<div class="l-w980">
<div class="boxWrap">
<div class="box">
<div class="imgWrap">
<img src="./_lib/images/home/pj-img1.jpg" width="300" height="200" alt="猫">
</div>
<div class="box_body">
<h3>PROJECT 1</h3>
<p class="mainTxt">Far far away, behind the word mountains, far from the countries</p>
<p class="subTxt">Vokalia and Consonantia.</p>
<div class="btnWrap">
<a href="javascript:void(0)" class="btn-more">more</a>
</div>
</div>
</div>
<!-- /box -->
<div class="box">
<div class="imgWrap">
<img src="./_lib/images/home/pj-img2.jpg" width="300" height="200" alt="猫">
</div>
<div class="box_body">
<h3>PROJECT 2</h3>
<p class="mainTxt">Far far away, behind the word mountains, far from the countries</p>
<p class="subTxt">Vokalia and Consonantia.</p>
<div class="btnWrap">
<a href="javascript:void(0)" class="btn-more">more</a>
</div>
</div>
</div>
<!-- /box -->
<div class="box">
<div class="imgWrap">
<img src="./_lib/images/home/pj-img3.jpg" width="300" height="200" alt="猫">
</div>
<div class="box_body">
<h3>PROJECT 3</h3>
<p class="mainTxt">Far far away, behind the word mountains, far from the countries</p>
<p class="subTxt">Vokalia and Consonantia.</p>
<div class="btnWrap">
<a href="javascript:void(0)" class="btn-more">more</a>
</div>
</div>
</div>
<!-- /box -->
</div>
</div>
</section>
<!-- /p-h_project -->
<section class="l-sec p-h_news">
<h2 class="sec-ttl"><span>NEWS</span></h2>
<div class="l-w980">
<div class="listWrap">
<ul class="list">
<li class="list_item">
<time class="date">2026.02.16</time>
<span class="category">info</span>
<a href="javascript:void(0)" class="title">Lorem ipsum dolor sit amet, consectetuer</a>
</li>
<li class="list_item">
<time class="date">2026.02.16</time>
<span class="category">info</span>
<a href="javascript:void(0)" class="title">Lorem ipsum dolor sit amet, consectetuer</a>
</li>
<li class="list_item">
<time class="date">2026.02.16</time>
<span class="category">info</span>
<a href="javascript:void(0)" class="title">Lorem ipsum dolor sit amet, consectetuer</a>
</li>
</ul>
</div>
</div>
</section>
<!-- /p-h_news -->
</article>
</main>
<?php include($curPath . '_inc/footer.php'); ?>
head.php
コードを見るHTML
Copied
COPY
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title><?php echo $pageTtl; ?> | サンプルページ</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="<?php echo $description; ?>" >
<link rel="stylesheet" href="<?php echo $curPath ?>_lib/css/common.css?<?php echo date('YmdHis'); ?>">
<link rel="stylesheet" href="<?php echo $curPath ?>_lib/css/<?php echo $pageCssName ?>.css?<?php echo date('YmdHis'); ?>">
</head>
<body class="<?php echo $pageClass; ?>">
<div class="l-wrapper">
header.php
コードを見るHTML
Copied
COPY
<header class="l-gHeader">
<div class="inner">
<h1><img src="<?php echo $curPath ?>_lib/images/common/hdr-logo.png" width="120" height="40" alt="Sample"></h1>
<nav class="l-gNavi">
<ul>
<li><a href="./">HOME</a></li>
<li><a href="javascript:void(0)">ABOUT</a></li>
<li><a href="javascript:void(0)">PROJECT</a></li>
<li><a href="javascript:void(0)">NEWS</a></li>
</ul>
</nav>
</div>
</header>
footer.php
コードを見るHTML
Copied
COPY
<a href="#" id="js-btn-pageTop" class="btn-pageTop"></a>
<footer class="l-gFooter">
<div class="inner">
<ul>
<li><a href="javascript:void(0)">FAQ</a></li>
<li><a href="javascript:void(0)">CONTACT</a></li>
</ul>
<p class="copyRight">© <?php echo date('Y'); ?> Sample All rights reserved.</p>
</div>
</footer>
</div>
<!--/wrapper-->
<script src="<?php echo $curPath ?>_lib/js/script.js?<?php echo date('YmdHis'); ?>"></script>
</body>
</html>
common.css
コードを見るHTML
Copied
COPY
@charset "utf-8";
@layer common, page, utilities;
@layer common {
/*--------------------------------------------------------------------------
□ Reset & 全体の設定
---------------------------------------------------------------------------*/
*,
*::before,
*::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
font-size: 62.5%;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
text-size-adjust: 100%;
scroll-behavior: smooth;
@media (width <= 768px) {
font-size: calc(100vw / 37.5);
}
}
body {
color: #333;
font-size: 1.6rem;
font-family: Arial, Helvetica, "Hiragino Kaku Gothic ProN", "Hiragino Sans", "Yu Gothic", "Meiryo", sans-serif;
line-height: 1.75;
margin-inline: auto;
min-width: 100rem;
min-block-size: 100dvb;
@media (width <= 768px) {
font-size: 1.5rem;
min-width: auto;
}
}
:where(h1, h2, h3, h4, h5, h6) {
font:inherit;
text-wrap: balance;
overflow-wrap: break-word;
}
:where(p){
text-wrap: pretty;
overflow-wrap: break-word;
}
:where(ol, ul) {
list-style: none;
}
:where(picture, video, canvas, svg){
display: block;
max-width: 100%;
}
:where(img){
height: auto;
max-width: 100%;
vertical-align: bottom;
}
:where(table) {
border-collapse:collapse;
border-spacing: 0;
}
:where(input, button, textarea, select, address) {
font: inherit;
}
:where(button,input[type="submit"],input[type="button"]){
border: none;
border-radius: 0;
cursor: pointer;
outline: none;
-webkit-appearance: none;
appearance: none;
}
:where(textarea) {
white-space: revert;
resize: vertical;
resize: block;
}
:where(iframe){
width: 100%;
}
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
main {
display: block;
}
}
/*リンク(全般)設定
---------------------------------------------------------------------------*/
a {
text-decoration:none;
outline: none;
color:#08C;
@media (width >= 769px) {
-webkit-transition: 0.3s ease-in-out;
transition: 0.3s ease-in-out;
}
}
@media (any-hover: hover) {
a:hover {
opacity:0.85;
text-decoration: none;
}
}
/*フォント設定
---------------------------------------------------------------------------*/
.mincho{
font-family: Georgia,"Hiragino Mincho ProN", "Hiragino Sans NW","Yu Mincho", "YuMincho","MS PMincho",serif;
}
/*カラー設定
---------------------------------------------------------------------------*/
:root {
--primary:#121212 ;
--secondary: ;
--text-primary: ;
--text-secondary: ;
--bg-color: #F6F6F6;
--radius-lg: 2.4rem;
--radius-md: 1.6rem;
--radius-sm: .8rem;
--shadow-subtle: 0 1rem 3rem rgba(74, 78, 105, 0.05);
}
/*--------------------------------------------------------------------------
□ Component
---------------------------------------------------------------------------*/
/*見出し設定
---------------------------------------------------------------------------*/
.sec-ttl{
font-size: 2.8rem;
font-weight: 700;
margin-bottom: 4rem;
text-align: center;
@media (width <= 768px) {
font-size: 2.2rem;
margin-bottom: 3rem;
}
}
/*テーブル設定
---------------------------------------------------------------------------*/
/*フォーム設定
---------------------------------------------------------------------------*/
/*ボタン
---------------------------------------------------------------------------*/
.btn-more {
background: var(--primary);
color: #fff;
display: inline-block;
line-height: 1;
padding: 1.4rem 6.4rem;
position: relative;
}
.btn-more::before {
content: "";
width: .8rem;
height: .8rem;
position: absolute;
right: 2rem;
top: 50%;
transform: translateY(-50%) rotate(45deg);
border-top: .2rem solid #fff;
border-right: .2rem solid #fff;
}
.btn-pageTop{
right: 2rem;
bottom: 2.7rem;
position: fixed;
width: 5rem;
height: 5rem;
z-index: 99;
display: block;
text-align: center;
line-height: 5rem;
color: #66a6ff;
border: 1px solid #66a6ff;
background-color: rgba(102, 166, 255,0.2);
opacity: 0;
pointer-events: none;
&&::before {
content: "";
width: 1rem;
height: 1rem;
position: absolute;
right: 2rem;
top: 50%;
transform: translateY(-50%) rotate(-45deg);
border-top: .2rem solid #66a6ff;
border-right: .2rem solid #66a6ff;
}
&&.is-show {
opacity: 1;
pointer-events: auto;
}
}
@media (any-hover: hover) {
.btn-pageTop:hover{
color: #59c3e6;
border: 1px solid #59c3e6;
background-color: rgba(89, 195, 230,0.2);
}
}
/*--------------------------------------------------------------------------
□ Layout
---------------------------------------------------------------------------*/
.l-w980{
width: 98rem;
margin-inline: auto;
@media (width <= 768px) {
width: 100%;
padding: 0 1.4rem;
}
}
.l-sec{
padding: 8rem 0;
@media (width <= 768px) {
padding: 4rem 0;
}
}
/*Header
---------------------------------------------------------------------------*/
.l-gHeader{
position: absolute;
left: 0;
top: 0;
width: 100%;
z-index: 99;
.inner{
display: flex;
flex-wrap: wrap;
align-items:center;
width: 100%;
height: 8rem;
padding: 0 4rem;
@media (width <= 768px) {
height: 6rem;
padding: 0 2rem;
}
h1{
img{
@media (width <= 768px) {
width: 10rem;
}
}
}
}
}
.l-gNavi{
margin-left: auto;
ul{
display: flex;
flex-wrap: wrap;
li{
margin-left: 2em;
@media (width <= 768px) {
margin-left: 1rem;
}
a{
color: #FFF;
@media (width <= 768px) {
font-size: 1.2rem;
}
}
}
}
}
/*FOOTER
---------------------------------------------------------------------------*/
.l-gFooter{
ul{
background-color: var(--bg-color);
display: flex;
align-items: center;
justify-content: center;
li{
margin: 0 1rem;
line-height: 7rem;
a{
color: var(--primary);
font-size: 1.4rem;
}
}
}
}
.copyRight {
line-height: 6rem;
height: 6rem;
font-size: 1.2rem;
text-align: center;
border-top: 1px solid #ddd;
}
}
/*@common*/
@layer utilities{
.clearfix::after {content: "";display: block;clear: both;}
.fw700{font-weight: 700;}
.ffs-palt{font-feature-settings: "palt";}
.textNone {text-indent: 100%;white-space: nowrap;overflow: hidden;line-height: 0;}
.floatL { float: left; }
.floatR { float: right; }
.alignL {text-align: left;}
.alignR {text-align: right;}
.alignCR {text-align: center;}
@media (769px <= width) {
.pc-none{display: none;}
.pc-mt_0{margin-top: 0;}
.pc-mt_1{margin-top: 1rem;}
.pc-mt_1_5{margin-top: 1.5rem;}
.pc-mt_2{margin-top: 2rem;}
.pc-mt_2_5{margin-top: 2.5rem;}
.pc-mt_3{margin-top: 3rem;}
.pc-mt_4{margin-top: 4rem;}
.pc-mt_5{margin-top: 5rem;}
.pc-mt_6{margin-top: 6rem;}
}
@media (width <= 768px) {
.sp-none{display: none;}
.sp-alignL {text-align: left;}
.sp-alignR {text-align: right;}
.sp-alignCR {text-align: center;}
.sp-mt_0{margin-top: 0;}
.sp-mt_1{margin-top: 1rem;}
.sp-mt_1_5{margin-top: 1.5rem;}
.sp-mt_2{margin-top: 2rem;}
.sp-mt_2_5{margin-top: 2.5rem;}
.sp-mt_3{margin-top: 3rem;}
.sp-mt_4{margin-top: 4rem;}
.sp-mt_5{margin-top: 5rem;}
.sp-mt_6{margin-top: 6rem;}
}
}
/*@utilities*/
p-home.css
コードを見るHTML
Copied
COPY
@layer common, page, utilities;
@layer page {
/*--------------------------------------------------------------------------
□TOPページ home
---------------------------------------------------------------------------*/
/*p-h_mainVisual
--------------------------------------*/
.p-h_mainVisual{
background: url(../images/home/mv.jpg) no-repeat 50% 50% / cover;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100dvh;
.logoArea{
.logo{
img{
@media (width <= 768px) {
width: 18rem;
}
}
}
p{
color: #FFF;
font-weight: 700;
text-shadow:
0 0 10px #333,
0 0 10px #333,
0 0 10px #333;
}
}
}
/*Main
---------------------------------------------------------------------------*/
/*p-h_about
--------------------------------------*/
.p-h_about{
text-align: center;
h2{
font-size: 3.6rem;
font-weight: 700;
line-height: 1.5;
@media (width <= 768px) {
font-size: 2.2rem;
}
}
p{
line-height: 2.4;
margin-top: 2rem;
@media (width <= 768px) {
font-size: 1.4rem;
line-height: 2;
}
}
.imgWrap{
margin-top: 2rem;
img{
@media (width <= 768px) {
width: 15rem;
}
}
}
}
/*p-h_project
--------------------------------------*/
.p-h_project{
background-color: var(--bg-color);
.boxWrap{
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 2rem;
.box {
background: #FFF;
box-shadow: var(--shadow-subtle);
width: 30rem;
@media (width <= 768px) {
width: 100%;
}
img{
width: 100%;
height: 20rem;
object-fit: cover;
}
.box_body{
padding: 2rem;
h3{
font-size: 2rem;
font-weight: 700;
@media (width <= 768px) {
font-size: 1.8rem;
}
}
p{
line-break: anywhere;
&&.subTxt{
font-size: 1.4rem;
}
}
.btnWrap{
margin-top: 2rem;
text-align: center;
}
}
}
}
}
/*p-h_news
--------------------------------------*/
.p-h_news{
.list{
margin-inline: auto;
width: 60rem;
@media (width <= 768px) {
width: 100%;
}
}
.list_item{
display: flex;
flex-wrap: wrap;
align-items: flex-start;
padding: 1.2rem 0;
@media (width <= 768px) {
align-items: center;
}
.date{
width: 11rem;
}
.category{
background-color: var(--primary);
font-size: 1.2rem;
text-align: center;
color: #fff;
border-radius: 3rem;
margin-right: 2rem;
width: 9rem;
height: 3rem;
line-height: 3rem;
padding: 0 2rem;
display: inline-block;
}
.title{
color: var(--primary);
width: calc(100% - 22rem);
@media (width <= 768px) {
width: 100%;
margin-top: 1rem;
}
@media (any-hover: hover) {
&:hover{
text-decoration: underline;
}
}
}
}
}
}
/*@page*/
2.解説
※ページTOPへボタンのフェードイン・アウトにjavascriptを使用していたりしますので、細かい部分も気になる方は開発ツールでご確認ください。
まず前提として、私がホームページ(以下、HP)制作で請け負う仕事は10ページ前後のサイトが多く、私以外の手が入らない案件が主です。
また、クライアントからの指定がない限り、headerやfooterなど使い回す部分を扱いやすいように、PHPファイルで作成します。
head内はサンプルサイトなのでシンプルにしてありますが、実際にはファビコンであったりOGPなどの設定は入れます。その辺は、あまり変わらないと思います。
CSSの読み込みに関しては、以下のように記述してあります。
<link rel="stylesheet" href="<?php echo $curPath ?>_lib/css/common.css?<?php echo date('YmdHis'); ?>">
<link rel="stylesheet" href="<?php echo $curPath ?>_lib/css/<?php echo $pageCssName ?>.css?<?php echo date('YmdHis'); ?>">
まず全てのページに影響するCSSファイルをcommon.cssとして読み込み、次に各ページ毎に読み込むCSSを変えれるように変数を利用した書き方をしています。
index.phpの冒頭に記述してありますが、
$pageCssName = “p-home”;
のように指定すれば、各ページに対応したCSSファイルを読み込んでくれます。
会社概要ページであれば、
$pageCssName = “p-company”;として、
p-company.cssファイルを作成する形です。
これによりファイル管理が大変スッキリし、見やすくもなります。
後でCSSファイル内のことを話す際にも触れますが、私はSCSSは利用しません。
理由を端的に言うとPHPとネイティブのCSSで同じようなことが既に出来るからです。
そもそも小中規模のサイト制作ではSCSSは不要であると考えていますし、私の仕事の取り方による部分が大きいとは思うのですが、実際の制作の場でSCSSを使ったサイトに触れる機会はほとんどありません。
SCSSを利用しているサイトでも制作会社はSCSSを利用して制作したけど、社内で更新する人はCSSを直接更新していてSCSSを使えなくなっていたりと、作ってもらった会社と繋がりが消えている会社は割と多い印象があります。
CSS設計
コーダーにとってCSS設計は多くのひとがぶち当たる1つの壁だと思います。
BEMだとかFLOCSS、Atomic CSSだとか、多くのひとが取り入れているのではないでしょうか。
私自身も影響は受けていますが、サンプルコードに書いたような感じで今は落ち着いています。
全部を混ぜたような感じですね。
下記のようなルールを決めています。
□ サイトの大きな枠組み。使い回す外枠には頭にlayoutのlを付けています。
l-gHeader、l-mainContents、l-secなど
□ そのページ固有のコンテンツには頭にpageのpを付けています。
p-home、p-about、p-company、など
□ セクションの親となる要素のclass名は基本略さない
※ 一般的に略してわかる単語は略してOK
p-h_mainVisual、p-h_about、p-h_projectなど
□ 単語の連結にはキャメル方式
boxWrap、logoArea、imgWrapなど
単語連結にするかどうかは high school → highSchool のように繋がって意味を成すのはもちろん、
box wrap → boxWrap のように子要素になる訳ではないひとまとまりのブロック、要素はキャメル連結する。
□ 子要素は基本ブロック名、要素名のみ
logo、box、mainTxt、subTxtなど
□ 子要素に親の名前を継いでclass名を付ける場合、その親のclass名は3文字以下の短縮にする
※基本的には子要素1つ1つにBEMのように名付けはしないが、する場合は下記のようにする。
何の短縮は親を見ればわかるようにする。
p-home→p-h_mainVisual→p-h_mv_logoArea
p-home→p-h_project→p-h_pj_boxWrap
□ 固有のページ名、モジュール名(部品)など特定のまとまり分けするのはハイフン
※ 接頭辞は3文字以内
l-、p-、sec-、is-、js-、pc-、sp-など
■ テーブル
親:tableTypeA
子:tbA-
■ フォーム
親:formTypeA
子:fmA-
□ ブロック名や要素名の連結はアンダーバー
box_body、list_itemなど
これらを元に構築していきます。
子要素のclass名をboxとかtxtみたいな名前にしてしまうのは、一般的には多分よくないです。
よくない理由としては、汎用的な命名なので他の場所で重複して利用してしまいCSSの上書きによるレイアウト崩れが起きる可能性が高かったり、CSSの記述が詳細度が高くなってしまう。といったことが挙がると思います。
そういったことを回避するためにも、BEMのように長いclass名を付けたりすることになるわけですが、昨今のモダンブラウザにおけるCSSの機能は目覚ましく進化しており、小中規模のホームページであれば気にしなくていいと私は考えます。
例えば、PROJECT部分のCSSですが、
/*p-h_project
--------------------------------------*/
.p-h_project{
background-color: var(--bg-color);
.boxWrap{
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 2rem;
.box {
background: #FFF;
box-shadow: var(--shadow-subtle);
width: 30rem;
@media (width <= 768px) {
width: 100%;
}
img{
width: 100%;
height: 20rem;
object-fit: cover;
}
.box_body{
padding: 2rem;
h3{
font-size: 2rem;
font-weight: 700;
@media (width <= 768px) {
font-size: 1.8rem;
}
}
p{
line-break: anywhere;
&&.subTxt{
font-size: 1.4rem;
}
}
.btnWrap{
margin-top: 2rem;
text-align: center;
}
}
}
}
}
ネイティブのCSSでもネストして記述出来るので、.p-h_projectのブロック1つのまとまりとしてCSSを管理出来ます。
親クラスの中でネストされている限り、例えば他の場所にある .box と混ざる心配は(詳細度のルール上)ほぼないですし、小中規模サイトならこれで十分安全です。
大規模開発なら「壊れにくさ(堅牢性)」が正義であると思いますが、「構造がシンプルなら、コードもシンプルに保つ」といった適正な設計こそが美しいと考えると、小中規模サイトではこのような形がよいのではないかと思っています。
詳細度が高くなるとHTMLの構造が変わった時など対応が大変という指摘もあるかと思いますが、経験上大規模なサイトでもなければ大変ではないです。
そもそも大変なくらい構造を変える時は、サイトのリニューアルに話はなっていくと思います。
詳細度ついでにカスケードレイヤーについて少し触れたいと思います。
common.cssと各ページのcssにはカスケードレイヤーを利用し、階層分けしてあります。
ファイル上部に、@layer common, page, utilities;といった記述があると思います。
これがカスケードレイヤーの指定になります。
理由はimportant!をあまり使わないようにするためです。
主に、utilitiesの内容がimportant使いがちになるので、優先度を一番高くしてあります。
※@layer common, page, utilities;は右から優先度が高くなります。
3.まとめ
大体最近はこんな感じです。
ネイティブのCSSで変数やネストなどが使えるようになったことが今の制作方法に大きく影響を与えていますが、基本的に自分しか制作に関わらないような案件が多いのであれば、わざわざ長いclass名を付けたり流行りのCSSフレームワーク、SCSSなどは使う必要はなく、構造もコードもシンプルにしていくのが一番だと思います。
このように書きましたが、昨今はAIの進歩が目覚ましく、HTMLの構成やCSSの命名もAIに提案、作成せれば一瞬で出来上がるので、こういったことに考えを巡らせることは、もはや不要なことなのかもしれません。