0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Java】HTML×CSSをBEM記法で整えてみる

Last updated at Posted at 2026-01-12

最近では、ReactやVueといったフレームワークで開発することが主流ですが、原点に返って、BEM記法でHTMLとCSSのテンプレートを作ってみましょう。

BEM記法とは?
BEM記法は世界的に広く普及しているCSS設計手法です。
似たものとしてFLOCSSがありますが日本の開発者によって考案されたCSS設計手法です。

BEM記法 (Block Element Modifier)
BEMは、元々ロシアのYandex社で開発された手法で、その高い再利用性、保守性、予測容易性から、世界中の多くの開発チームや企業で採用されています。
特定のフレームワークに依存しない汎用的な命名規則であり、Angularのような様々なフロントエンド環境でも使用されています。公式ドキュメントは英語でも提供されており、国際的な認知度は非常に高いです。

BEM: 世界的に広く普及しており、多くの国のプロジェクトで標準的に使われています。

FLOCSS (Flexible Layout Object Component Separation)
FLOCSSは、OOCSSやSMACSS、BEM、SuitCSSといった複数の既存のCSS設計思想のコンセプトを取り入れて、日本の開発者によって考案された比較的新しい日本独自のCSS構成案です。
そのため、日本のWeb制作現場では広く利用されていますが、海外のコミュニティやプロジェクトで採用されているケースは稀です。海外のCSS設計に関する議論やトレンドの中では、BEMやUtility First (Tailwind CSSなど) の話題が中心で、FLOCSSの名前が出ることはほとんどありません。
FLOCSS: 日本国内向けに開発された独自の設計思想であり、海外でのシェアはほぼありません。

今回は、BEM記法を使った設計手法でフォーム画面を作ってみます。

image.png

BEM設計方針

Block

Block
login

Element

Element
login__title
login__form
login__group
login__label
login__input
login__select
login__radio
login__action
login__button

Modifier

Block
login__button--primary
login__button--secondary

実装

/JakartaEERestful/src/main/webapp/users/login.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>管理者ログイン</title>
<!--個別ファイル-->
<link rel="stylesheet" href="../staticFiles/css/users/login.css" type="text/css"/>
<script type="text/javascript" src="../staticFiles/js/users/login.js"></script>
</head>
<body>
	<div class="login">
		<h1 class="login__title">管理者ログイン</h1>
		<form class="login__form" method="post">
			<!-- メールアドレス -->
			<div class="login__group">
				<label class="login__label" for="email">メールアドレス</label>
				<input
					class="login__input"
					type="email"
					id="email"
					name="email"
					required
				/>
			</div>
			<!-- パスワード -->
			<div class="login__group">
				<label class="login__label" for="password">パスワード</label>
				<input
					class="login__input"
					type="password"
					id="password"
					name="password"
					required
				/>
			</div>
			<!-- 性別 -->
			<div class="login__group">
				<span class="login__label">性別</span>
				<div class="login__radio">
					<label>
						<input type="radio" name="gender" value="M" required/>男性
					</label>
					<label>
						<input type="radio" name="gender" value="F" required/>女
					</label>
					<label>
						<input type="radio" name="gender" value="O" required/>その他
					</label>
				</div>
			</div>
			<!-- オフィス -->
			<div class="login__group">
				<label class="login__label">オフィス</label>
				<select
					class="login__select"
					id="office"
					name="office"
					required
				>
					<option value="">選択してください</option>
					<option value="東京都">東京都</option>
					<option value="神奈川県">神奈川県</option>
					<option value="埼玉県">埼玉県</option>
					<option value="千葉県">千葉県</option>
				</select>
			</div>
			<!-- ボタン -->
			<div class="login__actions">
				<button
					class="login__button login__button--primary"
					type="button"
				>
					ログイン
				</button>
				<button
					class="login__button login__button--secondary"
					type="button"
					onclick="clickBackToTopPage()"
				>
					戻る
				</button>
			</div>
		</form>
	</div>
</body>
</html>
/JakartaEERestful/src/main/webapp/staticFiles/css/users/login.css
@charset "UTF-8";
/* Block */
.login {
    max-width: 420px;
    margin: 60px auto;
    padding: 32px;
    border: 1px solid #ddd;
    border-radius: 8px;
    font-family: sans-serif;
}

/* Elements */
.login__title {
    text-align: center;
    margin-bottom: 24px;
}

.login__group {
    margin-bottom: 16px;
}

.login__label {
    display: block;
    margin-bottom: 6px;
    font-weight: bold;
}

.login__input,
.login__select {
    width: 100%;
    padding: 8px;
    box-sizing: border-box;
}

