CSS Media Queryのwidth < ○px記法の全ブラウザ対応方法

CSS Media Queryとは

CSS Media Query (CSSメディアクエリー)を使用すると画面サイズに応じてスタイルを適用できます。

例えば以下のように書けば画面幅が320px以上、768px未満のときに背景色が黄色になります。

@media (min-width: 320px) and (max-width: 767px) {
  body {
    background: yellow;
  }
}

@media (min-width: 320px) and (max-width: 767px) のサンプル

CSS Media Queryのmin-widthやmax-widthなど書き方は指定方法が直感的にわかりづらかったので、最近のモダンブラウザでは「320px <= width < 768px」のような書き方で適用できるようになりました。

後者の記法のほうが短く、わかりやすくなっています。

@media (320px <= width < 768px) {
  body {
    background: yellow;
  }
}

@media (320px <= width < 768px) のサンプル

全ブラウザで対応させる方法

@media (320px <= width < 768px) のような書き方だとわかりやすいですが、Safariだとバージョン16.3以下だと適用されません。

2023年3月31日時点ではSafariの最新バージョンはまだ16.4なので、この記法で書くと多くのSafariで無効になってしまいます。

Media Queries: Range Syntax | Can I use…

そのため、@media (320px <= width < 768px) のような書き方をしたい場合はPostCSS Media Minmaxを使用してmin-widthやmax-widthを使用した形式に変換する必要があります。

PostCSS Media Minmaxの使い方

まず以下のコマンドでPostCSSおよびPostCSS Media Minmaxをインストールします。

npm i -D postcss postcss-media-minmax

次にminmax.jsのような任意のファイルを作成して以下のように記述します。

const fs = require('fs')
const postcss = require('postcss')
const minmax = require('postcss-media-minmax')
const css = fs.readFileSync('input.css', 'utf8')
const output = postcss(minmax()).process(css).css

fs.writeFileSync('output.css', output)

あとは「node minmax.js」を実行すれば変換後のファイルが書き出されます。

変換前 input.css

@media (320px <= width < 768px) {
  body {
    background: yellow;
  }
}

変換後 output.css

@media (min-width: 320px) and (max-width: 767px) {
  body {
    background: yellow;
  }
}

Viteでの使用方法

Viteで使用する場合はvite.config.jsにてimportで読み込んでpluginsにminmax()を入れます。

// vite.config.js
import { defineConfig, loadEnv } from 'vite'
import minmax from 'postcss-media-minmax'

export default defineConfig(({ mode }) => {
  return {
    plugins: [htmlPlugin(loadEnv(mode, '.'))],
    css: {
      postcss: {
        plugins: [minmax()],
      },
    },
  }
})

function htmlPlugin(env) {
  return {
    name: 'html-transform',
    transformIndexHtml: {
      enforce: 'pre',
      transform: (html) => {
        return html.replace(/%(.*?)%/g, (match, p) => env[p] ?? match)
      },
    },
  }
}

Gulpでの使用方法

GitHubにあるpostcss / postcss-media-minmaxにはGulpでの書き方も記載されていますが、コードが間違っているため正しく動作しません。

正しく動作させるには以下のように記述します。

// gulpfile.js
const gulp = require('gulp')
const rename = require('gulp-rename')
const postcss = require('gulp-postcss')
const minmax = require('postcss-media-minmax')

gulp.task('default', () => {
  return gulp
    .src('src/*.css')
    .pipe(postcss([minmax()]))
    .pipe(rename('output.css'))
    .pipe(gulp.dest('build'))
})

まとめ

見ての通り新しいCSS Media Queryの記法を使用すれば、わかりやすいコードで記述できるようになります。

CSS Media Queryはmin-widthとmax-widthを間違えて記述してしまうミスが結構あるので、なるべく新しい記法で書くことをオススメします。

カテゴリーcss