From 5323df4a32ca9b81fa598c0ca988596d93afe713 Mon Sep 17 00:00:00 2001 From: Bastien Wirtz Date: Tue, 1 Oct 2019 21:35:51 -0700 Subject: Implementing dark mode --- app.css | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- app.js | 13 ++++++++- app.scss | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- index.html | 31 +++++++++++++--------- 4 files changed, 190 insertions(+), 27 deletions(-) diff --git a/app.css b/app.css index 846b54b..8a97742 100644 --- a/app.css +++ b/app.css @@ -3,8 +3,86 @@ html { body { font-family: 'Raleway', sans-serif; - background-color: #F5F5F5; - min-height: 100%; } + height: 100%; } + body #app { + min-height: 100%; + transition: background-color cubic-bezier(0.165, 0.84, 0.44, 1) 300ms; + background-color: #f5f5f5; + color: #363636; } + body #app .title { + color: #303030; } + body #app .subtitle { + color: #424242; } + body #app .card { + background-color: #ffffff; + box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.1); } + body #app .card:hover { + background-color: #ffffff; } + body #app .footer { + background-color: #ffffff; + box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.1); } + @media (prefers-color-scheme: light), (prefers-color-scheme: no-preference) { + body #app { + background-color: #f5f5f5; + color: #363636; } + body #app .title { + color: #303030; } + body #app .subtitle { + color: #424242; } + body #app .card { + background-color: #ffffff; + box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.1); } + body #app .card:hover { + background-color: #ffffff; } + body #app .footer { + background-color: #ffffff; + box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.1); } } + @media (prefers-color-scheme: dark) { + body #app { + background-color: #131313; + color: #eaeaea; } + body #app .title { + color: #fafafa; } + body #app .subtitle { + color: #f5f5f5; } + body #app .card { + background-color: #2b2b2b; + box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.4); } + body #app .card:hover { + background-color: #2b2b2b; } + body #app .footer { + background-color: #2b2b2b; + box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.4); } } + body #app.is-light { + background-color: #f5f5f5; + color: #363636; } + body #app.is-light .title { + color: #303030; } + body #app.is-light .subtitle { + color: #424242; } + body #app.is-light .card { + background-color: #ffffff; + box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.1); } + body #app.is-light .card:hover { + background-color: #ffffff; } + body #app.is-light .footer { + background-color: #ffffff; + box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.1); } + body #app.is-dark { + background-color: #131313; + color: #eaeaea; } + body #app.is-dark .title { + color: #fafafa; } + body #app.is-dark .subtitle { + color: #f5f5f5; } + body #app.is-dark .card { + background-color: #2b2b2b; + box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.4); } + body #app.is-dark .card:hover { + background-color: #2b2b2b; } + body #app.is-dark .footer { + background-color: #2b2b2b; + box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.4); } body h1, body h2, body h3, body h4, body h5, body h6 { font-family: 'Lato', sans-serif; } body h1 { @@ -54,7 +132,7 @@ body { body #bighead .navbar a:hover { background-color: #5a95f5; } body #main-section { - margin-bottom: 3rem; + margin-bottom: 2rem; padding: 0; } body #main-section h2 { border-bottom: 1px dashed #ccc; @@ -95,7 +173,6 @@ body { body .card a { outline: none; } body .card:hover { - background-color: #FFFFFF; transform: translate(0, -3px); } body .card:hover .tag { width: auto; @@ -117,10 +194,9 @@ body { bottom: 0; padding: 0.5rem; text-align: left; - background-color: #fafafa; - border-top: 1px solid #F5F5F5; color: #676767; - font-size: 0.85rem; } + font-size: 0.85rem; + transition: background-color cubic-bezier(0.165, 0.84, 0.44, 1) 300ms; } body .search-bar { position: relative; display: inline-block; } diff --git a/app.js b/app.js index dc8b6cc..a404314 100644 --- a/app.js +++ b/app.js @@ -4,7 +4,8 @@ const app = new Vue({ config: null, offline: false, filter: '', - vlayout: true + vlayout: true, + overrideDark: null }, created: function () { let that = this; @@ -22,6 +23,13 @@ const app = new Vue({ } }, false); }, + computed: { + isDark: function() { + return this.overrideDark !== null + ? this.overrideDark + : matchMedia("(prefers-color-scheme: dark)").matches; + } + }, methods: { checkOffline: function () { let that = this; @@ -44,6 +52,9 @@ const app = new Vue({ }); }); }, + toggleTheme: function() { + this.overrideDark = !this.isDark; + } } }); diff --git a/app.scss b/app.scss index ab9a394..d4d2099 100644 --- a/app.scss +++ b/app.scss @@ -1,12 +1,83 @@ $primary-color: #3367d6; $secondary-color: #4285f4; -html { height: 100%; } + +// /!\ Keep background colors sync with `theme-color` meta info +$theme-light: ( + background: #f5f5f5, + card-background: #ffffff, + text: #363636, + text-title: #303030, + text-subtitle: #424242, + card-shadow: rgba(0, 0, 0, 0.1) +); +$theme-dark: ( + background: #131313, + card-background: #2b2b2b, + text: #eaeaea, + text-title: #fafafa, + text-subtitle: #f5f5f5, + card-shadow: rgba(0, 0, 0, 0.4) +); + + + +@mixin theme($theme) { + background-color: map-get($theme, "background"); + color: map-get($theme, "text"); + + .title { + color: map-get($theme, "text-title"); + } + .subtitle { + color: map-get($theme, "text-subtitle"); + } + + .card { + background-color: map-get($theme, "card-background"); + box-shadow: 0 2px 15px 0 map-get($theme, "card-shadow"); + &:hover { + background-color: map-get($theme, "card-background"); + } + } + + .footer { + background-color: map-get($theme, "card-background"); + box-shadow: 0 2px 15px 0 map-get($theme, "card-shadow"); + } +} + +html { + height: 100%; +} body { font-family: 'Raleway', sans-serif; - background-color: #F5F5F5; - min-height: 100%; + height: 100%; + + #app { + min-height: 100%; + transition: background-color cubic-bezier(0.165, 0.84, 0.44, 1) 300ms; + + // Default theme + @include theme($theme-light); + + // System pref theme + @media (prefers-color-scheme: light), (prefers-color-scheme: no-preference) { + @include theme($theme-light); + } + @media (prefers-color-scheme: dark) { + @include theme($theme-dark); + } + + // User override theme + &.is-light { + @include theme($theme-light); + } + &.is-dark { + @include theme($theme-dark); + } + } h1, h2, h3, h4, h5, h6 { font-family: 'Lato', sans-serif; @@ -90,7 +161,7 @@ body { } #main-section { - margin-bottom: 3rem; + margin-bottom: 2rem; padding: 0; h2 { @@ -155,7 +226,6 @@ body { } .card:hover { - background-color: #FFFFFF; transform: translate(0, -3px); .tag { @@ -191,10 +261,9 @@ body { bottom: 0; padding: 0.5rem; text-align: left; - background-color: #fafafa; - border-top: 1px solid #F5F5F5; color: #676767; font-size: 0.85rem; + transition: background-color cubic-bezier(0.165, 0.84, 0.44, 1) 300ms; } .search-bar { diff --git a/index.html b/index.html index 6b75e49..d5aebd3 100644 --- a/index.html +++ b/index.html @@ -14,7 +14,10 @@ -
+
@@ -39,6 +42,11 @@
+ +
+
- - -- cgit v1.2.3