<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>HTML5+CSS3制作的颜色选取器代码</title>
<style>
html {
box-sizing: border-box;
height: 100%;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
@media (prefers-reduced-motion: reduce) {
*,
*:before,
*:after {
-webkit-animation-duration: 0ms !important;
animation-duration: 0ms !important;
transition-duration: 0ms !important;
}
}
body {
height: 100%;
}
img {
max-width: 100%;
height: auto;
}
html {
background-color: #b0bec5;
font-family: "Roboto", sans-serif;
font-weight: 500;
}
.container {
padding: 1em;
}
.material-color-picker {
display: flex;
width: 32em;
margin: 0 auto;
background-color: white;
border: 1px solid #78909c;
border-radius: 0.5em;
box-shadow: 0 1em 8em rgba(0, 0, 0, 0.35);
}
.material-color-picker__left-panel {
z-index: 1;
}
.material-color-picker__right-panel {
position: relative;
flex-grow: 1;
overflow: hidden;
}
.color-selector {
margin: 0;
padding: 0;
list-style: none;
display: flex;
flex-direction: column;
padding: 1em 0;
border-right: 0.25em solid #E0E0E0;
}
.color-selector input[type='radio'] {
display: none;
}
.color-selector label {
position: relative;
display: inline-block;
padding: 0.5em 1.5em;
cursor: pointer;
}
.color-selector label:before {
content: '';
display: inline-block;
vertical-align: middle;
padding: 0.75em;
background-color: currentColor;
border-radius: 50%;
}
.color-selector label:after {
content: '';
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
padding: 0.5em;
border: 0.25em solid;
border-radius: 50%;
transition: padding 250ms;
}
.color-selector input[type='radio']:checked + label:after {
padding: 1em;
}
.color-palette-wrapper {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
-webkit-transform: translateX(-100%);
transform: translateX(-100%);
display: flex;
flex-direction: column;
padding: 1.5em;
}
.color-palette-wrapper.js-active {
-webkit-transform: translateX(0);
transform: translateX(0);
}
.color-palette-header {
display: flex;
justify-content: space-between;
margin: 0;
margin-bottom: 1em;
font-weight: 400;
color: #757575;
}
.color-palette {
margin: 0;
padding: 0;
list-style: none;
display: flex;
flex-direction: column;
flex-grow: 1;
}
.color-palette__item {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
flex-grow: 1;
margin: 0.25em 0;
padding: 0 1em;
border-radius: 0.25em;
font-family: "Roboto Mono", monospace;
transition: -webkit-transform 250ms;
transition: transform 250ms;
transition: transform 250ms, -webkit-transform 250ms;
cursor: pointer;
}
.color-palette__item:hover {
-webkit-transform: scale(1.05);
transform: scale(1.05);
}
.copied-indicator {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, 0);
transform: translate(-50%, 0);
opacity: 0;
transition: all 250ms;
}
.copied-indicator.js-copied {
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
opacity: 0.75;
}
</style>
</head>
<body>
<script src="js/knockout-min.js"></script>
<script src="js/clipboard.min.js"></script>
<div class="container">
<div class="material-color-picker">
<div class="material-color-picker__left-panel">
<ol class="color-selector" data-bind="foreach: materialColors">
<li>
<input name="material-color" type="radio" data-bind="attr: { id: 'materialColor' + $index() }, checked: selectedColor, value: color" >
<label data-bind="attr: { for: 'materialColor' + $index(), title: color }, style: { 'color': $data.variations[4].hex }"></label>
</li>
</ol>
</div>
<div class="material-color-picker__right-panel" data-bind="foreach: materialColors">
<div class="color-palette-wrapper" data-bind="css: { 'js-active': selectedColor() === color }">
<h2 class="color-palette-header" data-bind="text: color"></h2>
<ol class="color-palette" data-bind="foreach: variations">
<li id="clipboardItem" class="color-palette__item" data-bind="attr: { 'data-clipboard-text': hex }, style: { 'background-color': hex }">
<span data-bind="text: weight"></span>
<span data-bind="text: hex"></span>
<span class="copied-indicator" data-bind="css: { 'js-copied': copiedHex() === hex }">Color copied!</span>
</li>
</ol>
</div>
</div>
</div>
</div>
<script>
var copiedHex = ko.observable();
var clipboard = new Clipboard('#clipboardItem');
clipboard.on('success', function(el) {
console.clear();
console.info('Action:', el.action);
console.info('Text:', el.text);
console.info('Trigger:', el.trigger);
el.clearSelection();
copiedHex(el.text);
});
///
var selectedColor = ko.observable("Red"); // lazy
ko.applyBindings({
materialColors: [
{
color: "Red",
variations: [
{
weight: 50,
hex: "#FFEBEE"
},
{
weight: 100,
hex: "#FFCDD2"
},
{
weight: 200,
hex: "#EF9A9A"
},
{
weight: 300,
hex: "#E57373"
},
{
weight: 400,
hex: "#EF5350"
},
{
weight: 500,
hex: "#F44336"
},
{
weight: 600,
hex: "#E53935"
},
{
weight: 700,
hex: "#D32F2F"
},
{
weight: 800,
hex: "#C62828"
},
{
weight: 900,
hex: "#B71C1C"
}
]
},
{
color: "Pink",
variations: [
{
weight: 50,
hex: "#FCE4EC"
},
{
weight: 100,
hex: "#F8BBD0"
},
{
weight: 200,
hex: "#F48FB1"
},
{
weight: 300,
hex: "#F06292"
},
{
weight: 400,
hex: "#EC407A"
},
{
weight: 500,
hex: "#E91E63"
},
{
weight: 600,
hex: "#D81B60"
},
{
weight: 700,
hex: "#C2185B"
},
{
weight: 800,
hex: "#AD1457"
},
{
weight: 900,
hex: "#880E4F"
}
]
},
{
color: "Purple",
variations: [
{
weight: 50,
h