├── README.md ├── LICENSE ├── kico.js └── kico.css /README.md: -------------------------------------------------------------------------------- 1 | # Kico-Style 2 | 3 | 一个可口的极简响应式前端框架。 4 | 5 | ## 使用方法 6 | 7 | 1. `Star` 本项目 8 | 2. 从这里 [下载](https://github.com/Dreamer-Paul/Kico-Style/archive/master.zip) 框架源码 9 | 3. 在你的项目中引用相关文件,参考 [文档](https://works.paugram.com/style) 快速使用 10 | 11 | ## 开源协议 12 | 13 | 本项目采用 MIT 开源协议进行授权,当然能留个版权说明就是最好的啦~ 14 | 15 | 原创不易!如果喜欢本项目,请 `Star` 它以示对我的支持~ 16 | 17 | 同时欢迎前往 [我的博客](https://paul.ren/donate) 为我提供赞助,谢谢您! 18 | 19 | ## 感谢 20 | 21 | 感谢来自开源社区提供的解决方案,为本项目的开发提供了参考和帮助! 22 | 23 | - [Tabler](https://github.com/tabler/tabler) 24 | - [JQuery](https://github.com/jquery/jquery) 25 | - [Bootstrap](https://github.com/twbs/bootstrap) 26 | - [Normalize.css](https://github.com/necolas/normalize.css) 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (C) 2019 Dreamer-Paul 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /kico.js: -------------------------------------------------------------------------------- 1 | /* ---- 2 | 3 | # Kico Style 1.0 4 | # By: Dreamer-Paul 5 | # Last Update: 2022.6.29 6 | 7 | 一个可口的极简响应式前端框架。 8 | 9 | 本代码为奇趣保罗原创,并遵守 MIT 开源协议。欢迎访问我的博客:https://paugram.com 10 | 11 | ---- */ 12 | 13 | Array.prototype.remove = function (value) { 14 | var index = this.indexOf(value); 15 | if(index > -1) this.splice(index, 1); 16 | }; 17 | 18 | (function (global, setting) { 19 | var KStyle = function (a, b) { 20 | return KStyle.fn.init(a, b); 21 | }; 22 | 23 | KStyle.fn = KStyle.prototype = { 24 | construtor: KStyle, 25 | init: function (a, b) { 26 | a = KStyle.selectAll(a); 27 | 28 | a.each = function (fn){ 29 | return KStyle.each(a, fn); 30 | }; 31 | 32 | a.image = function () { 33 | return KStyle.image(a); 34 | }; 35 | 36 | a.lazy = function (bg) { 37 | return KStyle.lazy(a, bg); 38 | }; 39 | 40 | a.scrollTo = function (offset) { 41 | return KStyle.scrollTo(a, offset); 42 | }; 43 | 44 | a.empty = function () { 45 | return KStyle.each(a, function (item) { KStyle.empty(item); }); 46 | } 47 | 48 | return a; 49 | } 50 | }; 51 | 52 | // 批量处理 53 | KStyle.each = function (data, fn) { 54 | for(var i = 0; i < data.length; i++){ 55 | fn(data[i], i, data); 56 | } 57 | }; 58 | 59 | // 创建对象 60 | KStyle.create = function (tag, prop) { 61 | var obj = document.createElement(tag); 62 | 63 | if(prop){ 64 | if(prop.id) obj.id = prop.id; 65 | if(prop.src) obj.src = prop.src; 66 | if(prop.href) obj.href = prop.href; 67 | if(prop.class) obj.className = prop.class; 68 | if(prop.text) obj.innerText = prop.text; 69 | if(prop.html) obj.innerHTML = prop.html; 70 | 71 | if(prop.child){ 72 | if(prop.child.constructor === Array){ 73 | KStyle.each(prop.child, (i) => { 74 | obj.appendChild(i); 75 | }); 76 | } 77 | else{ 78 | obj.appendChild(prop.child); 79 | } 80 | } 81 | 82 | if(prop.attr){ 83 | if(prop.attr.constructor === Array){ 84 | KStyle.each(prop.attr, (i) => { 85 | obj.setAttribute(i.name, i.value); 86 | }); 87 | } 88 | else if(prop.attr.constructor === Object){ 89 | obj.setAttribute(prop.attr.name, prop.attr.value); 90 | } 91 | } 92 | 93 | if(prop.parent) prop.parent.appendChild(obj); 94 | } 95 | 96 | return obj; 97 | }; 98 | 99 | // 选择对象 100 | KStyle.select = function (obj) { 101 | switch(typeof obj){ 102 | case "object": return obj; break; 103 | case "string": return document.querySelector(obj); break; 104 | } 105 | }; 106 | 107 | KStyle.selectAll = function (obj) { 108 | switch(typeof obj){ 109 | case "object": return obj; break; 110 | case "string": return document.querySelectorAll(obj); break; 111 | } 112 | }; 113 | 114 | // 清空子元素 115 | KStyle.empty = function (obj) { 116 | while(obj.firstChild){ 117 | obj.removeChild(obj.firstChild); 118 | } 119 | } 120 | 121 | // 弹窗 122 | var notice = { 123 | wrap: KStyle.create("notice"), 124 | list: [] 125 | }; 126 | 127 | KStyle.notice = function (content, attr) { 128 | var item = KStyle.create("div", {class: "ks-notice", html: "" + content + "", parent: notice.wrap}); 129 | 130 | notice.list.push(item); 131 | 132 | if(!document.querySelector("body > notice")) document.body.appendChild(notice.wrap); 133 | 134 | if(attr && attr.time){ 135 | setTimeout(notice_remove, attr.time); 136 | } 137 | else{ 138 | var close = KStyle.create("span", {class: "close", parent: item}); 139 | 140 | close.onclick = notice_remove; 141 | } 142 | 143 | if(attr && attr.color){ 144 | item.classList.add(attr.color); 145 | } 146 | 147 | function notice_remove() { 148 | item.classList.add("remove"); 149 | notice.list.remove(item); 150 | 151 | setTimeout(function () { 152 | try{ 153 | notice.wrap.removeChild(item); 154 | item = null; 155 | } 156 | catch(err) {} 157 | 158 | if(document.querySelector("body > notice") && notice.list.length === 0){ 159 | document.body.removeChild(notice.wrap); 160 | } 161 | }, 300); 162 | } 163 | }; 164 | 165 | // 灯箱 166 | var image_box = { 167 | img: KStyle.create("img"), 168 | vid: KStyle.create("video"), 169 | prev: KStyle.create("div", {class: "ks-prev"}), 170 | next: KStyle.create("div", {class: "ks-next"}), 171 | ball: KStyle.create("div", {class: "ks-ball"}) 172 | }; 173 | 174 | image_box.wrap = KStyle.create("div", {class: "ks-image", child: [ 175 | image_box.prev, image_box.img, image_box.vid, image_box.next, image_box.ball 176 | ]}); 177 | 178 | image_box.wrap.onclick = function (e) { 179 | image_box.wrap.classList.add("remove"); 180 | 181 | setTimeout(function () { 182 | try{ 183 | document.body.removeChild(image_box.wrap); 184 | image_box.wrap.classList.remove("remove"); 185 | } 186 | catch (err){} 187 | }, 300); 188 | }; 189 | 190 | image_box.img.alt = "灯箱预览"; 191 | image_box.img.onload = function () { 192 | image_box.wrap.classList.remove("loading"); 193 | }; 194 | 195 | image_box.vid.controls = true; 196 | image_box.vid.onclick = function (ev) { 197 | ev.stopPropagation(); 198 | } 199 | image_box.vid.onloadeddata = function () { 200 | image_box.wrap.classList.remove("loading"); 201 | }; 202 | 203 | KStyle.image = function (selector) { 204 | var current = 0; 205 | var get_images = KStyle.selectAll(selector); 206 | 207 | var actions = { 208 | ori: function (obj, num) { 209 | obj.setAttribute("ks-image", "active"); 210 | 211 | obj.onclick = function () { 212 | current = num; 213 | actions.set(); 214 | document.body.appendChild(image_box.wrap); 215 | }; 216 | }, 217 | set: function () { 218 | var img = get_images[current]; 219 | 220 | current === 0 ? image_box.prev.classList.add("ended") : image_box.prev.classList.remove("ended"); 221 | current === get_images.length - 1 ? image_box.next.classList.add("ended") : image_box.next.classList.remove("ended"); 222 | 223 | if(img.getAttribute("ks-original") !== null){ 224 | const _url = img.getAttribute("ks-original"); 225 | 226 | // 视频格式,展示成视频效果 227 | if (_url.includes("mp4")) { 228 | image_box.img.removeAttribute("src"); 229 | image_box.vid.src = _url; 230 | } 231 | else { 232 | image_box.img.src = _url; 233 | image_box.vid.removeAttribute("src"); 234 | } 235 | } 236 | else if(img.src){ 237 | image_box.img.src = img.src; 238 | } 239 | else{ 240 | console.error("This image has no valid tag!"); 241 | } 242 | 243 | image_box.wrap.classList.add("loading"); 244 | } 245 | }; 246 | 247 | KStyle.each(get_images, function (item, id) { 248 | if(item.src || item.getAttribute("ks-original")){ 249 | actions.ori(item, id); 250 | } 251 | }); 252 | 253 | // 设置按钮 254 | image_box.prev.onclick = function (e) { 255 | e.stopPropagation(); 256 | if(current - 1 >= 0) current--; 257 | 258 | actions.set(); 259 | }; 260 | image_box.next.onclick = function (e) { 261 | e.stopPropagation(); 262 | if(current + 1 < get_images.length) current++; 263 | 264 | actions.set(); 265 | }; 266 | }; 267 | 268 | // 懒加载 269 | KStyle.lazy = function (elements, bg) { 270 | //elements = Array.from(KStyle.selectAll(elements)); 271 | elements = KStyle.selectAll(elements); 272 | 273 | var list = []; 274 | 275 | var action = { 276 | setFront: function (item) { 277 | if(item.intersectionRatio > 0) { 278 | item.target.src = item.target.link; 279 | 280 | item.target.onload = function () { 281 | item.target.setAttribute("ks-lazy", "finished"); 282 | } 283 | 284 | obs.unobserve(item.target); 285 | } 286 | }, 287 | setBack: function (item) { 288 | if(item.boundingClientRect.top <= window.innerHeight + 100) { 289 | var img = new Image(); 290 | img.src = item.target.link; 291 | 292 | img.onload = function () { 293 | item.target.setAttribute("ks-lazy", "finished"); 294 | item.target.style.backgroundImage = "url(" + item.target.link + ")"; 295 | }; 296 | 297 | obs.unobserve(item.target); 298 | } 299 | } 300 | }; 301 | 302 | // 是否支持 OBS 303 | if(global.IntersectionObserver){ 304 | var obs = new IntersectionObserver(function (changes) { 305 | if (bg) { 306 | changes.forEach(function (t) { 307 | action.setBack(t); 308 | }); 309 | } 310 | else { 311 | changes.forEach(function (t) { 312 | action.setFront(t); 313 | }); 314 | } 315 | }); 316 | 317 | KStyle.each(elements, function (item) { 318 | item.link = item.getAttribute("ks-thumb") || item.getAttribute("ks-original"); 319 | 320 | if(!item.getAttribute("ks-lazy")) obs.observe(item); 321 | }) 322 | } 323 | else{ 324 | function back() { 325 | KStyle.each(list, function (item) { 326 | var check = item.el.getBoundingClientRect().top <= window.innerHeight; 327 | 328 | if(check && !item.showed){ 329 | action.setBack(item.el); 330 | list.remove(item); 331 | } 332 | }); 333 | } 334 | 335 | function front() { 336 | KStyle.each(list, function (item) { 337 | var check = item.el.getBoundingClientRect().top <= window.innerHeight; 338 | 339 | if(check && !item.showed){ 340 | action.setFront(item.el); 341 | list.remove(item); 342 | } 343 | }); 344 | } 345 | 346 | KStyle.each(elements, function (item) { 347 | item.link = item.getAttribute("ks-thumb") || item.getAttribute("ks-original"); 348 | 349 | if(!item.getAttribute("ks-lazy")) list.push({el: item, link: item.link}); 350 | }); 351 | 352 | bg ? back() : front(); 353 | bg ? document.addEventListener("scroll", back) : document.addEventListener("scroll", front); 354 | } 355 | }; 356 | 357 | // AJAX 358 | KStyle.ajax = function (prop) { 359 | if(!prop.url) prop.url = document.location.href; 360 | if(!prop.method) prop.method = "GET"; 361 | 362 | if(prop.method === "POST"){ 363 | var data = new FormData(); 364 | 365 | for(var d in prop.data){ 366 | data.append(d, prop.data[d]); 367 | } 368 | } 369 | else if(prop.method === "GET"){ 370 | var url = prop.url + "?"; 371 | 372 | for(var d in prop.data){ 373 | url += d + "=" + prop.data[d] + "&"; 374 | } 375 | 376 | prop.url = url.substr(0, url.length - 1); 377 | } 378 | 379 | var request = new XMLHttpRequest(); 380 | request.open(prop.method, prop.url); 381 | if(prop.crossDomain){ request.setRequestHeader("X-Requested-With", "XMLHttpRequest"); } 382 | 383 | if(prop.header){ 384 | for(var i in prop.header){ 385 | request.setRequestHeader(prop.header[i][0], prop.header[i][1]); 386 | } 387 | } 388 | 389 | request.send(data); 390 | 391 | request.onreadystatechange = function () { 392 | if(request.readyState === 4){ 393 | if(request.status === 200 || request.status === 304){ 394 | if(prop.type){ 395 | switch(prop.type){ 396 | case "text": prop.success(request.responseText); break; 397 | case "json": prop.success(JSON.parse(request.response)); break; 398 | } 399 | } 400 | else{ 401 | prop.success ? prop.success(request) : console.log(prop.method + " 请求发送成功"); 402 | } 403 | } 404 | else{ 405 | prop.failed ? prop.failed(request) : console.log(prop.method + " 请求发送失败"); 406 | } 407 | 408 | request = null; 409 | } 410 | }; 411 | 412 | return request; 413 | }; 414 | 415 | // 平滑滚动 416 | KStyle.scrollTo = function (el, offset) { 417 | el = KStyle.selectAll(el); 418 | 419 | el.forEach(function (t) { 420 | t.onclick = function (e) { 421 | var l = e.target.pathname; 422 | var c = window.location.pathname; 423 | 424 | var t = e.target.href.match(/#[\s\S]+/); 425 | if(t) t = ks.select(t[0]); 426 | 427 | if(c === l){ 428 | e.preventDefault(); 429 | 430 | var top = t ? (offset ? t.offsetTop - offset : t.offsetTop) : 0; 431 | 432 | "scrollBehavior" in document.documentElement.style ? global.scrollTo({top: top, left: 0, behavior: "smooth"}) : global.scrollTo(0, top); 433 | } 434 | else{ 435 | console.log(c, l); 436 | } 437 | } 438 | }) 439 | }; 440 | 441 | global.ks = KStyle; 442 | 443 | console.log("%c Kico Style %c https://paugram.com ","color: #fff; margin: 1em 0; padding: 5px 0; background: #3498db;","margin: 1em 0; padding: 5px 0; background: #efefef;"); 444 | })(window); -------------------------------------------------------------------------------- /kico.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | 3 | /* ---- 4 | 5 | # Kico Style 1.0 6 | # By: Dreamer-Paul 7 | # Last Update: 2023.4.14 8 | 9 | 一个可口的极简响应式前端框架。 10 | 11 | 本代码为奇趣保罗原创,并遵守 MIT 开源协议。欢迎访问我的博客:https://paugram.com 12 | 13 | ---- */ 14 | 15 | /* 0 - 全局 16 | -------------------------------- */ 17 | body, dl, dt, dd, ol, ul, 18 | h1, h2, h3, h4, h5, h6, p, 19 | pre, code, form, 20 | fieldset, legend, figure{ 21 | margin: 0; 22 | padding: 0; 23 | } 24 | 25 | *, *:before, *:after{ box-sizing: border-box } 26 | 27 | :root{ 28 | /* 内设配色方案 */ 29 | --red: #ea644a; 30 | --red-color: #fff; 31 | 32 | --yellow: #ffb03a; 33 | --yellow-color: #fff; 34 | 35 | --blue: #3498db; 36 | --blue-color: #fff; 37 | 38 | --green: #27a17e; 39 | --green-color: #fff; 40 | 41 | --primary: var(--blue); 42 | --primary-color: var(--blue-color); 43 | 44 | --secondly: var(--yellow); 45 | --secondly-color: var(--yellow-color); 46 | 47 | --gray: #ccc; 48 | --light-gray: #ddd; 49 | --lighter-gray: #eee; 50 | 51 | /* 容器 */ 52 | --wrapper-width: 75em; 53 | --wrapper-gap: 1.25em; 54 | 55 | /* 边框 */ 56 | --radius: .5em; 57 | --border-color: transparent; 58 | --border-width: 1px; 59 | 60 | /* 间距 */ 61 | --row-gap: 2em; 62 | } 63 | 64 | :root{ 65 | color: #353535; 66 | -webkit-text-size-adjust: 100%; 67 | -webkit-tap-highlight-color: transparent; 68 | font: 16px/1.5 'Microsoft Yahei', 'PingFang SC', 'Hiragino Sans GB', sans-serif; 69 | } 70 | 71 | @media screen and (max-width: 768px){ 72 | :root.font-auto{ font-size: 14px } 73 | } 74 | 75 | @media screen and (min-width: 1921px){ 76 | :root.font-auto{ font-size: 18px } 77 | } 78 | 79 | @media (prefers-reduced-motion: no-preference){ 80 | :root{ scroll-behavior: smooth } 81 | } 82 | 83 | /* - 选择内容 */ 84 | ::-moz-selection{ 85 | color: #fff; 86 | background-color: rgba(0, 0, 0, .66); 87 | } 88 | 89 | ::selection{ 90 | color: #fff; 91 | background-color: rgba(0, 0, 0, .66); 92 | } 93 | 94 | /* - 滚动条 */ 95 | ::-webkit-scrollbar{ 96 | width: 10px; 97 | height: 10px; 98 | } 99 | 100 | ::-webkit-scrollbar-thumb{ 101 | background: #ccc; 102 | background: var(--gray); 103 | border-radius: 5px; 104 | } 105 | ::-webkit-scrollbar-track{ border-radius: 5px } 106 | ::-webkit-scrollbar-track:hover{ background: rgba(0, 0, 0, .05) } 107 | 108 | body::-webkit-scrollbar-track{ border-radius: 0 } 109 | 110 | /* - 辅助类 */ 111 | .float-none{ float: none !important } 112 | .float-left{ float: left !important } 113 | .float-right{ float: right !important } 114 | 115 | .clearfix:after{ 116 | content: ''; 117 | clear: both; 118 | display: block; 119 | } 120 | 121 | .font-s{ font-size: .875em } 122 | .font-m{ font-size: 1.125em } 123 | .font-l{ font-size: 1.25em } 124 | 125 | .text-left{ text-align: left !important } 126 | .text-right{ text-align: right !important } 127 | .text-center{ text-align: center !important } 128 | .text-justify{ text-align: justify !important } 129 | 130 | .text-break{ word-break: break-all !important } 131 | .text-nowrap{ white-space: nowrap !important } 132 | .text-ellipsis{ 133 | overflow: hidden; 134 | white-space: nowrap; 135 | text-overflow: ellipsis; 136 | } 137 | 138 | /* 1 - 容器 139 | -------------------------------- */ 140 | .wrap{ 141 | margin: 0 auto; 142 | padding: 0 var(--wrapper-gap); 143 | max-width: var(--wrapper-width); 144 | box-sizing: content-box; 145 | } 146 | 147 | .wrap.min{ max-width: 50em } 148 | .wrap.mid{ max-width: 65em } 149 | .wrap.max{ max-width: 85em } 150 | .wrap.full{ max-width: 100% } 151 | 152 | .wrap.thin{ padding: 0 .75em } 153 | .wrap.thick{ padding: 0 1.5em } 154 | .wrap.clear{ 155 | padding-left: 0; 156 | padding-right: 0; 157 | } 158 | 159 | /* 2 - 元素 160 | -------------------------------- */ 161 | h1{ font-size: 2em } 162 | 163 | h1, h2, h3, h4, h5, h6{ margin-bottom: 1rem } 164 | 165 | h1:last-child, h2:last-child, h3:last-child, h4:last-child, h5:last-child, h6:last-child, p:last-child{ margin-bottom: 0 } 166 | 167 | p{ 168 | line-height: 1.8; 169 | margin-bottom: 1em; 170 | } 171 | 172 | a{ 173 | color: #3498db; 174 | color: var(--primary); 175 | text-decoration: none; 176 | } 177 | 178 | a:hover{ 179 | color: #ffc670; 180 | color: var(--secondly); 181 | } 182 | 183 | abbr[title]{ 184 | cursor: help; 185 | text-decoration: none; 186 | border-bottom: 1px dotted; 187 | } 188 | 189 | em, mark, kbd{ 190 | font-size: .875em; 191 | padding: .25em .5em; 192 | border-radius: var(--radius); 193 | } 194 | 195 | em{ 196 | color: var(--primary-color); 197 | font-style: normal; 198 | background-color: var(--primary); 199 | } 200 | em.red{ 201 | color: var(--red-color); 202 | background: var(--red); 203 | } 204 | em.yellow{ 205 | color: var(--yellow-color); 206 | background: var(--yellow); 207 | } 208 | em.blue{ 209 | color: var(--blue-color); 210 | background: var(--blue); 211 | } 212 | em.green{ 213 | color: var(--green-color); 214 | background: var(--green); 215 | } 216 | 217 | kbd{ 218 | color: #fff; 219 | background: #333; 220 | font-family: 'Consolas', 'Courier New', monospace, "微软雅黑"; 221 | } 222 | 223 | img, svg, audio, video, iframe{ 224 | max-width: 100%; 225 | vertical-align: middle; 226 | } 227 | 228 | /* - 文章 */ 229 | article{ 230 | letter-spacing: .03em; 231 | } 232 | 233 | article a{ 234 | word-break: break-all; 235 | } 236 | 237 | article > *{ margin-bottom: 1em } 238 | article > *:last-child{ margin-bottom: 0 } 239 | 240 | article h1, article h2, article h3{ font-size: 1.2em } 241 | article h4, article h5, article h6{ font-size: 1.1em } 242 | 243 | article ul, article ol, article dl{ line-height: 1.8 } 244 | 245 | /* - 按钮 */ 246 | button{ 247 | margin: 0; 248 | outline: 0; 249 | font: inherit; 250 | } 251 | 252 | .btn{ 253 | color: inherit; 254 | cursor: pointer; 255 | background: #fff; 256 | padding: .5em 1em; 257 | display: inline-block; 258 | border-radius: var(--radius); 259 | border: var(--border-width) solid var(--border-color); 260 | } 261 | .btn:hover{ color: inherit } 262 | 263 | /* -- 禁用的按钮 */ 264 | .btn[disabled]{ 265 | opacity: .5; 266 | cursor: not-allowed; 267 | } 268 | 269 | /* -- 按钮尺寸 */ 270 | .btn.small{ font-size: .875em } 271 | .btn.middle, .btn.large{ padding: .75em 1.5em } 272 | .btn.large{ font-size: 1.2em } 273 | 274 | /* -- 按钮颜色 */ 275 | .btn.red{ 276 | color: var(--red-color); 277 | background-color: var(--red); 278 | } 279 | .btn.yellow{ 280 | color: var(--yellow-color); 281 | background-color: var(--yellow); 282 | } 283 | .btn.blue{ 284 | color: var(--blue-color); 285 | background-color: var(--blue); 286 | } 287 | .btn.green{ 288 | color: var(--green-color); 289 | background-color: var(--green); 290 | } 291 | .btn.primary{ 292 | color: var(--primary-color); 293 | background-color: var(--primary); 294 | } 295 | .btn.secondly{ 296 | color: var(--secondly-color); 297 | background-color: var(--secondly); 298 | } 299 | .btn.transparent{ background-color: transparent } 300 | 301 | /* - 代码 */ 302 | pre, code{ 303 | word-break: normal; 304 | font-family: 'Consolas', 'Courier New', monospace; 305 | } 306 | 307 | pre{ 308 | tab-size: 4; 309 | padding: 1em; 310 | color: #fff; 311 | overflow: auto; 312 | background-color: #333; 313 | border-radius: var(--radius); 314 | } 315 | 316 | :not(pre) > code{ 317 | color: #c40b00; 318 | font-size: 85%; 319 | word-wrap: normal; 320 | border-radius: var(--radius); 321 | padding: .25em .5em; 322 | word-break: break-all; 323 | background-color: #f7f2f4; 324 | } 325 | 326 | /* - 项目列表 */ 327 | ul, ol{ margin-left: 1.25em } 328 | ul.clear, ol.clear{ 329 | margin-left: 0; 330 | list-style: none; 331 | } 332 | 333 | dl dd{ margin-left: 1.5em } 334 | dl dd:before{ 335 | content: "--"; 336 | margin-right: .25em; 337 | } 338 | 339 | /* - 补间动画 */ 340 | a, .btn{ transition: color .3s, background-color .3s } 341 | 342 | /* - 引用 */ 343 | blockquote{ 344 | margin: 0 0 1em; 345 | line-height: 1.8; 346 | font-style: oblique; 347 | background: #f5fafd; 348 | padding: 1em 1em 1em 2em; 349 | border-left: 5px #3498db solid; 350 | } 351 | 352 | cite{ 353 | color: var(--primary); 354 | font-style: normal; 355 | } 356 | 357 | /* - 分割线 */ 358 | hr{ 359 | border: 0; 360 | margin: 1.5em 0; 361 | border-top: var(--border-width) var(--gray) solid; 362 | } 363 | 364 | /* - 表单 */ 365 | input[disabled], textarea[disabled]{ 366 | cursor: no-drop !important; 367 | } 368 | 369 | input, select, textarea{ 370 | margin: 0; 371 | outline: none; 372 | font: inherit; 373 | max-width: 100%; 374 | background: none; 375 | vertical-align: middle; 376 | } 377 | 378 | input[type*="date"], input[type="email"], input[type="month"], input[type="number"], input[type="password"], input[type="search"], input[type="tel"], input[type="text"], input[type="time"], input[type="url"], input[type="week"], 379 | select, textarea{ 380 | padding: .5em; 381 | color: inherit; 382 | border-radius: var(--radius); 383 | border: var(--border-width) var(--gray) solid; 384 | /* 旧版本浏览器可能部分输入框会塌陷 */ 385 | min-height: calc(2.5em + calc(var(--border-width) * 2)); 386 | -webkit-appearance: none; 387 | -moz-appearance: none; 388 | appearance: none; 389 | } 390 | 391 | input.invalid, input:out-of-range{ 392 | border-color: #c40b00; 393 | background: rgba(255, 0, 0, .1); 394 | } 395 | 396 | input[type="file"]:not([hidden]){ 397 | display: flex; 398 | align-items: center; 399 | } 400 | 401 | input[type="file"]::-webkit-file-upload-button{ 402 | color: #fff; 403 | border: none; 404 | outline: none; 405 | padding: .5em 1em; 406 | font-size: inherit; 407 | margin-right: .5em; 408 | display: inline-block; 409 | border-radius: var(--radius); 410 | background-color: var(--primary); 411 | } 412 | 413 | input[type="color"]{ 414 | width: 3em !important; 415 | height: 3em !important; 416 | border: none; 417 | padding: 0; 418 | } 419 | 420 | input[type="color"]::-webkit-color-swatch-wrapper{ 421 | padding: 0; 422 | } 423 | 424 | input[type="color"]::-moz-color-swatch{ 425 | border: none; 426 | } 427 | 428 | input[type="color"]::-webkit-color-swatch{ 429 | border: none; 430 | border-radius: var(--radius); 431 | } 432 | 433 | input[type="range"]{ 434 | margin: 0; 435 | height: 100%; 436 | -webkit-appearance: none; 437 | -moz-appearance: none; 438 | cursor: ew-resize; 439 | cursor: grab; 440 | overflow: hidden; 441 | min-height: 1.5rem; 442 | } 443 | 444 | input[type="range"]:focus{ 445 | outline: none; 446 | box-shadow: none; 447 | } 448 | 449 | input[type="range"]:active::-webkit-slider-thumb{ 450 | border-color: var(--primary); 451 | background-color: var(--primary); 452 | } 453 | 454 | input[type="range"]:active::-moz-range-thumb{ 455 | border-color: var(--primary); 456 | background-color: var(--primary); 457 | } 458 | 459 | input[type="range"]:focus::-ms-thumb{ 460 | border-color: var(--primary); 461 | background-color: var(--primary); 462 | } 463 | 464 | input[type="range"]::-moz-focus-outer{ border: 0 } 465 | 466 | input[type="range"]::-webkit-slider-runnable-track{ 467 | content: ''; 468 | height: calc(var(--border-width) * 2); 469 | pointer-events: none; 470 | background-color: var(--primary); 471 | } 472 | 473 | input[type="range"]::-webkit-slider-thumb{ 474 | width: 1em; 475 | height: 1em; 476 | -webkit-appearance: none; 477 | appearance: none; 478 | background: #fff; 479 | border-radius: 5em; 480 | margin-top: calc(-.5em + var(--border-width)); 481 | border: var(--border-width) solid rgba(0, 0, 0, .15); 482 | transition: .3s border-color, .3s background-color; 483 | } 484 | 485 | input[type="range"]::-moz-range-track{ 486 | height: 2px; 487 | background: rgba(0, 50, 126, .12); 488 | } 489 | 490 | input[type="range"]::-moz-range-thumb{ 491 | width: 1em; 492 | height: 1em; 493 | background: #fff; 494 | border-radius: 5em; 495 | margin-top: calc(-.5em + var(--border-width)); 496 | border: var(--border-width) solid rgba(0, 0, 0, .15); 497 | transition: .3s border-color, .3s background-color; 498 | } 499 | 500 | input[type="range"]::-moz-range-progress{ 501 | border: 0; 502 | height: 2px; 503 | margin-top: 0; 504 | background-color: var(--primary); 505 | } 506 | 507 | select{ 508 | -webkit-appearance: none; 509 | appearance: none; 510 | padding-right: 1.75em; 511 | background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 5'%3E%3Cpath fill='none' stroke='%23333' stroke-linecap='round' stroke-linejoin='round' d='M.5.5l4.5 4 4.5-4'/%3E%3C/svg%3E") right .5rem center/.75em no-repeat; 512 | } 513 | 514 | select[multiple], select[size]:not([size="1"]){ 515 | background: none; 516 | } 517 | 518 | textarea{ 519 | display: block; 520 | overflow: auto; 521 | resize: vertical; 522 | } 523 | 524 | progress{ 525 | overflow: auto; 526 | border-radius: 50px; 527 | } 528 | 529 | progress::-webkit-progress-bar{ 530 | background-color: #eee; 531 | } 532 | 533 | /* - 表单模组 */ 534 | 535 | /* -- 单选多选框 */ 536 | input[type="checkbox"], input[type="radio"]{ 537 | float: left; 538 | width: 1.5em; 539 | height: 1.5em; 540 | cursor: pointer; 541 | position: relative; 542 | margin: 0 .5em 0 0; 543 | -moz-appearance: none; 544 | -webkit-appearance: none; 545 | } 546 | 547 | input[type="checkbox"]:before, input[type="radio"]:before{ 548 | content: ''; 549 | width: 100%; 550 | height: 100%; 551 | display: block; 552 | box-shadow: 0 0 0 var(--border-width) var(--gray) inset; 553 | transition: background-color .3s, box-shadow .3s; 554 | } 555 | 556 | input[type="checkbox"]:after{ 557 | top: 10%; 558 | left: 10%; 559 | width: 30%; 560 | height: 60%; 561 | content: ''; 562 | position: absolute; 563 | transition: transform .3s; 564 | transform-origin: 100% 100%; 565 | border-right: .15em solid #fff; 566 | border-bottom: .15em solid #fff; 567 | transform: rotate(45deg) scale(0); 568 | } 569 | 570 | input[type="radio"], input[type="radio"]:before{ border-radius: 100% } 571 | input[type="checkbox"], input[type="checkbox"]:before{ border-radius: .2em } 572 | 573 | input[type="radio"]:checked:before{ 574 | background-color: var(--primary); 575 | border: var(--border-width) solid var(--primary); 576 | box-shadow: 0 0 0 .2em #fff inset; 577 | } 578 | 579 | input[type="checkbox"]:checked:before{ 580 | box-shadow: none; 581 | background-color: var(--primary); 582 | } 583 | 584 | input[type="checkbox"]:checked:after{ 585 | transform: rotate(45deg) scale(1); 586 | } 587 | 588 | /* -- 开关按钮 */ 589 | input[type="checkbox"].switch{ 590 | width: 4em; 591 | height: 2em; 592 | float: none; 593 | cursor: pointer; 594 | position: relative; 595 | box-sizing: content-box; 596 | border-radius: calc(var(--radius) * 10); 597 | border: var(--border-width) solid var(--gray); 598 | background-color: var(--lighter-gray); 599 | transition: border .3s, background-color .3s; 600 | } 601 | 602 | input[type="checkbox"].switch:before{ 603 | margin: 0; 604 | border: 0; 605 | width: 2em; 606 | height: 2em; 607 | content: ''; 608 | display: block; 609 | box-shadow: none; 610 | background: #fff; 611 | position: absolute; 612 | transition: transform .3s; 613 | border-radius: calc(var(--radius) * 10); 614 | } 615 | 616 | input[type="checkbox"].switch:after{ content: normal } 617 | 618 | input[type="checkbox"].switch:checked{ 619 | box-shadow: none; 620 | border-color: var(--primary); 621 | background-color: var(--primary); 622 | } 623 | 624 | input.switch:checked:before{ 625 | background: #fff; 626 | transform: translateX(2em); 627 | } 628 | 629 | /* - 表单小组 */ 630 | fieldset{ 631 | border: none; 632 | margin-bottom: 2em; 633 | } 634 | 635 | fieldset > *{ margin-bottom: 1em } 636 | fieldset:last-child{ margin-bottom: 0 } 637 | 638 | fieldset legend{ margin: 0 0 1em } 639 | 640 | fieldset input:not([type="checkbox"]):not([type="radio"]), fieldset select, fieldset textarea{ width: 100% } 641 | 642 | /* -- 控件模块 */ 643 | fieldset label{ 644 | display: block; 645 | user-select: none; 646 | } 647 | 648 | /* -- 控件标题 */ 649 | fieldset label > span:first-child{ 650 | opacity: .6; 651 | font-size: .875em; 652 | white-space: nowrap; 653 | margin-bottom: .5rem; 654 | display: inline-block; 655 | } 656 | 657 | fieldset label.required > span:first-child:after{ 658 | color: red; 659 | content: "*"; 660 | margin-left: .25em; 661 | } 662 | 663 | /* -- 单行表单 */ 664 | form .inline label, fieldset.inline label{ 665 | display: inline-block; 666 | vertical-align: bottom; 667 | margin: 0 .75em .75em 0; 668 | } 669 | 670 | /* - 表格 */ 671 | .ks-table{ 672 | width: 100%; 673 | overflow-x: auto; 674 | overflow-y: hidden; 675 | border-radius: var(--radius); 676 | } 677 | 678 | table{ 679 | border: 0; 680 | width: 100%; 681 | max-width: 100%; 682 | caption-side: bottom; 683 | border-collapse: collapse; 684 | } 685 | 686 | th:not([align]){ 687 | text-align: inherit; 688 | text-align: -webkit-match-parent; 689 | } 690 | 691 | th, td{ padding: .75em } 692 | 693 | table thead tr{ 694 | border-bottom: min(2px, calc(var(--border-width) * 2)) solid var(--gray); 695 | border-bottom-color: var(--gray); 696 | } 697 | table tbody tr{ 698 | border-bottom: var(--border-width) solid var(--light-gray); 699 | transition: border-color .3s, background-color .3s; 700 | } 701 | table tbody tr:last-child{ border-bottom: 0 } 702 | 703 | table tbody tr:hover{ background-color: var(--lighter-gray) } 704 | 705 | /* - 蓝色风格 */ 706 | table.fill thead{ 707 | background-color: var(--primary); 708 | border-bottom: none; 709 | } 710 | table.fill thead tr{ 711 | border-bottom: none; 712 | } 713 | table.fill thead th, table.fill thead td{ 714 | color: #fff; 715 | } 716 | 717 | table.fill tbody tr{ 718 | border-bottom: none; 719 | } 720 | 721 | table.fill tbody tr:nth-child(even) th, table.fill tbody tr:nth-child(even){ 722 | background-color: #f7f7f7; 723 | } 724 | 725 | /* - 嵌入式网页 */ 726 | iframe{ 727 | border: none; 728 | } 729 | 730 | /* - 栅格系统 */ 731 | .row{ 732 | display: flex; 733 | flex-wrap: wrap; 734 | row-gap: var(--row-gap); 735 | margin: 0 calc(var(--row-gap) / 2 * -1); 736 | } 737 | 738 | .row.s{ 739 | row-gap: 1em; 740 | margin: 0 -.5em; 741 | } 742 | .row.m{ 743 | row-gap: 2.5em; 744 | margin: 0 -1.25em; 745 | } 746 | .row.l{ 747 | row-gap: 3em; 748 | margin: 0 -1.5em; 749 | } 750 | 751 | .row.full{ 752 | row-gap: 0; 753 | margin: 0; 754 | } 755 | 756 | /* -- 对齐方式 */ 757 | .row.right{ justify-content: flex-end; } 758 | .row.center{ justify-content: center; } 759 | .row.around{ justify-content: space-around; } 760 | .row.between{ justify-content: space-between; } 761 | 762 | /* -- 网格间距 */ 763 | .row > [class*="col-"]{ 764 | flex: 0 0 100%; 765 | padding: 0 calc(var(--row-gap) / 2); 766 | max-width: 100%; 767 | } 768 | 769 | .row.s > [class*="col-"]{ 770 | padding: 0 .5em; 771 | } 772 | .row.m > [class*="col-"]{ 773 | padding: 0 1.25em; 774 | } 775 | .row.l > [class*="col-"]{ 776 | padding: 0 1.5em; 777 | } 778 | .row.full > [class*="col-"]{ 779 | padding: 0; 780 | } 781 | 782 | /* -- 自适应间距栅格 */ 783 | @media screen and (max-width: 600px){ 784 | .row.auto{ 785 | row-gap: 1em; 786 | margin: 0 -.5em; 787 | } 788 | 789 | .row.auto > [class*="col-"]{ 790 | padding: 0 .5em; 791 | } 792 | } 793 | 794 | @media screen and (min-width: 1920px){ 795 | .row.auto{ 796 | row-gap: 2.5em; 797 | margin: 0 -1.25em; 798 | } 799 | 800 | .row.auto > [class*="col-"]{ 801 | padding: 0 1.25em; 802 | } 803 | } 804 | 805 | /* -- 栅格主体 */ 806 | .row .col-auto{ 807 | flex: 1 1 auto; 808 | max-width: 100%; 809 | } 810 | 811 | .row .col-1{ 812 | flex: 0 0 8.3333%; 813 | max-width: 8.3333%; 814 | } 815 | 816 | .row .col-2{ 817 | flex: 0 0 16.6666%; 818 | max-width: 16.6666%; 819 | } 820 | 821 | .row .col-3{ 822 | flex: 0 0 25%; 823 | max-width: 25%; 824 | } 825 | 826 | .row .col-4{ 827 | flex: 0 0 33.3333%; 828 | max-width: 33.3333%; 829 | } 830 | 831 | .row .col-5{ 832 | flex: 0 0 41.6666%; 833 | max-width: 41.6666%; 834 | } 835 | 836 | .row .col-6{ 837 | flex: 0 0 50%; 838 | max-width: 50%; 839 | } 840 | 841 | .row .col-7{ 842 | flex: 0 0 58.3333%; 843 | max-width: 58.3333%; 844 | } 845 | 846 | .row .col-8{ 847 | flex: 0 0 66.6666%; 848 | max-width: 66.6666%; 849 | } 850 | 851 | .row .col-9{ 852 | flex: 0 0 75%; 853 | max-width: 75%; 854 | } 855 | 856 | .row .col-10{ 857 | flex: 0 0 83.3333%; 858 | max-width: 83.3333%; 859 | } 860 | 861 | .row .col-11{ 862 | flex: 0 0 91.6666%; 863 | max-width: 91.6666%; 864 | } 865 | 866 | .row .col-12{ 867 | flex: 0 0 100%; 868 | max-width: 100%; 869 | } 870 | 871 | /* --- 手机 */ 872 | @media screen and (min-width: 600px){ 873 | .row .col-s-auto{ 874 | flex: 1 1 auto; 875 | max-width: 100%; 876 | } 877 | 878 | .row .col-s-1{ 879 | flex: 0 0 8.3333%; 880 | max-width: 8.3333%; 881 | } 882 | 883 | .row .col-s-2{ 884 | flex: 0 0 16.6666%; 885 | max-width: 16.6666%; 886 | } 887 | 888 | .row .col-s-3{ 889 | flex: 0 0 25%; 890 | max-width: 25%; 891 | } 892 | 893 | .row .col-s-4{ 894 | flex: 0 0 33.3333%; 895 | max-width: 33.3333%; 896 | } 897 | 898 | .row .col-s-5{ 899 | flex: 0 0 41.6666%; 900 | max-width: 41.6666%; 901 | } 902 | 903 | .row .col-s-6{ 904 | flex: 0 0 50%; 905 | max-width: 50%; 906 | } 907 | 908 | .row .col-s-7{ 909 | flex: 0 0 58.3333%; 910 | max-width: 58.3333%; 911 | } 912 | 913 | .row .col-s-8{ 914 | flex: 0 0 66.6666%; 915 | max-width: 66.6666%; 916 | } 917 | 918 | .row .col-s-9{ 919 | flex: 0 0 75%; 920 | max-width: 75%; 921 | } 922 | 923 | .row .col-s-10{ 924 | flex: 0 0 83.3333%; 925 | max-width: 83.3333%; 926 | } 927 | 928 | .row .col-s-11{ 929 | flex: 0 0 91.6666%; 930 | max-width: 91.6666%; 931 | } 932 | 933 | .row .col-s-12{ 934 | flex: 0 0 100%; 935 | max-width: 100%; 936 | } 937 | } 938 | 939 | /* --- 平板 */ 940 | @media screen and (min-width: 900px){ 941 | .row .col-m-auto{ 942 | flex: 1 1 auto; 943 | max-width: 100%; 944 | } 945 | 946 | .row .col-m-1{ 947 | flex: 0 0 8.3333%; 948 | max-width: 8.3333%; 949 | } 950 | 951 | .row .col-m-2{ 952 | flex: 0 0 16.6666%; 953 | max-width: 16.6666%; 954 | } 955 | 956 | .row .col-m-3{ 957 | flex: 0 0 25%; 958 | max-width: 25%; 959 | } 960 | 961 | .row .col-m-4{ 962 | flex: 0 0 33.3333%; 963 | max-width: 33.3333%; 964 | } 965 | 966 | .row .col-m-5{ 967 | flex: 0 0 41.6666%; 968 | max-width: 41.6666%; 969 | } 970 | 971 | .row .col-m-6{ 972 | flex: 0 0 50%; 973 | max-width: 50%; 974 | } 975 | 976 | .row .col-m-7{ 977 | flex: 0 0 58.3333%; 978 | max-width: 58.3333%; 979 | } 980 | 981 | .row .col-m-8{ 982 | flex: 0 0 66.6666%; 983 | max-width: 66.6666%; 984 | } 985 | 986 | .row .col-m-9{ 987 | flex: 0 0 75%; 988 | max-width: 75%; 989 | } 990 | 991 | .row .col-m-10{ 992 | flex: 0 0 83.3333%; 993 | max-width: 83.3333%; 994 | } 995 | 996 | .row .col-m-11{ 997 | flex: 0 0 91.6666%; 998 | max-width: 91.6666%; 999 | } 1000 | 1001 | .row .col-m-12{ 1002 | flex: 0 0 100%; 1003 | max-width: 100%; 1004 | } 1005 | } 1006 | 1007 | /* --- 电脑 */ 1008 | @media screen and (min-width: 1024px){ 1009 | .row .col-l-auto{ 1010 | flex: 1 1 auto; 1011 | max-width: 100%; 1012 | } 1013 | 1014 | .row .col-l-1{ 1015 | flex: 0 0 8.3333%; 1016 | max-width: 8.3333%; 1017 | } 1018 | 1019 | .row .col-l-2{ 1020 | flex: 0 0 16.6666%; 1021 | max-width: 16.6666%; 1022 | } 1023 | 1024 | .row .col-l-3{ 1025 | flex: 0 0 25%; 1026 | max-width: 25%; 1027 | } 1028 | 1029 | .row .col-l-4{ 1030 | flex: 0 0 33.3333%; 1031 | max-width: 33.3333%; 1032 | } 1033 | 1034 | .row .col-l-5{ 1035 | flex: 0 0 41.6666%; 1036 | max-width: 41.6666%; 1037 | } 1038 | 1039 | .row .col-l-6{ 1040 | flex: 0 0 50%; 1041 | max-width: 50%; 1042 | } 1043 | 1044 | .row .col-l-7{ 1045 | flex: 0 0 58.3333%; 1046 | max-width: 58.3333%; 1047 | } 1048 | 1049 | .row .col-l-8{ 1050 | flex: 0 0 66.6666%; 1051 | max-width: 66.6666%; 1052 | } 1053 | 1054 | .row .col-l-9{ 1055 | flex: 0 0 75%; 1056 | max-width: 75%; 1057 | } 1058 | 1059 | .row .col-l-10{ 1060 | flex: 0 0 83.3333%; 1061 | max-width: 83.3333%; 1062 | } 1063 | 1064 | .row .col-l-11{ 1065 | flex: 0 0 91.6666%; 1066 | max-width: 91.6666%; 1067 | } 1068 | 1069 | .row .col-l-12{ 1070 | flex: 0 0 100%; 1071 | max-width: 100%; 1072 | } 1073 | } 1074 | 1075 | /* -- 网格对齐方式 */ 1076 | .row > .left, .row > .right, .row > .top, .row > .bottom, .row > .center{ 1077 | display: flex; 1078 | flex-direction: column; 1079 | } 1080 | 1081 | .row > .center{ 1082 | align-items: center; 1083 | justify-content: center; 1084 | } 1085 | 1086 | .row > .center-fixed{ 1087 | text-align: center; 1088 | } 1089 | 1090 | .row > .left{ 1091 | -webkit-box-align: start; 1092 | align-items: flex-start; 1093 | } 1094 | 1095 | .row > .right{ 1096 | -webkit-box-align: end; 1097 | align-items: flex-end; 1098 | } 1099 | 1100 | .row > .top{ 1101 | justify-content: flex-start; 1102 | } 1103 | 1104 | .row > .bottom{ 1105 | justify-content: flex-end; 1106 | } 1107 | 1108 | @media screen and (max-width: 900px){ 1109 | .row > .to-center{ 1110 | align-items: center !important; 1111 | } 1112 | } 1113 | 1114 | /* - 隐藏栅格功能 */ 1115 | @media screen and (max-width: 600px){ 1116 | .row > .hide-s{ display: none; } 1117 | } 1118 | 1119 | @media screen and (max-width: 900px){ 1120 | .row > .hide-m{ display: none; } 1121 | } 1122 | 1123 | @media screen and (max-width: 1024px){ 1124 | .row > .hide-l{ display: none; } 1125 | } 1126 | 1127 | /* 4 - 动画 1128 | -------------------------------- */ 1129 | 1130 | /* - 淡入淡出 */ 1131 | @keyframes fade-in{ from{ opacity: 0 } to{ opacity: 1 } } 1132 | @-webkit-keyframes fade-in{ from{ opacity: 0 } to{ opacity: 1 } } 1133 | 1134 | @keyframes fade-off{ from{ opacity: 1 } to{ opacity: 0 } } 1135 | @-webkit-keyframes fade-off{ from{ opacity: 1 } to{ opacity: 0 } } 1136 | 1137 | @keyframes fade-in-top{ from{ opacity: 0; transform: translateY(20px) } to{ opacity: 1; transform: translateY(0) } } 1138 | @-webkit-keyframes fade-in-top{ from{ opacity: 0; transform: translateY(20px) } to{ opacity: 1; transform: translateY(0) } } 1139 | 1140 | @keyframes fade-in-bottom{ from{ opacity: 0; transform: translateY(-20px) } to{ opacity: 1; transform: translateY(0) } } 1141 | @-webkit-keyframes fade-in-bottom{ from{ opacity: 0; transform: translateY(-20px) } to{ opacity: 1; transform: translateY(0) } } 1142 | 1143 | @keyframes fade-in-left{ from{ opacity: 0; transform: translateX(20px) } to{ opacity: 1; transform: translateX(0) } } 1144 | @-webkit-keyframes fade-in-left{ from{ opacity: 0; transform: translateX(20px) } to{ opacity: 1; transform: translateX(0) } } 1145 | 1146 | @keyframes fade-in-right{ from{ opacity: 0; transform: translateX(-20px) } to{ opacity: 1; transform: translateX(0) } } 1147 | @-webkit-keyframes fade-in-right{ from{ opacity: 0; transform: translateX(-20px) } to{ opacity: 1; transform: translateX(0) } } 1148 | 1149 | /* - 淡入缩放 */ 1150 | @keyframes fade-small-large{ from{ opacity: 0; transform: scale(.5, .5) } to{ opacity: 1; transform: scale(1, 1) } } 1151 | @-webkit-keyframes fade-small-large{ from{ opacity: 0; transform: scale(.5, .5) } to{ opacity: 1; transform: scale(1, 1) } } 1152 | 1153 | @keyframes fade-large-small{ from{ opacity: 1; transform: scale(1, 1) } to{ opacity: 0; transform: scale(.5, .5) } } 1154 | @-webkit-keyframes fade-large-small{ from{ opacity: 1; transform: scale(1, 1) } to{ opacity: 0; transform: scale(.5, .5) } } 1155 | 1156 | @keyframes fade-larger-small{ from{ opacity: 0; transform: scale(1.5, 1.5) } to{ opacity: 1; transform: scale(1, 1) } } 1157 | @-webkit-keyframes fade-larger-small{ from{ opacity: 0; transform: scale(1.5, 1.5) } to{ opacity: 1; transform: scale(1, 1) } } 1158 | 1159 | @keyframes fade-small-larger{ from{ opacity: 1; transform: scale(1, 1) } to{ opacity: 0; transform: scale(1.5, 1.5) } } 1160 | @-webkit-keyframes fade-small-larger{ from{ opacity: 1; transform: scale(1, 1) } to{ opacity: 0; transform: scale(1.5, 1.5) } } 1161 | 1162 | @keyframes scale-small-large{ from{ transform: scale(0, 0) } to{ transform: scale(1, 1) } } 1163 | @-webkit-keyframes scale-small-large{ from{ transform: scale(0, 0) } to{ transform: scale(1, 1) } } 1164 | 1165 | @keyframes scale-large-small{ from{ transform: scale(1, 1) } to{ transform: scale(0, 0) } } 1166 | @-webkit-keyframes scale-large-small{ from{ transform: scale(1, 1) } to{ transform: scale(0, 0) } } 1167 | 1168 | /* - 平移 */ 1169 | @keyframes up-and-down{ from{ transform: translateY(-20px) } to{ transform: translateY(20px) } } 1170 | @-webkit-keyframes up-and-down{ from{ transform: translateY(-20px) } to{ transform: translateY(20px) } } 1171 | 1172 | @keyframes left-and-right{ from{ transform: translateX(-20px) } to{ transform: translateX(20px) } } 1173 | @-webkit-keyframes left-and-right{ from{ transform: translateX(-20px) } to{ transform: translateX(20px) } } 1174 | 1175 | /* - 旋转 */ 1176 | @keyframes rotate{ from{ transform: rotate(0deg) } to{ transform: rotate(360deg) } } 1177 | @-webkit-keyframes rotate{ from{ transform: rotate(0deg) } to{ transform: rotate(360deg) } } 1178 | 1179 | /* - 弹跳 */ 1180 | @keyframes jump{ 1181 | 0% { 1182 | transform: translateY(0) scale(1.15,.8) 1183 | } 1184 | 1185 | 20% { 1186 | transform: translateY(-35px) scaleY(1.1) 1187 | } 1188 | 1189 | 50% { 1190 | transform: translateY(-50px) scale(1) 1191 | } 1192 | 1193 | 80% { 1194 | transform: translateY(-35px) scale(1) 1195 | } 1196 | 1197 | to { 1198 | transform: translateY(0) scale(1.15,.8) 1199 | } 1200 | } 1201 | 1202 | /* 5 - 组件 1203 | -------------------------------- */ 1204 | 1205 | /* - 漂浮提示 */ 1206 | [ks-tag]{ position: relative } 1207 | [ks-tag]:before, [ks-tag]:after{ 1208 | z-index: 1; 1209 | opacity: 0; 1210 | position: absolute; 1211 | pointer-events: none; 1212 | transition: opacity .3s; 1213 | } 1214 | 1215 | /* -- 小箭头 */ 1216 | [ks-tag]:before{ 1217 | width: 0; 1218 | height: 0; 1219 | content: ''; 1220 | border: .5rem solid var(--border-color); 1221 | } 1222 | 1223 | [ks-tag~=top]:before{ 1224 | bottom: 100%; 1225 | border-top-color: rgba(0, 0, 0, .7); 1226 | } 1227 | [ks-tag~=bottom]:before{ 1228 | top: 100%; 1229 | border-bottom-color: rgba(0, 0, 0, .7); 1230 | } 1231 | 1232 | [ks-tag~=top]:before, [ks-tag~=bottom]:before{ 1233 | left: 50%; 1234 | transform: translateX(-50%); 1235 | } 1236 | 1237 | [ks-tag=left]:before{ 1238 | right: 100%; 1239 | border-left-color: rgba(0, 0, 0, .7); 1240 | } 1241 | [ks-tag=right]:before{ 1242 | left: 100%; 1243 | border-right-color: rgba(0, 0, 0, .7); 1244 | } 1245 | 1246 | [ks-tag=left]:before, [ks-tag=right]:before{ 1247 | top: 50%; 1248 | transform: translateY(-50%); 1249 | } 1250 | 1251 | /* -- 文字 */ 1252 | [ks-tag~=top]:after{ 1253 | bottom: 100%; 1254 | margin-bottom: 1rem; 1255 | } 1256 | [ks-tag~=bottom]:after{ 1257 | top: 100%; 1258 | margin-top: 1rem; 1259 | } 1260 | 1261 | [ks-tag=top]:after, [ks-tag=bottom]:after{ 1262 | left: 50%; 1263 | transform: translateX(-50%); 1264 | } 1265 | 1266 | [ks-tag=left]:after{ 1267 | right: 100%; 1268 | margin-right: 1rem; 1269 | } 1270 | [ks-tag=right]:after{ 1271 | left: 100%; 1272 | margin-left: 1rem; 1273 | } 1274 | 1275 | [ks-tag=left]:after, [ks-tag=right]:after{ 1276 | top: 50%; 1277 | transform: translateY(-50%); 1278 | } 1279 | 1280 | /* -- 组合对齐方式 */ 1281 | [ks-tag~=left][ks-tag~=top]:after, [ks-tag~=left][ks-tag~=bottom]:after{ 1282 | right: 0; 1283 | min-width: 4em; 1284 | } 1285 | [ks-tag~=right][ks-tag~=top]:after, [ks-tag~=right][ks-tag~=bottom]:after{ 1286 | left: 0; 1287 | min-width: 4em; 1288 | } 1289 | 1290 | [ks-text]:hover:before, [ks-text]:hover:after{ opacity: 1 } 1291 | 1292 | [ks-text]:after{ 1293 | color: #fff; 1294 | font-size: .85rem; 1295 | white-space: nowrap; 1296 | border-radius: .5rem; 1297 | padding: .25rem .5rem; 1298 | content: attr(ks-text); 1299 | background: rgba(0, 0, 0, .7); 1300 | } 1301 | 1302 | /* - 弹窗 */ 1303 | notice{ 1304 | top: 0; 1305 | left: 0; 1306 | right: 0; 1307 | z-index: 10; 1308 | padding: 1em; 1309 | position: fixed; 1310 | user-select: none; 1311 | pointer-events: none; 1312 | } 1313 | 1314 | .ks-notice{ 1315 | color: var(--primary-color); 1316 | display: table; 1317 | background: #333; 1318 | border-radius: 3em; 1319 | pointer-events: auto; 1320 | margin: 0 auto 1em auto; 1321 | box-shadow: 0 5px 5px -2px rgba(0, 0, 0, .2); 1322 | animation: fade-small-large .3s both; 1323 | -webkit-animation: fade-small-large .3s both; 1324 | } 1325 | 1326 | .ks-notice.remove{ 1327 | animation: fade-in-top .3s both reverse; 1328 | -webkit-animation: fade-in-top .3s both reverse; 1329 | } 1330 | 1331 | /* -- 弹窗颜色 */ 1332 | .ks-notice.red{ 1333 | color: var(--red-color); 1334 | background: var(--red); 1335 | } 1336 | 1337 | .ks-notice.yellow{ 1338 | color: var(--yellow-color); 1339 | background: var(--yellow); 1340 | } 1341 | 1342 | .ks-notice.blue{ 1343 | color: var(--blue-color); 1344 | background: var(--blue); 1345 | } 1346 | 1347 | .ks-notice.green{ 1348 | color: var(--green-color); 1349 | background: var(--green); 1350 | } 1351 | 1352 | .ks-notice > span{ 1353 | padding: .5em 1em; 1354 | display: table-cell; 1355 | vertical-align: middle; 1356 | } 1357 | 1358 | .ks-notice .close{ 1359 | cursor: pointer; 1360 | border-radius: 0 1em 1em 0; 1361 | transition: background .3s; 1362 | } 1363 | 1364 | .ks-notice .close:hover{ 1365 | background: rgba(0, 0, 0, .1); 1366 | } 1367 | 1368 | .ks-notice .close:after{ 1369 | content: '×'; 1370 | font: inherit; 1371 | } 1372 | 1373 | /* - 图片放大 */ 1374 | [ks-image=active]{ 1375 | cursor: pointer; 1376 | cursor: zoom-in; 1377 | } 1378 | 1379 | .ks-image{ 1380 | top: 0; 1381 | left: 0; 1382 | right: 0; 1383 | bottom: 0; 1384 | z-index: 66; 1385 | position: fixed; 1386 | user-select: none; 1387 | animation: fade-in .3s both; 1388 | -webkit-animation: fade-in .3s both; 1389 | } 1390 | .ks-image.loading{ cursor: wait } 1391 | .ks-image.remove:before{ 1392 | animation: fade-off .3s both; 1393 | -webkit-animation: fade-off .3s both; 1394 | } 1395 | 1396 | .ks-image:before{ 1397 | top: 0; 1398 | left: 0; 1399 | right: 0; 1400 | bottom: 0; 1401 | content: ''; 1402 | position: absolute; 1403 | background: rgba(0, 0, 0, .6); 1404 | } 1405 | 1406 | .ks-image .ks-prev, .ks-image .ks-next{ 1407 | top: 0; 1408 | bottom: 0; 1409 | width: 10%; 1410 | height: 5em; 1411 | margin: auto; 1412 | max-width: 5em; 1413 | cursor: pointer; 1414 | position: absolute; 1415 | transition: opacity .3s, transform .3s; 1416 | } 1417 | .ks-image .ks-prev:hover{ transform: translateX(-.5em) } 1418 | .ks-image .ks-next:hover{ transform: translateX(.5em) } 1419 | 1420 | .ks-image .ks-prev{ 1421 | left: 0; 1422 | background: center/60% no-repeat url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMTAyNCAxMDI0IiB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZmlsbD0icmdiYSgyNTUsMjU1LDI1NSwwLjkpIj48cGF0aCBkPSJNMzI0LjIxMTUxNyA1MTEuODA1NjMxIDc4Ny44ODk1OTQgNzMuMDgyNTgzYzE2LjE5NDIyLTE2LjYzMDM2NSAxNi4xOTQyMi00My45NzQ3MDQgMC02MC42MDUwNjgtMTYuMTk0MjItMTYuNjMwMzY1LTQyLjQ5NTYwNy0xNi42MzAzNjUtNTguNjEzOTc2IDBMMjM1Ljc1MDExMyA0NzkuMzYwMzAyYy04LjY0NzAzMSA4Ljk2OTM5OC0xMi4zNDQ3NzUgMjAuOTM0OTE3LTExLjcxOTAwMyAzMi40NDUzMjktMC42NDQ3MzUgMTEuOTA4NjMgMy4wNzE5NzIgMjMuODc0MTQ5IDExLjcxOTAwMyAzMi44MjQ1ODVsNDkzLjUwNjU0MiA0NjYuODgyNzg4YzE2LjExODM2OSAxNi42NDkzMjcgNDIuNDM4NzE4IDE2LjY0OTMyNyA1OC42MTM5NzYgMCAxNi4xOTQyMi0xNy4wODU0NzEgMTYuMTk0MjItNDMuOTc0NzA0IDAtNjAuNjA1MDY4TDMyNC4yMTE1MTcgNTExLjgwNTYzMSI+PC9wYXRoPjwvc3ZnPg==); 1423 | } 1424 | .ks-image .ks-next{ 1425 | right: 0; 1426 | background: center/60% no-repeat url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjAwIDIwMCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9InJnYmEoMjU1LDI1NSwyNTUsMC45KSI+PHBhdGggZD0iTTEzNi43LDEwMGwtOTAuNiw4NS44Yy0zLjIsMy4yLTMuMiw4LjUsMCwxMS44YzMuMiwzLjMsOC4zLDMuMywxMS40LDBsOTYuNC05MS4yYzEuNy0xLjcsMi40LTQuMSwyLjMtNi40YzAuMS0yLjItMC42LTQuNi0yLjMtNi4zTDU3LjYsMi40Yy0zLjEtMy4yLTguMy0zLjItMTEuNCwwcy0zLjIsOC42LDAsMTEuOEwxMzYuNywxMDAiLz48L3N2Zz4NCg==); 1427 | } 1428 | 1429 | .ks-image .ended{ 1430 | opacity: .5; 1431 | cursor: no-drop; 1432 | } 1433 | 1434 | .ks-image .ks-ball{ 1435 | top: 1em; 1436 | right: 1em; 1437 | width: 2em; 1438 | height: 2em; 1439 | opacity: 0; 1440 | border-radius: 66%; 1441 | position: absolute; 1442 | pointer-events: none; 1443 | transition: opacity .3s; 1444 | border: .5em #fff solid; 1445 | border-left-color: #3498db; 1446 | border-left-color: var(--primary); 1447 | animation: rotate .5s linear infinite paused; 1448 | -webkit-animation: rotate .5s linear infinite paused; 1449 | } 1450 | .ks-image.loading .ks-ball{ 1451 | opacity: 1; 1452 | animation-play-state: running; 1453 | } 1454 | 1455 | .ks-image img, .ks-image video{ 1456 | top: 0; 1457 | left: 0; 1458 | right: 0; 1459 | bottom: 0; 1460 | margin: auto; 1461 | max-width: 80%; 1462 | max-height: 90%; 1463 | cursor: zoom-out; 1464 | position: absolute; 1465 | transition: transform .3s; 1466 | animation: fade-small-large .3s backwards; 1467 | -webkit-animation: fade-small-large .3s backwards; 1468 | } 1469 | 1470 | .ks-image video{ 1471 | cursor: auto; 1472 | } 1473 | 1474 | .ks-image img:not([src]), .ks-image video:not([src]){ 1475 | display: none; 1476 | } 1477 | 1478 | .ks-image.remove img, .ks-image.remove video, .ks-image.remove .ks-prev, .ks-image.remove .ks-next{ 1479 | animation: fade-large-small .3s both; 1480 | -webkit-animation: fade-large-small .3s both; 1481 | } 1482 | 1483 | .ks-image img[src$=".jpg"], .ks-image video{ 1484 | box-shadow: 0 5px 15px rgba(0, 0, 0, .5); 1485 | } 1486 | 1487 | /* ---- 1488 | 1489 | Copyright (C) 2023 Dreamer-Paul. 1490 | 1491 | ---- */ 1492 | --------------------------------------------------------------------------------