.login__radio label {
    margin-right: 12px;
}

.login__actions {
    text-align: center;
    margin-top: 24px;
}

/* Button */
.login__button {
    padding: 10px 24px;
    border: none;
    cursor: pointer;
}

.login__button--primary {
    background-color: #0d6efd;
    color: #fff;
    border-radius: 4px;
}

.login__button--secondary{
	background-color: grey;
	color: #fff;
	border-radius: 4px;
}

サイト

Maven Repositoryについて

Maven Repository 「Thymeleaf」

【MySQL(MariaDB)】実運用を想定したECサイト用のER図設計

Stripe を深ぼる / 返金処理

Webデザインについて

【レイアウト構成】初級編:コーポレートサイト/1カラム

開発に関わるテストをまとめてみた。

JakartaEE×Thymeleafについて

Jakarta EEプロジェクトにThymeleafを導入するには、主に依存関係の追加テンプレートエンジンの設定が必要です。Spring Bootのように自動設定されるわけではないため、手動での設定が必要となります。

導入ステップ
1. 必要な依存関係をプロジェクトに追加する
Maven ( pom.xml ) を使用する場合、以下の依存関係を追加します。
これにより、Thymeleafライブラリがプロジェクトに組み込まれます。

pom.xml
<dependency>
    <groupId>org.thymeleaf</groupId>
    <artifactId>thymeleaf</artifactId>
    <version>3.1.2.RELEASE</version> <!-- 最新の安定バージョンに適宜変更してください -->
</dependency>
<!-- Webコンテナによっては、サーブレットAPIの依存関係も必要になる場合があります -->
<dependency>
    <groupId>jakarta.servlet</groupId>
    <artifactId>jakarta.servlet-api</artifactId>
    <version>6.0.0</version> <!-- 使用しているJakarta EEのバージョンに合わせる -->
    <scope>provided</scope>
</dependency>

2. Thymeleafテンプレートエンジンを設定する(Javaコード)
Thymeleafはサーバーサイドテンプレートエンジンであるため、Javaコード内でテンプレートエンジンとテンプレートリゾルバーを設定する必要があります。通常、これはサーブレットやフィルター、あるいはJakarta EEのCDI (Contexts and Dependency Injection) マネージドビーンなどで行います。
以下は、基本的な設定の例です。

Sample.java
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;

// ...

public void setupThymeleaf(ServletContext servletContext) {
    ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext);
    templateResolver.setPrefix("/WEB-INF/templates/"); // テンプレートファイルの場所
    templateResolver.setSuffix(".html"); // テンプレートの拡張子
    templateResolver.setTemplateMode(TemplateMode.HTML); // テンプレートモード (HTML5を推奨)
    templateResolver.setCacheable(false); // 開発中はキャッシュを無効にする

    TemplateEngine templateEngine = new TemplateEngine();
    templateEngine.setTemplateResolver(templateResolver);

    // この templateEngine インスタンスを使用してテンプレートを処理します
}

3. テンプレートを処理するサーブレットを作成する
Jakarta EEアプリケーション内でThymeleafを使用して動的なコンテンツを生成するには、サーブレットを作成し、その中でテンプレートエンジンを呼び出します。

Sample-servlet.java
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.WebContext;
import org.thymeleaf.web.jakarta.JakartaServletWebApplication;
import java.io.IOException;

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    private TemplateEngine templateEngine;

    @Override
    public void init() throws ServletException {
        // Thymeleaf設定を初期化
        // 実際には、JakartaServletWebApplication を使用してコンテキストを取得するなどの設定が必要
        // ... (ステップ2の設定を応用して初期化)
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");

        // WebContextを作成し、リクエスト・レスポンス・サーブレットコンテキストをバインド
        final WebContext ctx = new WebContext(
            JakartaServletWebApplication.create(request, response, this.getServletContext()),
            request.getLocale());
        ctx.setVariable("message", "Jakarta EE と Thymeleaf の連携成功!");

        // テンプレートを描画
        templateEngine.process("hello", ctx, response.getWriter());
    }
}

4. テンプレートファイルを配置する
設定したプレフィックス(例: /WEB-INF/templates/)に基づき、HTMLファイルを配置します。ファイルにはThymeleafの属性を記述できます。
src/main/webapp/WEB-INF/templates/hello.html

src/main/webapp/WEB-INF/templates/hello.html
">
<head>
    <title>Thymeleaf in Jakarta EE</title>
</head>
<body>
    <p th:text="${message}">ここにメッセージが表示されます</p>
</body>
</html>

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?