CSS嫌いエンジニアの生存戦略~巨人の肩に乗りまくり~
このページを訪れた方へ
CSSが嫌い?それとも苦手?
この記事は、根本的なCSSへの苦手感を拭ったり、CSSを使えるようになるような記事ではありません。問題を解決しないし、"学び"としては嫌悪されるものです。フロントエンドエンジニアは曲がれ右してください。
他のCSS苦手なエンジニアは、どんなふうに開発してるんだろう?
という疑問を抱く方に向けて、少しでも参考や安心に繋がればいいなと思います。
なぜCSSが嫌い/苦手なの?
CSSが嫌いなエンジニアが多い理由を、勝手に考えてみたの記事を見て、だから私はCSSが苦手なのか、と納得しました。
- エラーが出ない
- プロパティの種類が多すぎる
- 無効化や削除したいのに、なんのプロパティのせいなのかが分からない
これがが私の苦手感の元でした。
どこのCSSがどんなふうに効いているのか?
が全くわからない。調べてやってみても、効かなかったり変に効いたり...
とにかく不明な点が多い。プロパティの種類も多いので難易度UP。
地道にモックアップをしても、結局身についてるのかよくわからない。
「とにかく今すぐモダンでいい感じの見た目を作りたい」
そんな時には巨人の肩に乗らせてもらおう。
Soliloquy Chat App
私の戦略を紹介するにあたり、例としてSoliloquy Chat Appを紹介します。
完成したUIはこんな感じ。
Tech Stack
こちらはとってもシンプルな静的Appです。
- HTML
- CSS
- JavaScript
- Render(デプロイ先)
詳しい開発経緯やApp内容については別記事へどうぞ。こちら
GithubはCSSどうしたの?
CodePenでお二方の先人のコードをお借りしました...!
最初は自分でやってみたものの、レスポンシブルで洗練されたデザインを...となると1からはとても無理。
UIコンポーネントライブラリを使いたい。React愛してる。
しかし、今回はVanillaでやると決めたので、自力でCSSを書くも断念。
CodePenで出会った偉大なるお二方のコードをお借りしました。
Codepen利用時の注意
Codepenに公開されているコードを自分のAppに取り入れる時には、以下のように引用元を表記する必要があります。
/*
Copyright (c) YEAR - AUTHORS NAME - URL TO ORIGINAL
Released under the MIT license
*/
公開されている大抵のコードはMITライセンスが取り入れられているそうです。
取り入れ方
自分が作りたいものを固めたら、Codepenで作りたいものに近いコードを探します。
例えば、今回私は「Chat CSS」「Fire CSS」と調べました。
上記の検索ワードでヒットした中で、Simple Chat UI by Sajad Hashemianと、CSS Only Fire by Simon Goellnerを使用させていただきました。
では、手本にするコードを見つけたらどうするか?
8つのStepにして紹介します。
- 作りたいAppのテーマ色を決める(1~3色の組み合わせ)
- Codepenをコピー&ペースト
- CSSでカラーをテーマ色に変える
- HTMLで、自分のAppには不要な要素を削除する
- CSSで、削除した要素についていたclass等へのstyleを削除する
- HTMLに、さらに追加したい要素を追加する(Soliloquy Chat Appではポップアップを追加)
- Codepenで見つけたコードを組み合わせる場合は、既存のHTMLの要素にclassをつけて実装するか、新しくHTMLの要素を追加するか検討(今回はclassを追加し、JSでclassの切り替えを実施)
- JSを扱いやすいように、リファクタリングする
わかりやすい変更例として、JSコードを載せます。
オリジナルのJSコード
from Simple Chat UI by Sajad Hashemian
const msgerForm = get(".msger-inputarea");
const msgerInput = get(".msger-input");
const msgerChat = get(".msger-chat");
const BOT_MSGS = [
"Hi, how are you?",
"Ohh... I can't understand what you trying to say. Sorry!",
"I like to play games... But I don't know how to play!",
"Sorry if my answers are not relevant. :))",
"I feel sleepy! :("
];
// Icons made by Freepik from www.flaticon.com
const BOT_IMG = "https://image.flaticon.com/icons/svg/327/327779.svg";
const PERSON_IMG = "https://image.flaticon.com/icons/svg/145/145867.svg";
const BOT_NAME = "BOT";
const PERSON_NAME = "Sajad";
msgerForm.addEventListener("submit", event => {
event.preventDefault();
const msgText = msgerInput.value;
if (!msgText) return;
appendMessage(PERSON_NAME, PERSON_IMG, "right", msgText);
msgerInput.value = "";
botResponse();
});
function appendMessage(name, img, side, text) {
// Simple solution for small apps
const msgHTML = `
<div class="msg ${side}-msg">
<div class="msg-img" style="background-image: url(${img})"></div>
<div class="msg-bubble">
<div class="msg-info">
<div class="msg-info-name">${name}</div>
<div class="msg-info-time">${formatDate(new Date())}</div>
</div>
<div class="msg-text">${text}</div>
</div>
</div>
`;
msgerChat.insertAdjacentHTML("beforeend", msgHTML);
msgerChat.scrollTop += 500;
}
function botResponse() {
const r = random(0, BOT_MSGS.length - 1);
const msgText = BOT_MSGS[r];
const delay = msgText.split(" ").length * 100;
setTimeout(() => {
appendMessage(BOT_NAME, BOT_IMG, "left", msgText);
}, delay);
}
// Utils
function get(selector, root = document) {
return root.querySelector(selector);
}
function formatDate(date) {
const h = "0" + date.getHours();
const m = "0" + date.getMinutes();
return `${h.slice(-2)}:${m.slice(-2)}`;
}
function random(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
リファクタリングしたJSコード
// 使わない関数は削除
const msgForm = document.getElementsByClassName("msger-inputarea");
const msgInput = document.getElementsByClassName("msger-input");
const msgChat = document.getElementsByClassName("msger-chat");
const main = document.getElementsByClassName("msger");
const title = document.getElementsByClassName("msger-header-title");
msgForm[0].addEventListener("submit", (e) => {
e.preventDefault();
const msgText = msgInput[0].value;
if(!msgText) {
return;
}
appendMessage(msgText);
msgInput[0].value = "";
})
// 追加機能のEventを設定
title[0].addEventListener("click", () => {
title[0].innerText = "BURN IT UP";
msgChat[0].classList.add("msger-fire");
main[0].classList.add("fire");
setTimeout(() => {
location.reload();
}, "4000")
})
// HTMLベタうちから、createDiv関数を作成しリファクタリング
function appendMessage(text) {
const parentDiv = createDiv(["msg", "right-msg"]);
const imgDiv = createDiv(["msg-img"]);
const bubble = createDiv(["msg-bubble"]);
const infoDiv = createDiv(["msg-info"]);
const timeDiv = createDiv(["msg-info-time"], formatDate(new Date()));
const textDiv = createDiv(["msg-text"], text);
const infoBlock = infoDiv.appendChild(timeDiv);
bubble.appendChild(infoBlock);
bubble.appendChild(textDiv);
parentDiv.appendChild(imgDiv);
parentDiv.appendChild(bubble);
msgChat[0].appendChild(parentDiv);
msgChat[0].scrollTop += 500;
}
function formatDate(date) {
const hour = "0" + date.getHours();
const min = "0" + date.getMinutes();
return `${hour.slice(-2)}:${min.slice(-2)}`;
}
// 追加した関数
function createDiv(classArr, inner) {
const newDiv = document.createElement("div");
if(classArr !== undefined) {
newDiv.classList.add(...classArr);
}
if(inner !== undefined) {
newDiv.innerText = inner;
}
return newDiv;
}
まとめ
CSS苦手の民が、先人のコードを元にコーディングする時のポイントは、
- テーマカラーを決める
- テーマに沿って細かなCSSを調整する
- 自分に必要ないコードは削除する
の3点です。
色や文字のフォント、線の太さを変えるだけでも印象が変わるので、基礎的なCSSを押さえておけばバッチリです。
もちろん自分でゼロイチでStyle当てられる方がいい!とは思う!けれど、作ってなんぼ精神で開発をしている人は、巨人の肩に乗りまくりましょう。どんなにいい機能があっても、見た目がダサければ目に留まらない。
CSS職人、愛してる。Codepen、ありがとう。精進します。
引用資料
- CSSが嫌いなエンジニアが多い理由を、勝手に考えてみた
- MITライセンス
- Simple Chat UI by Sajad Hashemian
- CSS Only Fire by Simon Goellner
おすすめ配色サイト
Discussion