`で囲う
```html
本文
```
#### 改善方法
```html
本文
```
HTML5からは「意味のあるタグ(セマンティックタグ)」が豊富に用意されており、Googleのクローラーやスクリーンリーダーもこれらを理解して処理します。構造的に正しいタグを使うことで、**検索エンジン対策やアクセシビリティの向上にもつながります。**
### NG3:インラインスタイルを多用する
```html
タイトル
```
#### 改善方法
```html
タイトル
```
```css
.main-title {
color: red;
}
```
インラインスタイルは「一度だけ」「急ぎで修正する」場合などに限って使うべきです。大量の要素にスタイルを適用する場合や、後からの調整が必要な場面では**スタイルの一元管理ができなくなり、大混乱の元**になります。クラス設計とCSSファイルをしっかり分ける習慣を持ちましょう。
### NG4:適当なクラス名(box1、testなど)
```html
内容
```
#### 改善方法
```html
内容
```
クラス名は**コードを読む人へのメッセージ**でもあります。命名に意味があればあるほど、構造が直感的に理解できるようになります。BEM記法(例:`.product__title--highlight`)なども習得すると、大規模サイトにも対応しやすくなります。
上記のNG行動は特にネットのコードをコピペしたときにしがちなので注意しましょう。
### NG5:画像にサイズ指定がない
```html

```
#### 改善方法
```html

```
画像のサイズを指定しないと、ページの読み込み中に**突然コンテンツがずれて表示される**ことがあります。これが「CLS(レイアウトのズレ)」というUX悪化の一因です。**あらかじめサイズを指定することで、ページ全体が安定して表示されます。**
### NG6:`!important`を多用する
```css
.button {
color: white !important;
}
```
#### 改善方法
```css
.btn-primary {
color: white;
}
```
`!important`は最終手段です。あまりにも多用すると、**どのCSSが効いているのか分からなくなり、バグの温床**になります。どうしても必要な場面(例:サードパーティCSSの上書きなど)以外は使わないようにしましょう。
### NG7:背景画像に意味のある画像を使う
```css
.hero {
background-image: url("main.jpg");
}
```
#### 改善方法
```html

