UI 設計小錦囊 - 20 種差異鮮明色彩組合
5 |
寫網頁介面時,有時我會想用多種顏色表示不同類別資料,此時如何挑選一組彼此差異明顯的顏色,差異大到即使同框出現也不致混淆,這批顏色該如何搭配組合是個學問。
面對這個常見的小需求,我 Google 到不錯的建議 - List of 20 Simple, Distinct Colors,為了繪製捷運路線圖需要 20 種不同且差異鮮明的顏色(若加上黑白共 22 種),作者花了不少時間,力求各顏色間不易混淆、色彩鮮明、具備對映顏色名稱,看起來也蠻順眼的,我很喜歡。
考慮色弱及視力障礙人士的無障礙需求,作者還整理了涵蓋 99% (19色)、99.99% (9色)、100% (5色) 人口比例的較高反差組合。
另外,選擇 Convenient 順序時,可依序取用,若需要六個顏色則取 1 - 6,需要 12 種取 1 - 12,數字小的優先使用,效果較好。
為了方便使用,我將這 20 種顏色轉成 CSS 樣式並分為前景版及背景版,背景版還需依據背景色選用醒目的文字顏色,我想到之前 Github Copilot 教我的魔術數字公式: complementary = (r * 0.299 + g * 0.587 + b * 0.114) > 186 ? '#000000' : '#ffffff';
寫幾行 JavaScript 產生 CSS 樣式:
const pool = ['#e6194B', '#3cb44b', '#ffe119', '#4363d8', '#f58231', '#911eb4', '#42d4f4', '#f032e6', '#bfef45', '#fabed4', '#469990', '#dcbeff', '#9A6324', '#fffac8', '#800000', '#aaffc3', '#808000', '#ffd8b1', '#000075', '#a9a9a9', '#ffffff', '#000000'];
const complementary = (hex) => {
const m = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return (parseInt(m[1], 16) * 0.299 + parseInt(m[2], 16) * 0.587 + parseInt(m[3], 16) * 0.114) > 186 ? '#000000' : '#ffffff';
}
console.log(pool.map((c, i) => `.dc-${i} { color:${c}; } .dbc-${i} { color:${complementary(c)}; background-color:${c}; }`).join('\n'));
最後輸出結果如下:
.dc-0 { color:'#e6194B'; } .dbc-0 { color:'#ffffff'; background-color:'#e6194B'; }
.dc-1 { color:'#3cb44b'; } .dbc-1 { color:'#ffffff'; background-color:'#3cb44b'; }
.dc-2 { color:'#ffe119'; } .dbc-2 { color:'#000000'; background-color:'#ffe119'; }
.dc-3 { color:'#4363d8'; } .dbc-3 { color:'#ffffff'; background-color:'#4363d8'; }
.dc-4 { color:'#f58231'; } .dbc-4 { color:'#ffffff'; background-color:'#f58231'; }
.dc-5 { color:'#911eb4'; } .dbc-5 { color:'#ffffff'; background-color:'#911eb4'; }
.dc-6 { color:'#42d4f4'; } .dbc-6 { color:'#ffffff'; background-color:'#42d4f4'; }
.dc-7 { color:'#f032e6'; } .dbc-7 { color:'#ffffff'; background-color:'#f032e6'; }
.dc-8 { color:'#bfef45'; } .dbc-8 { color:'#000000'; background-color:'#bfef45'; }
.dc-9 { color:'#fabed4'; } .dbc-9 { color:'#000000'; background-color:'#fabed4'; }
.dc-10 { color:'#469990'; } .dbc-10 { color:'#ffffff'; background-color:'#469990'; }
.dc-11 { color:'#dcbeff'; } .dbc-11 { color:'#000000'; background-color:'#dcbeff'; }
.dc-12 { color:'#9A6324'; } .dbc-12 { color:'#ffffff'; background-color:'#9A6324'; }
.dc-13 { color:'#fffac8'; } .dbc-13 { color:'#000000'; background-color:'#fffac8'; }
.dc-14 { color:'#800000'; } .dbc-14 { color:'#ffffff'; background-color:'#800000'; }
.dc-15 { color:'#aaffc3'; } .dbc-15 { color:'#000000'; background-color:'#aaffc3'; }
.dc-16 { color:'#808000'; } .dbc-16 { color:'#ffffff'; background-color:'#808000'; }
.dc-17 { color:'#ffd8b1'; } .dbc-17 { color:'#000000'; background-color:'#ffd8b1'; }
.dc-18 { color:'#000075'; } .dbc-18 { color:'#ffffff'; background-color:'#000075'; }
.dc-19 { color:'#a9a9a9'; } .dbc-19 { color:'#ffffff'; background-color:'#a9a9a9'; }
.dc-20 { color:'#ffffff'; } .dbc-20 { color:'#000000'; background-color:'#ffffff'; }
.dc-21 { color:'#000000'; } .dbc-21 { color:'#ffffff'; background-color:'#000000'; }
簡單寫個網頁測試效果:線上展示
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style>
.dc-0 { color:#e6194B; } .dbc-0 { color:#ffffff; background-color:#e6194B; }
.dc-1 { color:#3cb44b; } .dbc-1 { color:#ffffff; background-color:#3cb44b; }
.dc-2 { color:#ffe119; } .dbc-2 { color:#000000; background-color:#ffe119; }
.dc-3 { color:#4363d8; } .dbc-3 { color:#ffffff; background-color:#4363d8; }
.dc-4 { color:#f58231; } .dbc-4 { color:#ffffff; background-color:#f58231; }
.dc-5 { color:#911eb4; } .dbc-5 { color:#ffffff; background-color:#911eb4; }
.dc-6 { color:#42d4f4; } .dbc-6 { color:#ffffff; background-color:#42d4f4; }
.dc-7 { color:#f032e6; } .dbc-7 { color:#ffffff; background-color:#f032e6; }
.dc-8 { color:#bfef45; } .dbc-8 { color:#000000; background-color:#bfef45; }
.dc-9 { color:#fabed4; } .dbc-9 { color:#000000; background-color:#fabed4; }
.dc-10 { color:#469990; } .dbc-10 { color:#ffffff; background-color:#469990; }
.dc-11 { color:#dcbeff; } .dbc-11 { color:#000000; background-color:#dcbeff; }
.dc-12 { color:#9A6324; } .dbc-12 { color:#ffffff; background-color:#9A6324; }
.dc-13 { color:#fffac8; } .dbc-13 { color:#000000; background-color:#fffac8; }
.dc-14 { color:#800000; } .dbc-14 { color:#ffffff; background-color:#800000; }
.dc-15 { color:#aaffc3; } .dbc-15 { color:#000000; background-color:#aaffc3; }
.dc-16 { color:#808000; } .dbc-16 { color:#ffffff; background-color:#808000; }
.dc-17 { color:#ffd8b1; } .dbc-17 { color:#000000; background-color:#ffd8b1; }
.dc-18 { color:#000075; } .dbc-18 { color:#ffffff; background-color:#000075; }
.dc-19 { color:#a9a9a9; } .dbc-19 { color:#ffffff; background-color:#a9a9a9; }
.dc-20 { color:#ffffff; } .dbc-20 { color:#000000; background-color:#ffffff; }
.dc-21 { color:#000000; } .dbc-21 { color:#ffffff; background-color:#000000; }
</style>
<style>
input[type="number"] {
width: 4em;
}
.blocks {
display: flex;
flex-direction: row;
flex-wrap: wrap;
padding: 6px;
}
.blocks > span {
width: 2em; text-align: center;
margin: 2px;
border: 1px solid #ccc;
}
</style>
<script src="https://unpkg.com/vue@latest"></script>
</head>
<body>
<div id="app">
<label>
<input type="number" v-model="colorCount" min="4" max="22" /> Colors
</label>
<label>
<input type="number" v-model="blockCount" min="10" max="255" /> Blocks
</label>
<label>
<input type="checkbox" v-model="bgcolor" /> Background
</label>
<div class="blocks">
<span v-for="item in items" :class="item.css">
{{item.seq}}
</span>
</div>
</div>
<script>
const app = Vue.createApp({
data: function () {
return {
colorCount: 20,
blockCount: 100,
bgcolor: false
};
},
computed: {
items: function () {
const items = [];
for (let i = 0; i < this.blockCount; i++) {
items.push({
seq: i + 1,
css: (this.bgcolor ? 'dbc-' : 'dc-') + (parseInt(Math.random() * this.colorCount) % this.colorCount)
});
}
items.sort(() => Math.random() - 0.5);
return items;
}
},
});
app.mount('#app');
</script>
</body>
</html>
收入 UI 設計錦囊!
The suggestion of 20 distinct colors in same UI, this article shows a easy way to use them in HTML.
Comments
# by 小黑
「魔術數字公式」的似乎連結失效了
# by Ike
感覺 #42d4f4 搭 黑色字 會比較適合
# by Ka-iu
用我的網路打開線上展示會發現程式碼沒有執行,發現是因為這個 library 404: <script src="https://unpkg.com/vue@next"></script> 我從 Vue 官網找了這個套上去就正常了 <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> https://jsbin.com/puguges
# by JD
https://unpkg.com/vue@next 這個用不了 得換https://unpkg.com/vue@latest或其他
# by Jeffrey
to Kai-ui & JD, 感謝回報與補充,已修正。