コラム・豆知識
CSSグリッドとフレックスボックスの活用
近年のWeb制作ではCSS Grid
やFlexbox
がカラムレイアウト計算を簡単にし、柔軟性を高めています。
これらの技術を利用することで、固定幅や割合幅、ギャップの設定などが直感的に行えます。
ブラウザ対応状況も良好なため積極的に活用しましょう。
マージンとパディングの影響と調整
カラム間のスペースを作るためにマージンやパディングを用いますが、これらはカラム幅の計算に大きく影響します。
ボックスモデルの理解が不可欠であり、正確な合計幅を計算してレイアウト崩れを防ぐ必要があります。
特に固定幅レイアウトでは注意が必要です。
レスポンシブデザインとメディアクエリの連携
カラム数や幅は画面サイズに応じて変化させることが多く、@media
クエリで細かく制御します。
これによりスマートフォンからデスクトップまで最適な表示を実現し、ユーザー体験の向上につながります。
計算ロジックとCSS設定を連動させることがポイントです。
ツールの仕組み解説
// 入力欄と表示欄の要素を準備 const inputs = { totalWidth: document.getElementById('totalWidth'), columns: document.getElementById('columns'), margin: document.getElementById('margin'), columnWidth: document.getElementById('columnWidth') }; const result = document.getElementById('result'); const error = document.getElementById('error'); const gridVisualization = document.getElementById('grid-visualization');
「全体幅」「カラム数」「マージン」「カラム幅」の4つの入力欄と、結果表示やエラー表示、グリッドの見た目を操作する部分を最初に取得しておきます。
// 入力欄が変わったら handleInput を実行 document.querySelectorAll('.calc-input').forEach(input => { input.addEventListener('input', handleInput); });
入力欄のどこかに文字を入れるたびに、計算を始める準備をします。
function handleInput(event) { const currentInput = event.target; // 4つすべて入力されないように制限 if (filledInputsCount === 3 && currentInput.value.trim() !== '') { // 他にすでに3つ入力されてたら、今の入力を消す const filledInputs = Object.values(inputs).filter(input => input !== currentInput && input.value.trim() !== '' ); if (filledInputs.length === 3) { currentInput.value = ''; return; } } // 入力されている欄が何個あるか数える filledInputsCount = Object.values(inputs) .filter(input => input.value.trim() !== '').length; // 入力が3つそろったら計算 if (filledInputsCount === 3) { calculate(); } else { result.classList.add('hidden'); error.classList.add('hidden'); } }
「4つのうち3つだけ入力してね」という制限をつけています。
3つ入力されたら、残り1つを自動計算するために calculate()
を実行します。
function formatNumber(value) { const roundedValue = Math.round(value * 100) / 100; return roundedValue % 1 === 0 ? roundedValue.toFixed(0) : roundedValue.toFixed(2); }
計算結果の小数点を、キレイな形に整える関数です。
たとえば 12.345 → 12.35、または 20.00 → 20 みたいに見やすくします。
function calculate() { // 入力されている値を取り出す const values = {}; let emptyField = null; Object.entries(inputs).forEach(([key, input]) => { if (input.value.trim() !== '') { values[key] = parseFloat(input.value); } else { emptyField = key; } }); ... }
入力されている3つの値を数値として取り出し、どれが空欄かをチェックしています。
// 空いてる項目ごとに計算処理を分ける if (emptyField === 'totalWidth') { calculatedValue = values.columnWidth * values.columns + values.margin * (values.columns - 1); showResult('全体幅', calculatedValue); }
「全体幅」が空欄だったら、 (カラムの幅 × 本数)+(マージン × 本数-1)で全体の長さを出しています。
else if (emptyField === 'columns') { calculatedValue = Math.floor((values.totalWidth + values.margin) / (values.columnWidth + values.margin)); showResult('カラム数', calculatedValue); }
「カラム数」が空欄なら、全体の幅 ÷(カラム幅 + マージン)でざっくり何本入るかを計算しています。
else if (emptyField === 'margin') { calculatedValue = (values.totalWidth - (values.columnWidth * values.columns)) / (values.columns - 1); if (calculatedValue < 0) { showError(...); return; } showResult('マージン', calculatedValue); }
マージンが空欄のときは、全体の幅からカラムの幅を引いて、間のすきまを割り出すような計算です。
else if (emptyField === 'columnWidth') { calculatedValue = (values.totalWidth - (values.margin * (values.columns - 1))) / values.columns; if (calculatedValue < 0) { showError(...); return; } showResult('カラム幅', calculatedValue); }
カラムの幅が空欄のときは、全体幅からマージン分を引いて、残りをカラム数で割ることで1本あたりの幅を求めます。
function showResult(label, value) { result.innerHTML = `計算結果:${label} ${formatNumber(value)}px`; result.classList.remove('hidden'); }
計算結果を画面に表示します。
function showError(excess) { error.innerHTML = `エラー:幅が${formatNumber(excess)}px足りません`; error.classList.remove('hidden'); }
無理な値(マイナスになるなど)になった場合は、エラーメッセージを表示します。
function updateGridVisualization(values, emptyField, calculatedValue) { // 入力値と計算値をもとに、グリッドの見た目を描く }
ここでは、実際のグリッドがどうなるかを画面に表示します。
カラムとマージンを交互に並べて、縮小して表示してくれるので、直感的にレイアウトをイメージできます。
window.addEventListener('DOMContentLoaded', () => { // ページを開いたときに、3つの値がそろっていれば自動で計算 });
最初から3つ入力されている場合は、自動で計算して結果を出してくれます。