```
背景画像には`alt`が付けられないため、**意味のある画像や情報を含む画像には不向き**です。検索エンジンやスクリーンリーダーが画像の内容を理解できないため、重要な画像は`
![]()
`タグで扱いましょう。
### NG8:スタイルに`id`を使用している
```css
#header {
background-color: blue;
}
```
#### 改善方法
```css
.header {
background-color: blue;
}
```
`id`は1ページ内で唯一であるべきで、**JavaScriptやアンカーリンクのターゲット用に使用**するのが基本です。CSSはクラスベースで管理することで、**再利用性が高まり、スタイル競合のトラブルも避けやすくなります。**
## おわりに
プログラミングやマークアップの世界では、「とりあえず動けばOK」な時期も必要です。しかし、次のステップに進むには「**なぜその書き方をするのか**」「**なぜこれは避けるべきなのか**」という視点が欠かせません。
今回紹介したNG行動は、ほんの一部です。学習を続けるうちに「最初にこれを知っておきたかった!」と思うような知識がどんどん出てくるでしょう。
HTMLやCSSは、見た目を整えるだけのものではありません。**意味のあるタグ選び、構造的に正しいレイアウト、柔軟で保守しやすいスタイル**——それらを実現することで、プロフェッショナルなWeb制作ができるようになります。
この記事をきっかけに、「なぜその書き方なのか?」という意識を持ってコーディングに取り組んでみてください。小さな意識の積み重ねが、**確実なスキルアップ**につながります。
---
## 【Rails】コールバックの基本、応用、スキップを分かりやすく解説
- URL: https://blog.to-ko-s.com/articles/active-record-callback
- 著者: 塩見直樹
- 公開日: 2025-06-08
- タグ: Rails
> Railsのコールバック機能を基本から応用まで解説。before_save、after_createなどの使い方、条件付き実行、スキップ方法を初学者向けに紹介します。
## はじめに
こんにちは、株式会社TOKOSのナオキです!
皆さんはコードの可読性を気にした設計が出来ていますか?
「とりあえず思い通りに動けばいいや」と思いコントローラーにロジックを詰め込んだり、同じ処理をコントローラー毎に記述していませんか?
もしそのような方がいましたら今回解説するコールバックを使用し、メソッドの複雑度をさげ可読性が上がるよう設計していきましょう!
#### 対象読者
- Rails初学者の方
- コードの可読性を上げたいと思っている方
## コールバックとは
Railsガイドより
> オブジェクトのライフサイクルの特定の瞬間に呼び出されるメソッドのことです。
> コールバックを使えば、Active Recordオブジェクトがデータベースで初期化・作成・保存・更新・削除・バリデーション・読み込みのたびに実行されるコードを記述できます。
詳細に知りたい方は以下を参照してください!
よく使用されるコールバックには以下のようなものがあります。
| コールバックの種類 | 説明 |
| ------------------ | ---------------------------- |
| `before_save` | レコードが保存される前に実行 |
| `after_save` | レコードが保存された後に実行 |
| `before_create` | レコードが作成される前に実行 |
| `after_create` | レコードが作成された後に実行 |
| `before_destroy` | レコードが削除される前に実行 |
| `after_destroy` | レコードが削除された後に実行 |
## 基本的な使用方法
コールバックを使用する際は、モデルクラス内で上記で紹介したようなコールバックを登録し、実行させたいメソッドを受け取ります。
以下のサンプルコードは、保存前に名前の余分な空白をなくす処理です。
保存時にデータを一貫した形式にしたい場合、このように記述する方法もあります。
```ruby title="user.rb" showLineNumbers
class User < ApplicationRecord
before_save :normalize_name
private
def normalize_name
self.name = name.strip
end
end
```
このようにコールバックを登録することで、`User`のレコードが保存されるたびに`normalize_name`メソッドが実行されます。
`User`のレコードを保存するという処理を複数箇所で行っていた場合、本来であればその使用箇所全てに同じ記述をしなくてはいけません。
しかし、コールバックを登録しておけば他の箇所でその処理の記述をしなくても済みます。
それによりメソッドの記述量が減り、可読性をあげることができるのです!
コールバックの登録ではメソッド以外にも以下のようにブロックを受け取ることができます。
コールバックしたいロジックが短い時などはこちらを使用してみてもいいかもしれません。
```ruby title="user.rb" showLineNumbers
class User < ApplicationRecord
before_save do
self.name = name.strip
end
end
```
例としてサンプルコードをもう1つあげます。
以下はユーザーを作成した後にそのユーザーに対してメールを送る処理です。
```ruby title="user.rb" showLineNumbers
class User < ApplicationRecord
after_create :send_email
private
def send_email
UserMailer.welcome_email(self).deliver_now
end
end
```
基本的にはこのような感じで使用していきます!
## コールバックの応用
特定の条件下でのみコールバックを実行することも可能です。
以下は`if`を使用しユーザー作成後、`email`が存在する場合にのみメール送信をします。
`if`の逆である`unless`を使用することも可能です!
```ruby title="user.rb" showLineNumbers
class User < ApplicationRecord
after_create :send_email, if: -> { email.present? }
private
def send_email
UserMailer.welcome_email(self).deliver_now
end
end
```
また、以下のように`if, unless`を併用してコールバック登録をすることも出来ます。
```ruby title="user.rb" showLineNumbers
class User < ApplicationRecord
after_create :send_email, if: -> { email.present? }, unless: -> { status == 'guest' }
private
def send_email
UserMailer.welcome_email(self).deliver_now
end
end
```
上記はユーザー作成時、`email`が存在しなおかつ、`status`が`guest`でないユーザーに対してメール送信を行います。
## コールバックのスキップ
#### スキップされてしまう場合
以下のメソッドを使用するとコールバックはスキップされます。
これはバリデーションも同様です!
- `delete`
- `delete_all`
- `update_column`
- `update_all`
- `upsert`
スキップされるメソッドがあることを知らないと、なぜコールバックが実行されないのかで詰まってしまう可能性があります。
なので、コールバックがうまく実行されない場合は使用しているメソッドがスキップされるメソッドでないかを確認しましょう!
上記以外にもスキップされるメソッドがあるので詳しく知りたい方は、記事の上部に貼ってあるRailsガイドを参照してください。
#### あえてスキップしたい場合
通常はコールバックを行いたいが、例外的にスキップさせたい場合もあるかと思います。
そのような場合には`attr_accessor`を使用する方法があります!
以下のように`attr_accessor`で、コールバックをスキップするかどうかを管理するためのフラグを追加し、そのフラグの状態でコールバックの処理を実行するかどうか制御します。
```ruby title="user.rb" showLineNumbers
class User < ApplicationRecord
attr_accessor :skip_normalize_name # 追加
before_save :normalize_name, unless: -> { skip_normalize_name }
private
def normalize_name
self.name = name.strip
end
end
```
上記のように設定したらあとは以下のように使用するだけです!
**通常時の保存の場合:**
```ruby title="Ruby"
user = User.new(name: " 田中太郎")
user.save
puts user.name
# => "田中太郎"
```
**コールバックをスキップしたい場合:**
```ruby title="Ruby"
user = User.new(name: " 田中太郎")
user.skip_normalize_name = true
user.save
puts user.name
# => " 田中太郎"
```
このように`attr_accessor`を使用したらコールバックの制御を簡単に行えます。
スキップ処理が必要な場合のみ適切に使用することが大切になります!
## おわりに
今回はコールバックについて解説をしました!
コールバックは、モデルのライフサイクルに特定の処理を組み込む便利な機能ですが、使い方を誤るとコードが複雑化し、デバックが難しくなってしまいます。
本記事で紹介した、特定の条件下でのコールバック実行やスキップ機能をうまく活用し、必要な箇所にだけ適切にコールバックを取り入れることが大切になります!
ぜひ、この記事を参考に、プロジェクトでコールバックを効果的に活用してみてください!
---
## 要素のサイズでUIを切り替える!@containerでレスポンシブ対応
- URL: https://blog.to-ko-s.com/articles/css-container-query-responsive
- 著者: 成岡拓哉
- 公開日: 2025-06-01
- タグ: HTML, CSS
> CSSで要素サイズに応じたレスポンシブを実現したい方に向けて、@containerの基本構文と使い方をやさしく解説しました。ぜひ参考にしてください。
## はじめに
こんにちは。株式会社TOKOSのタクヤです。
いきなりですが、「CSSで画面サイズに合わせてデザインを変えたいのに、うまくいかない…」そんな風に思ったことはありませんか?
CSSでは画面の幅に合わせてデザインを変える方法が一般的かと思いますが、最近では要素の大きさに応じて見た目を変えられる、新しい書き方が登場しています。
この記事では、その新しい方法である`@container`について、はじめての方でも分かるように使い方をやさしく解説します。
### 対象読者
- CSSを学び始めた方
- メディアクエリでのレスポンシブに限界を感じている方
## @containerとは
`@container`は、**対象となる要素のサイズに合わせて見た目を変えられるCSSの仕組み**です。
これまでのCSSでは、画面の幅に合わせて文字の大きさや配置などを切り替えるのが一般的でした。しかし実際のWebサイトでは、画面全体ではなくある特定の要素のサイズに合わせて見た目を調整したい場面も多くあります。
たとえば、以下のような場面です。
- 狭いスペースでは、コンテンツを縦並びにして収めたい
- 広いスペースがあるときは、画像と文字を横に並べたい
こういったときに便利なのが`@container`です。
その**要素のサイズに合わせてCSSのスタイルを切り替えられる**ので、見た目の調整がもっと自由に、細かくできるようになります。
## 基本的な使い方
### 基本構文
`@container`を使うには、まず見た目を切り替える基準となる要素を設定する必要があります。
```css title="style.css" showLineNumbers
.container {
container-type: inline-size;
}
```
この指定によって、`.container`のサイズを基準に見た目を切り替えられるようになります。
```css title="style.css" showLineNumbers
@container (min-width: 600px) {
.text {
font-size: 20px;
}
}
```
このように記述すると、`.container`のサイズが600px以上のとき、`.text`の文字サイズが大きくなります。
### コード全文
```html title="index.html" showLineNumbers
この文字はコンテナのサイズによって大きさが変わります。
```
```css title="style.css" showLineNumbers
.container {
container-type: inline-size;
width: 100%;
max-width: 800px;
padding: 24px;
background: #f5f5f5;
margin: 0 auto;
}
.text {
font-size: 16px;
color: #333;
}
/* .container のサイズが600px以上になったらフォントサイズを大きくする */
@container (min-width: 600px) {
.text {
font-size: 20px;
}
}
```
## 応用編
通常の`@container`は、基本的な使い方で見たように、子要素の見た目を親コンテナ(`container-type`を指定した要素)のサイズに合わせて切り替えます。
しかし、`container-name`というプロパティを使えば、**どのコンテナを基準にしているかコード上で明確になり、可読性が向上します**。
以下の例では、親要素`.layout`に`container-name`を指定し、その中にある`.sidebar`と`.main-content`の見た目を、`.layout`のサイズに応じて切り替えています。
```html title="index.html" showLineNumbers
```
```css title="style.css" showLineNumbers
/* 親要素を名前付きコンテナとして定義 */
.layout {
container-name: layout;
container-type: inline-size;
}
/* 通常の見た目(狭いとき:縦並び) */
.sidebar {
background: #e0e0e0;
padding: 16px;
margin-bottom: 16px;
}
.main-content {
background: #f5f5f5;
padding: 16px;
}
/* layoutコンテナが広くなったときの見た目(横並び) */
@container layout (min-width: 600px) {
.layout-inner {
display: flex;
gap: 16px;
}
.sidebar {
width: 200px;
flex-shrink: 0;
margin-bottom: 0;
}
.main-content {
flex: 1;
}
}
```
### 解説
`.layout`に`container-name: layout;`を指定することで、この要素のサイズを`layout`という名前で参照できるようになります。
`@container layout ...`と書くことで、`.layout-inner`や`.sidebar`、`.main-content`といった子孫要素の見た目を、`.layout`コンテナのサイズに応じてまとめて切り替えられます。
なお、Container Queriesはコンテナの子孫要素にのみ適用されるため、`.layout`自身にはスタイルを適用できません。そのため、`.layout-inner`というラッパー要素を設けて、そこにFlexboxのスタイルを適用しています。
このように`container-name`を使えば、どのコンテナを基準にするかを明示的に指定できるため、複雑なレイアウトでも柔軟に対応できます。
## 終わりに
今回は要素のサイズに応じて見た目を切り替える方法である`@container`について解説しました。
これまでのように画面の幅に頼らず、特定の要素の大きさに合わせて文字サイズやレイアウトを変えられるため、より細かく、思い通りにデザインを調整できます。
ぜひこの記事を参考に使ってみてください。
---
## 【CSS】clip-path入門編、三角形も丸も自由自在に作成!
- URL: https://blog.to-ko-s.com/articles/css-clip-path
- 著者: 寺田拓真
- 公開日: 2025-05-24
- タグ: HTML, CSS
> CSSのclip-pathを使って三角形や円形を作る方法を初心者向けに解説。border三角形との違いや、hoverアニメーションの活用例も紹介します。
## はじめに
こんにちは!たくまです!
みなさんはCSSで三角形を作成する際、どのように作成しますか?
僕はWeb制作を始めたての頃、borderを使用して以下のように作成していました。
```css title="CSS" showLineNumbers
.triangle {
width: 0;
height: 0;
border-style: solid;
border-top: 50px solid transparent;
border-bottom: 50px solid transparent;
border-left: 60px solid #555555;
border-right: 0;
}
```
確かに上記で三角形を表現することは可能です。
ただ、borderを使用した際には以下のような問題点があります。
- **背景色や背景画像が使えない**(「面」がない)
- **構造が直感的ではない**(なぜかwidth/heightがゼロ)
- **サイズ調整が難しい**(borderの太さで調整する必要がある)
- **影や角丸など、CSSの他のプロパティと相性が悪い**
上記にあげたように、使い勝手が悪いです。
そこで、今回はclip-pathを使用した三角形などの作成方法を紹介します。
clip-pathであれば背景色や影をつけることができ、仕組みさえ覚えたらかなり応用が効きます。
## clip-path について
### clip-pathの基本
`clip-path`は、CSSで**要素の表示領域を指定の形で切り抜く**ためのプロパティです。
簡単に言えば、「ここだけ見せて、それ以外は隠す」マスクのようなものをイメージしてください。
たとえば、画像を円形に見せたいときは以下のように書きます:
```css title="CSS" showLineNumbers
.circle-image {
clip-path: circle(50%);
}
```
画像の角を丸くするのではなく、「切り抜いて」形を変えるのがポイントです。
`clip-path`は`border-radius`と違い、三角形や斜めの多角形、波形なども再現できる点が非常に強力です。
### clip-pathのメリットとは?
`clip-path`の大きなメリットは以下の通りです。
#### 1\. 背景色や背景画像を活かした形状が作れる
よくある「CSS三角形」は、冒頭で紹介したように以下のような`border`を使って作ります。
```css title="CSS" showLineNumbers
.triangle {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
}
```
これは「三角形」に見えるだけで、要素としての面積はゼロであり、**背景色や背景画像を使えません**。
一方で`clip-path`を使うと、普通に背景色や画像を適用した状態で三角形を表現できます。
```css title="CSS" showLineNumbers
.clip-triangle {
width: 200px;
height: 200px;
background: red;
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
}
```
これはしっかりと“面”として存在する三角形。背景画像も透過も影もOKです。
#### 2\. クリック範囲(hit area)も変わる
`clip-path`を使って表示されていない部分は、マウスイベントの対象外になります。つまり、視覚的に見えない部分は**クリックできません。**
たとえば、円形ボタンを`clip-path: circle()`で作れば、**円の中だけがクリック可能**になります。
これはアクセシビリティやUIの一貫性の観点でも大きなメリットです。
#### 3\. アニメーションとの相性が良い
`clip-path`は数値で指定するので、**hover時の形状変化**や**スクロールアニメーション**にも使いやすいです。
```css title="CSS" showLineNumbers
.box {
clip-path: circle(40%);
transition: clip-path 0.4s ease;
}
.box:hover {
clip-path: circle(75%);
}
```
ボタンのホバーやカードの動きにちょっと変化をつけたいとき、見た目にインパクトを出したいときに使えます。
### clip-pathで作れる主な形
`clip-path`は様々な関数で形を指定できます
| 形 | 使う関数 | 説明 |
| ------------------ | ----------- | ------------------------------ |
| 円形 | `circle()` | 中心と半径を指定 |
| 楕円形 | `ellipse()` | 横・縦方向の半径を指定 |
| 四角形(角丸も可) | `inset()` | 内側の距離と角丸を指定 |
| 三角形〜多角形 | `polygon()` | 自由な頂点で指定 |
| SVGパス | `path()` | 複雑な図形も対応(上級者向け) |
## 初心者でもできるclip-path活用アイデア
### 三角形のサンプルコード
```css title="CSS" showLineNumbers
.clip-triangle {
width: 200px;
height: 200px;
background: #0077cc;
clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
margin: 40px auto;
}
```
基本的な三角形です。
### ホバーで形を変えるアニメーション
```css title="CSS" showLineNumbers
.card {
clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
transition: clip-path 0.3s ease;
}
.card:hover {
clip-path: polygon(10% 0, 90% 0, 100% 100%, 0% 100%);
}
```
ほんの少し形を変えるだけで「動きのあるおしゃれなUI」が実現できます。
こちらは実際にデモ画面でご覧ください。
## よくある注意点
便利なclip-pathですが、以下のような注意点もあります。
- **IEは非対応**(基本的に2023年以降は気にしなくてOK)
- ブラウザによっては`clip-path`の複雑なアニメーションでパフォーマンス低下することも
- `polygon()`の座標は **%指定にするとレスポンシブ対応しやすい**
- スマホでは形の崩れが起きやすいので、**実機でのテストが必須**
## おすすめツール
複雑な形を自分で手入力するのは大変…という方は、
以下のツールを使うと、マウス操作だけでclip-pathを作成できます。
GUIで形を作れば、その場でCSSが生成されるのでとても便利です!
## おわりに
`clip-path`を使えば、CSSだけで今まで難しかった形状デザインがサクッと実装できます。
- 背景色付きの三角形や波型など、簡単に作れる
- デザインの差別化・動きのあるUIにぴったり
- 初心者でも、コピペから試せる手軽さ
まずは三角形や斜めの区切りから始めてみましょう。
1つ使えるようになると、表現の幅が一気に広がります!
---
## position: absolute を使ってレスポンシブ対応!%で相対指定のすゝめ
- URL: https://blog.to-ko-s.com/articles/position-absolute-specification
- 著者: 寺田拓真
- 公開日: 2025-04-26
- タグ: HTML, CSS
> position absoluteでのレスポンシブ対応をpx指定からパーセンテージ指定に変えることで実現する方法を解説。固定値指定の問題点と、親要素に対する相対指定によるレイアウト崩れの防止方法を紹介します。
## はじめに
こんにちは!たくまです!
Web制作を始めたばかりの方にとって、要素の配置は難題の1つです。
特に`position: absolute`を使って要素を配置しようとすると、画面サイズが変わったときに思ったように動かないことがありませんか?
例えば、以下のような記述を使用した場合:
```css
.container {
position: relative;
width: 80%;
margin: 0 auto;
}
.absolute-box {
position: absolute;
top: 100px;
left: 50px;
width: 300px;
}
```
このコードでは、`.absolute-box`は`.container`の中で、上から100px、左から50pxの位置に幅300pxで配置されます。
しかし、タブレットやスマホなどの画面サイズが小さいデバイスでは、`.container`の幅が狭くなり、`.absolute-box`が親要素からはみ出したり、他の要素と重なったりする可能性があります。
特に、固定のピクセル値を使用するとレスポンシブデザインに対応しづらくなります。
しかし、`position: absolute`を使いながらも、親要素に対するパーセンテージ指定を活用することで、レスポンシブ対応に適した柔軟なレイアウトを実現できます。
## `position: absolute`の基本
ご存じの方も多いかと思いますが、`position: absolute`について簡単なおさらいです!
`position: absolute`を指定した要素は、それまでの流れから外れて、特定の位置に配置されます。
その配置の基準となるのは、主に`position`が`relative`に設定された親要素です。
もしそのような親要素が存在しない場合、`body`要素が基準となります。
```css
.container {
position: relative;
width: 80%;
margin: 0 auto;
}
.absolute-box {
position: absolute;
top: 100px;
left: 50px;
width: 300px;
}
```
冒頭の例の場合、`container`に`position: relative;`が設定されているため、`.container`の中で、上から100px、左から50pxの位置に幅300pxで配置されます。
しかし、`position: relative;` が設定されていない場合は、`body`の上から100px、左から50pxの位置に幅300pxで配置されます。
## ピクセル(`px`)指定の問題点
`position: absolute`を使用する際に、`top`、`left`などをpx単位で指定すると、以下のような問題が発生することがあります。
- **画面サイズに応じた調整が困難**:固定されたピクセル値は、異なるデバイスや画面サイズに対応しづらく、要素が意図しない位置に表示されることがあります。
- **重なりやはみ出しの発生**:他の要素との重なりや、コンテナからのはみ出しが発生し、レイアウトが崩れる原因となります。
- **メンテナンスの難しさ**:複数のメディアクエリを使用して各画面サイズに対応する必要があり、スタイルシートが複雑になります。
特に複数の`position: absolute`をpx指定で使用した場合、レスポンシブ対応で意図せぬレイアウトが多発して修正に時間がかかってしまうことも多いかと思います🫠
## パーセンテージ(%)指定の活用でレスポンシブ対応
`position: absolute`を使用する際、`top`、`left`、`width`、`height`などのプロパティにパーセンテージ(%)を使用することで、親要素のサイズに対する相対的な配置が可能になります。
これにより、画面サイズの変化に応じて要素の位置やサイズが自動的に調整され、レスポンシブなレイアウトが実現できます。
### なぜパーセンテージ指定がレスポンシブ対応に有効なのか?
`top`や`left`などの位置指定プロパティに%を使用、`width`や`height`に%を使用すると、その値は親要素のサイズに対する割合として解釈されます。
つまり、**親要素のサイズが変化しても、子要素の位置やサイズはその割合に基づいて自動的に調整される**ため、画面サイズの変化に柔軟に対応できます。
実際のコードと画面で確認してみましょう。
```html
```
```css
.container {
position: relative;
width: 80%;
background-color: red;
margin: 0 auto;
height: 700px;
}
.absolute-box {
position: absolute;
background-color: blue;
top: 30%;
left: 5%;
width: 50%;
height: 50px;
color: white;
}
```
上記のコードでは、`.absolute-box`は`.container`の上から30%、左から5%の位置に配置され、幅は親要素の50%となります。画面サイズが変化して`.container`のサイズが変わっても、`.absolute-box`の位置とサイズは自動的に調整され、レスポンシブなレイアウトが実現されます。
画面幅が小さくなってもコンテンツの位置関係は変わってないことが分かるかと思います。
{/* prettier-ignore */}
- %指定は親要素のサイズに依存するため、親要素に`position: relative`を設定し、明確なサイズを指定することが重要です。
- 要素の高さや幅を%で指定する場合、親要素の高さや幅が明確に設定されていないと、期待通りに動作しないことがあります。
## まとめ
`position: absolute`を使用しながらも、親要素に対するパーセンテージ指定を活用することで、レスポンシブ対応の柔軟なレイアウトが実現可能です。
`position: absolute`は非常に便利なプロパティですが、使い方次第では他の要素を巻き込んでおかしなレイアウトになってしまうので注意しましょう。
適切な親要素の設定と相対的な配置を意識することで、画面サイズの変化にも対応したレイアウトを構築できます。
また、複雑なレイアウトや多くの要素を含む場合は、FlexboxやGridレイアウトの使用も検討しましょう。
今後のWeb制作において、これらのテクニックを活用して、より柔軟でユーザーフレンドリーなレイアウトを目指しましょう。
---
## 【2025年最新】WordPressにreCAPTCHAを導入する方法
- URL: https://blog.to-ko-s.com/articles/wordpress-anti-spam-recaptcha
- 著者: 成岡拓哉
- 公開日: 2025-04-20
- タグ: WordPress
> WordPressにGoogleのreCAPTCHAを導入する方法を解説します。従来の専用サイトからの登録方法とGoogle Cloud Consoleでの導入方法の両方を紹介します。
## はじめに
こんにちは。株式会社TOKOSのタクヤです。
いきなりですが、
「お問い合わせフォームから迷惑メールが毎日のように届いて困っている…」
「reCAPTCHAの設定って難しそう…」
そんなお悩みをお持ちではありませんか?
WordPressでサイト運営をしている方が抱える問題として迷惑メールが挙げられます。
この記事では、Googleが提供するスパム対策ツール「reCAPTCHA」を活用して迷惑メール対策をする方法を最新情報をもとに詳しく解説していきます。
従来の専用サイトからの登録方法だけでなくGoogle Cloudを使用した導入方法までしっかりと紹介します。
### 対象読者
- WordPressのお問い合わせフォームでスパム対策をしたい方
- reCAPTCHAの導入をしたい方
Googleは2025年末までに、すべてのreCAPTCHAキーをGoogle Cloudプロジェクトに統合する方針を発表しています。
これにより、今後はCloud Consoleでの管理が標準となっていく見込みです。
## reCAPTCHAとは
reCAPTCHA(リキャプチャ)とは、Googleが提供するスパム防止システムで、アクセスしてきた相手が「人間かボットか」を判定してくれる仕組みです。
例えば、あなたがWebサイトにアクセスしたときに「信号機の画像を選んでください」のような質問が表示されたことがあるかと思いますが、それがまさにreCAPTCHAです。
### reCAPTCHAの種類
| **バージョン** | **特徴** | **対象ユーザー** |
| --------------------- | -------------------------------------------------- | ------------------------------------------ |
| v2 チェックボックス型 | 「私はロボットではありません」にチェックするタイプ | 初心者にも使いやすい |
| v2 Invisible | ボタンを押したタイミングで裏側で認証 | ユーザーに負担をかけたくない場合におすすめ |
| v3 スコア判定型 | 裏で自動判定される仕組み。UIに影響を与えない | 上級者・中〜大規模サイト向け |
| Enterprise | v3の拡張版で、課金と詳細分析が可能 | 商用サービス向け(Google Cloud必須) |
reCAPTCHAは無料で利用できて導入も難しくありません。
ただ無料で利用できる月間リクエスト数が10,000リクエストとなっているため、中〜大規模サイトでは無料版だと不十分です。そんな場合は有料版のEnterpriseを契約するか、別のサービスを利用するのも良いかもしれません。
同等の機能で無料で利用できるサービスとして、Cloudflareが提供している`Cloudflare Turnstile`というものがあります。
`Cloudflare Turnstile`についてはこちらの記事を参考に導入してみてください。
## 従来の導入手順
以前は、Googleの専用サイトからreCAPTCHAを手軽に導入できました。
※ただし、現在でも従来の方法で導入が可能なため、念のため解説します。
**1. reCAPTCHA公式サイトにアクセス**
**2. Googleアカウントでログイン**
**3. 新しいサイトの登録を行う(ラベル、ドメイン、reCAPTCHAのバージョンなどを選択)**

**4. サイトキーとシークレットキーを取得**

**5. WordPress側にプラグインを導入(例:Contact Form 7)**
**6. WordPressの管理画面から取得したキーを登録**


WebサイトにreCAPTCHAが導入されました。

## Google Cloud での導入
以前はGoogle reCAPTCHA専用サイトから簡単に導入できるものでしたが、現在はGoogle Cloudへの統合が進んでおり、より高機能で安全な利用が可能になっています。
**1. Google Cloud Consoleにアクセス**
**2. Googleアカウントでログイン**
**3. プロジェクトを作成(reCAPTCHA専用でOK)**


**4. 「reCAPTCHA Enterprise API」を有効化**


**5. キーを作成**


**6. サイトキーを取得**

**7. シークレットキーの取得**


**8. WordPress側にプラグインを導入(例:Contact Form 7)**
**9. WordPressの管理画面から取得したキーを登録**


WebサイトにreCAPTCHAが導入されました。

## さいごに
今回はWordPressにGoogleのreCAPTCHAを導入する方法を解説しました。
WordPressサイトでのスパム対策に効果的なreCAPTCHAは、今後Google Cloudでの利用が主流になっていきます。
ぜひこの記事を参考にWordPressのスパム対策をしてみてください。
---
## 【初心者向け】JavaScriptで要素の監視を行う方法
- URL: https://blog.to-ko-s.com/articles/javascript-mutation-observer
- 著者: 成岡拓哉
- 公開日: 2025-04-18
- タグ: JavaScript
> JavaScriptのMutationObserverでDOMの変化を監視する方法を解説します。要素の追加・削除、属性変更、テキスト変更を検知する実装例を紹介します。
## はじめに
こんにちは!株式会社TOKOSのフロントエンドエンジニアのタクヤです!
「HTMLが変化したときに自動で監視できたら便利なのに…」と感じたことはありませんか?
この記事では、JavaScriptでHTMLの変化を監視する方法として、`MutationObserver`の使い方を解説します。初学者の方でも理解できるよう、構文と具体的なコード例を交えて紹介していきます。
### 対象読者
- JavaScriptを学び始めた方
- JavaScriptを用いて要素の変更を監視したい方
## MutationObserverとは
`MutationObserver`(ミューテーションオブザーバー)とは、Webページ上の要素(DOM)が変化したことを監視するためのJavaScriptの仕組みです。
例えば、HTMLの要素が追加・削除されたり、テキストが書き換えられたり、属性(classやidなど)が変更された場合に、JavaScriptがリアルタイムでそれを監視してくれるといった具合です。
Webサイトでは、要素が追加・削除されたり、属性が変更されたりすることがあります。こうしたDOMの変化をリアルタイムで監視して、任意の処理を実行できるのが`MutationObserver`の役割です。
以前はMutation Eventsという仕組みがありましたが、今ではパフォーマンスと柔軟性の面で優れた`MutationObserver`が主流です。
## 基本的な使い方
```html title="index.html" showLineNumbers
ISSENブログ
```
```javascript title="main.js" showLineNumbers
// 監視対象の要素を取得
const targetElement = document.getElementById("target-element")
// 変更があったときに実行される関数の定義
const callback = () => {
console.log("変更がありました")
}
// オプションの設定(どの変更を監視するか)
const config = {
childList: true, // 子要素の追加・削除を監視
}
// インスタンス生成と監視開始
const observer = new MutationObserver(callback)
observer.observe(targetElement, config)
```
`config`では、どの種類の変化を監視するかを細かく設定できます。
`childList`は子要素の追加・削除を監視するオプションです。
`callback`はコールバック関数で、監視対象に変更があった際に自動で呼び出される関数です。
## 実例
少し複雑な実例として、もとからあるHTML要素の中に新しく要素を作成してそれを監視してみます。
```html title="index.html" showLineNumbers
```
```javascript title="main.js" showLineNumbers
// 監視対象の要素を取得
const targetElement = document.getElementById("target-element")
// ボタンの要素を取得
const btnElement = document.getElementById("add-btn")
// 変更があったときに実行される関数の定義
const callback = () => {
console.log("新しい要素が追加されました")
}
// オプションの設定(どの変更を監視するか)
const config = {
childList: true, // 子要素の追加・削除を監視
}
// インスタンス生成と監視開始
const observer = new MutationObserver(callback)
observer.observe(targetElement, config)
// ボタンをクリックで要素を追加
btnElement.addEventListener("click", () => {
const newElement = document.createElement("span")
newElement.textContent = "新しいテキストです"
targetElement.appendChild(newElement)
})
```
### 監視オプションの詳細解説
以下は、MutationObserverで指定できる主なオプションとその意味をまとめた表です。
| オプション名 | 説明 |
| ------------- | ------------------------------------------------------------------ |
| childList | 子要素の追加・削除を監視します。 |
| attributes | HTMLタグの属性(classやidなど)の変更を監視します。 |
| characterData | テキストノードの中身が変更されたときに検出します。 |
| subtree | 指定した要素の中にある子や孫の要素もすべて含めて監視対象にします。 |
### テキスト内容の変化を監視(characterData)
タグの中にあるテキストそのものが書き換えられたときに監視したいときは、`characterData: true`を使います。
ただし、テキストノード自体を監視対象に指定する必要があります。
`textContent`を変更すると子ノードの置換として扱われるため、`characterData`では検知されません。
テキストノードの`nodeValue`を直接変更するか、`subtree: true`を併用する必要があります。
```html title="index.html" showLineNumbers
ISSENブログ
```
```javascript title="main.js" showLineNumbers
// 監視対象の要素を取得
const targetElement = document.getElementById("target-element")
// 変更があったときに実行される関数の定義
const callback = () => {
console.log("テキストに変更がありました")
}
// オプションの設定(タグ内のテキストの変更)
const config = {
characterData: true,
subtree: true, // 子孫のテキストノードも監視対象にする
}
// インスタンス生成と監視開始
const observer = new MutationObserver(callback)
observer.observe(targetElement, config)
// テキストノードのnodeValueを直接変更
targetElement.firstChild.nodeValue = "新しい文字" // ここで監視される
```
### タグの属性の変更を監視(attributes)
HTMLタグには`class`や`id`、`disabled`などの属性があります。
これが変更されたときに監視したい場合は、`attributes: true`を設定します。
```html title="index.html" showLineNumbers
ISSENブログ
```
```javascript title="main.js" showLineNumbers
// 監視対象の要素を取得
const targetElement = document.getElementById("target-element")
// 変更があったときに実行される関数の定義
const callback = () => {
console.log("属性に変更がありました")
}
// オプションの設定(属性の変更)
const config = {
attributes: true,
}
// インスタンス生成と監視開始
const observer = new MutationObserver(callback)
observer.observe(targetElement, config)
// 属性の変更
targetElement.setAttribute("class", "changed") // ここで監視される
```
### 子要素の追加・削除を検知する(childList)
指定した要素の「直下の子要素」に変更があったかどうかを監視します。
例えば、`appendChild()`や`removeChild()`で子要素が追加・削除されたときに反応します。
ただし、子孫要素(子の中の子など)の変更までは監視できません。
それらも含めて監視したい場合は、次の`subtree`オプションを追加します。
```html title="index.html" showLineNumbers
```
```javascript title="main.js" showLineNumbers
// 監視対象の要素を取得
const targetElement = document.getElementById("target-element")
// 変更があったときに実行される関数の定義
const callback = () => {
console.log("子要素に変更がありました")
}
// オプションの設定(直下の子要素の変更を監視)
const config = {
childList: true, // 直下の子要素の追加・削除を監視
}
// インスタンス生成と監視開始
const observer = new MutationObserver(callback)
observer.observe(targetElement, config)
const newElement = document.createElement("span")
newElement.textContent = "新しいテキストです"
targetElement.appendChild(newElement) // ここで監視される
```
### 子要素や孫要素もまとめて監視(subtree)
`subtree: true`を指定すると、指定した要素の「子ども」や「孫」の要素もすべてまとめて監視できます。
これがない場合、直下の子要素の変更しか検知できません。
```html title="index.html" showLineNumbers
```
```javascript title="main.js" showLineNumbers
// 監視対象の要素を取得
const targetElement = document.getElementById("target-element")
// 変更があったときに実行される関数の定義
const callback = () => {
console.log("子孫要素に変更がありました")
}
// オプションの設定(子孫要素も含めて監視)
const config = {
childList: true,
subtree: true, // 子孫要素も監視対象にする
}
// インスタンス生成と監視開始
const observer = new MutationObserver(callback)
observer.observe(targetElement, config)
```
## よくあるミスと注意点
### 監視対象の要素が存在しない
```javascript title="main.js" showLineNumbers
const targetElement = document.getElementById("target-element")
```
この行で`null`が返ると、その後の`observer.observe()`がエラーになります。
監視前に必ず対象があるか確認しましょう。
### オプション設定の漏れ
たとえば子要素の追加を監視したいのに`childList: true`を設定していなければ、何も監視されません。
目的に応じて正しく`config`を指定しましょう。
### 不要な範囲の監視でパフォーマンスが低下
`subtree: true`にすると、対象の子孫すべてを監視します。
大量のDOMを対象にする場合は、必要最小限に絞ることが重要です。
## 終わりに
今回はJavaScriptでHTMLの変化を監視する方法を解説しました。
`MutationObserver`を使えば、DOMの変更を効率的に監視できます。
非同期通信やユーザー操作によって変化するWebサイトではとても役立つ技術です。
ぜひ参考にしてみてください。
---
## 【JavaScript】データ重複を許さないSetクラスの紹介
- URL: https://blog.to-ko-s.com/articles/javascript-set
- 著者: 杉田侑祐
- 公開日: 2025-04-06
- タグ: JavaScript
> JavaScriptのSetクラスと配列の違いを解説。重複を許さないSetの特性や、主要メソッドの対応関係、パフォーマンス比較、実践的な使用例を学べます
## はじめに
### この記事の概要
こんにちは、株式会社TOKOSの杉田です!
今回はJavaScriptのSetクラスの基本的な使い方から、実践的な応用例まで詳しく解説していきます!
あまり使用する頻度はないかもしれませんが重複を許さないユニークな値の集合を扱う場合などに活躍します!
ぜひ最後までご覧ください!
この記事では、以下の内容について詳しく解説します:
- Setクラスの使用方法
### 対象読者
- 初学者の方
- フロントエンド開発をされている方
### この記事で扱う内容、扱わない内容
この記事で扱う内容 :
- Setクラスの概要
この記事で扱わない内容:
- JavaScriptの基本的な使用方法
## 概要
JavaScriptのSetクラスは、ES6(ECMAScript 2015)で導入されました!
冒頭でもお伝えしましたが、重複を許さないユニークな値の集合を扱う場合などで使用します!
### Setクラスの基礎
Setオブジェクトは、プリミティブ値やオブジェクト参照を含む、どのような型のユニーク(一意)の集合も保持できます。
Setの主な特徴は下記になります。
- 値が一度だけ格納される(重複不可)
- 順序が保持される(挿入順)
- キーを使わず値のみを格納
- NaNとundefinedも格納可能
また、紛らわしいですが配列とは別物になります。
配列との違いは下記になります。
重複要素の扱い
- Set
- 重複する値を保持できない
- 配列
- 同じ値を複数持つことができる
要素の検索効率
- Set
- `has()`メソッドによる要素検索は非常に高速
- 配列
- `includes()`や`indexOf()`による検索はSetに劣る
要素へのアクセス
- Set
- インデックスによる直接アクセスはできない
- 配列
- `array[index]`のように直接インデックスでアクセスできる
### Setクラスの主要メソッド
Setクラスの主要メソッドは下記になります。
| Setのメソッド | 配列での同等の操作 | 説明 |
| ----------------- | -------------------------------------------- | ------------------------------------------------------------ |
| new Set() | \[\] | 新しい空のコレクションを作成 |
| add(value) | push(value) | 要素を追加する |
| delete(value) | splice(array.indexOf(value), 1) | 特定の値を削除する |
| has(value) | includes(value) または indexOf(value) !== -1 | 値が存在するか確認する |
| clear() | length = 0 または splice(0) | すべての要素を削除する |
| forEach(callback) | forEach(callback) | 各要素に対してコールバックを実行 |
| values() | values() | 値のイテレータを返す |
| entries() | entries() | キーと値のペアのイテレータを返す(配列では\[index, value\]) |
### 基本的な使用例
要素の追加・削除などメソッドを使用した例は下記になります。
```javascript title="JavaScript" showLineNumbers
// 新しいSetを作成
const colors = new Set()
// 要素を追加
colors.add("赤")
colors.add("青")
colors.add("緑")
console.log(colors.size) // 3
// 重複要素の追加は無視される
colors.add("赤")
console.log(colors.size) // 3(変わらない)
// 要素の存在確認
console.log(colors.has("赤")) // true
console.log(colors.has("黄")) // false
// 要素の削除
colors.delete("青")
console.log(colors.size) // 2
// すべての要素を削除
colors.clear()
console.log(colors.size) // 0
```
上記例のように、重複要素が追加される場合は無視されます!
### 配列との相互変換
冒頭で配列とは別物とお伝えしましたが、相互変換ができます!
```javascript title="JavaScript" showLineNumbers
// 配列からSetへの変換
const array = [1, 2, 2, 3, 4, 4, 5]
const uniqueSet = new Set(array)
console.log(uniqueSet) // Set(5) {1, 2, 3, 4, 5}
// SetからArrayへの変換
const uniqueArray = [...uniqueSet]
console.log(uniqueArray) // [1, 2, 3, 4, 5]
// または Array.from() を使う方法
const anotherUniqueArray = Array.from(uniqueSet)
console.log(anotherUniqueArray) // [1, 2, 3, 4, 5]
```
### 実践的な応用例
ここからよく使うパターンを紹介します!
**配列から重複を削除する**
```javascript title="JavaScript" showLineNumbers
function removeDuplicates(array) {
return [...new Set(array)]
}
const numbersWithDuplicates = [1, 2, 2, 3, 4, 4, 5, 5, 5]
const uniqueNumbers = removeDuplicates(numbersWithDuplicates)
console.log(uniqueNumbers) // [1, 2, 3, 4, 5]
```
**2つの配列の共通要素を見つける(交差)**
```javascript title="JavaScript" showLineNumbers
function intersection(arrayA, arrayB) {
const setB = new Set(arrayB)
return arrayA.filter((element) => setB.has(element))
}
const array1 = [1, 2, 3, 4, 5]
const array2 = [3, 4, 5, 6, 7]
console.log(intersection(array1, array2)) // [3, 4, 5]
```
**2つの配列の差分を見つける(差集合)**
```javascript title="JavaScript" showLineNumbers
function difference(arrayA, arrayB) {
const setB = new Set(arrayB)
return arrayA.filter((element) => !setB.has(element))
}
const array1 = [1, 2, 3, 4, 5]
const array2 = [3, 4, 5, 6, 7]
console.log(difference(array1, array2)) // [1, 2]
```
**2つの配列を結合して重複を削除(和集合)**
```javascript title="JavaScript" showLineNumbers
function union(arrayA, arrayB) {
return [...new Set([...arrayA, ...arrayB])]
}
const array1 = [1, 2, 3]
const array2 = [2, 3, 4, 5]
console.log(union(array1, array2)) // [1, 2, 3, 4, 5]
```
**オブジェクト配列から特定のプロパティの重複を削除**
```javascript title="JavaScript" showLineNumbers
function getUniqueByProperty(array, prop) {
const seen = new Set()
return array.filter((item) => {
const value = item[prop]
if (seen.has(value)) {
return false
}
seen.add(value)
return true
})
}
const users = [
{ id: 1, name: "田中" },
{ id: 2, name: "鈴木" },
{ id: 3, name: "田中" }, // 重複した名前
{ id: 4, name: "佐藤" },
]
const uniqueUsers = getUniqueByProperty(users, "name")
console.log(uniqueUsers)
// [{ id: 1, name: '田中' }, { id: 2, name: '鈴木' }, { id: 4, name: '佐藤' }]
```
### パフォーマンスの考慮点
大量のデータを扱う場合、Setは配列操作よりもパフォーマンスが良いです。
下記コードは配列とSetのパフォーマンスを比較した例です。
Setの`has()`は配列の`includes()`と比べて、実行時間が100分の1程度になります。
```javascript title="JavaScript" showLineNumbers
// パフォーマンス比較の例
const largeArray = Array.from({ length: 100000 }, (_, i) => i)
const largeSet = new Set(largeArray)
console.time("Array includes")
const inArray = largeArray.includes(99999)
console.timeEnd("Array includes") // Array includes: ~5-10ms
console.time("Set has")
const inSet = largeSet.has(99999)
console.timeEnd("Set has") // Set has: ~0.01-0.05ms
```
## さいごに
今回はあまり馴染み深くないSetクラスについて紹介しました!
配列を使用することが多いとは思いますが、扱うデータによっては実装が簡潔になり、パフォーマンスも向上するため、ぜひ活用してみてください!
---
## 【Next.js】Suspenseの初歩的な使い方
- URL: https://blog.to-ko-s.com/articles/nextjs-suspense
- 著者: 西原月熙
- 公開日: 2025-03-30
- タグ: React, Next.js
> Next.jsでのSuspenseの基本的な使い方を解説。サーバーコンポーネントでのawaitパターンやクライアントコンポーネントでのuse hookを用いた実装方法を、コード例とともに紹介します。
## はじめに
こんにちは、株式会社TOKOSの[ツキヤ](https://x.com/west_tsukiya)です!
React18から、`Suspense`が本格的に使えるようになりましたね。
適切に使うことでUXやパフォーマンス観点で有益な機能です✨
本記事では、そんな`Suspense`をNext.jsと組み合わせて使う一般的な方法を説明します💪
## Suspenseとは?
ひとことで簡単に言うと、「**コンポーネントが読み込み(ロード)中の間に、別のコンポーネントを一時的に表示する仕組み**」です!
では、「読み込み中」とはどんな状態でしょうか?🤔
これもひとことで言うと「`Promise`が解決していない」データを持っている状態です!
簡単なコード例を見てみましょう!
```tsx title="page.tsx"
export default function Page() {
const response = fetch("https://jsonplaceholder.typicode.com/posts")
return (
Loading... }>
Loading...
`という文字が表示されることになるわけです!
この時、「静的なUIは即座にUIに表示させることができる」点が嬉しいポイントです✨
今回の例で言うと、`footer`は静的なUIなので、データの`fetch`等を待たずに即座に表示された方がユーザー体験としては嬉しいですよね🤭
`Suspense`を使わずにすぐに`await`をするパターンだと、「`Promise`が解決」されるまでは、画面内の全てのUIが表示されないことになってしまうのです😨
Promise(= 非同期)部分を適切に`Suspense`で括ることで、使っていて気持ち良いサイトにできるのです!
## Next.jsでSuspense対応をさせてみよう
それではざっくり理解が進んだところで、Next.jsで`Suspense`を使っていきましょう!
流れとしては、「`Suspense`を使わないバージョン」→「`Suspense`を使うバージョン」で進めていきます。
### 前提知識
サーバーコンポーネントやRouteHandler等の理解をしている前提で説明していきます。
また、TypeScriptを使用しています。