diff --git a/src/components/notification/notification.js b/src/components/notification/notification.js index c786f2cc..4dea63bb 100644 --- a/src/components/notification/notification.js +++ b/src/components/notification/notification.js @@ -6,7 +6,8 @@ import { highlightClass, highlightStyle } from '../../services/user_highlighter/ const Notification = { data () { return { - userExpanded: false + userExpanded: false, + betterShadow: this.$store.state.interface.browserSupport.cssFilter } }, props: [ diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue index 72c1ca69..f98afbe0 100644 --- a/src/components/notification/notification.vue +++ b/src/components/notification/notification.vue @@ -2,7 +2,7 @@
- +
diff --git a/src/components/notifications/notifications.scss b/src/components/notifications/notifications.scss index 87c89f6a..d17ae25d 100644 --- a/src/components/notifications/notifications.scss +++ b/src/components/notifications/notifications.scss @@ -49,11 +49,17 @@ .avatar-compact { width: 32px; height: 32px; + box-shadow: var(--avatarStatusShadow); border-radius: $fallback--avatarAltRadius; border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius); overflow: hidden; line-height: 0; + &.better-shadow { + box-shadow: none; + filter: drop-shadow(var(--avatarStatusShadowFilter)) + } + &.animated::before { display: none; } diff --git a/src/components/status/status.js b/src/components/status/status.js index 10716583..725bc3f8 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -33,7 +33,8 @@ const Status = { showingTall: false, expandingSubject: typeof this.$store.state.config.collapseMessageWithSubject === 'undefined' ? !this.$store.state.instance.collapseMessageWithSubject - : !this.$store.state.config.collapseMessageWithSubject + : !this.$store.state.config.collapseMessageWithSubject, + betterShadow: this.$store.state.interface.browserSupport.cssFilter } }, computed: { diff --git a/src/components/status/status.vue b/src/components/status/status.vue index 4541c560..26be335c 100644 --- a/src/components/status/status.vue +++ b/src/components/status/status.vue @@ -21,7 +21,7 @@
@@ -464,8 +464,14 @@ .status .avatar-compact { width: 32px; height: 32px; + box-shadow: var(--avatarStatusShadow); border-radius: $fallback--avatarAltRadius; border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius); + + &.better-shadow { + box-shadow: none; + filter: drop-shadow(var(--avatarStatusShadowFilter)) + } } .avatar { @@ -477,6 +483,11 @@ overflow: hidden; position: relative; + &.better-shadow { + box-shadow: none; + filter: drop-shadow(var(--avatarStatusShadowFilter)) + } + img { width: 100%; height: 100%; diff --git a/src/components/style_switcher/style_switcher.vue b/src/components/style_switcher/style_switcher.vue index fa173b98..66fe0f6b 100644 --- a/src/components/style_switcher/style_switcher.vue +++ b/src/components/style_switcher/style_switcher.vue @@ -278,6 +278,18 @@
+
+ + filter: drop-shadow() + + + drop-shadow + spread-radius + inset + +

{{$t('settings.style.shadows.filter_hint.inset_ignored')}}

+

{{$t('settings.style.shadows.filter_hint.spread_zero')}}

+
diff --git a/src/components/user_card_content/user_card_content.js b/src/components/user_card_content/user_card_content.js index 254d1666..97cd4983 100644 --- a/src/components/user_card_content/user_card_content.js +++ b/src/components/user_card_content/user_card_content.js @@ -7,7 +7,8 @@ export default { return { hideUserStatsLocal: typeof this.$store.state.config.hideUserStats === 'undefined' ? this.$store.state.instance.hideUserStats - : this.$store.state.config.hideUserStats + : this.$store.state.config.hideUserStats, + betterShadow: this.$store.state.interface.browserSupport.cssFilter } }, computed: { diff --git a/src/components/user_card_content/user_card_content.vue b/src/components/user_card_content/user_card_content.vue index 5529948e..cca418ff 100644 --- a/src/components/user_card_content/user_card_content.vue +++ b/src/components/user_card_content/user_card_content.vue @@ -10,7 +10,7 @@
- +
@@ -159,6 +159,11 @@ box-shadow: var(--avatarShadow); object-fit: cover; + &.better-shadow { + box-shadow: none; + filter: drop-shadow(var(--avatarStatusShadowFilter)) + } + &.animated::before { display: none; } diff --git a/src/i18n/en.json b/src/i18n/en.json index 8847b11e..7f5a2a4f 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -236,6 +236,13 @@ "spread": "Spread", "inset": "Inset", "hint": "For shadows you can also use --variable as a color value to use CSS3 variables. Please note that setting opacity won't work in this case.", + "filter_hint": { + "always_drop_shadow": "Warning, this shadow always uses {0} when browser supports it.", + "text": "Please note that {0} does not support {1} parameter and {2} keyword.", + "spread_zero": "Shadows with spread > 0 will appear as if it was set to zero", + "inset_ignored": "Inset shadows using will be ignored", + "inset_substituted": "Inset shadows will be substituted with {1} equivalent" + }, "components": { "panel": "Panel", "panelHeader": "Panel header", diff --git a/src/modules/interface.js b/src/modules/interface.js index 07489685..132fb08d 100644 --- a/src/modules/interface.js +++ b/src/modules/interface.js @@ -4,6 +4,12 @@ const defaultState = { settings: { currentSaveStateNotice: null, noticeClearTimeout: null + }, + browserSupport: { + cssFilter: window.CSS && window.CSS.supports && ( + window.CSS.supports('filter', 'drop-shadow(0 0)') || + window.CSS.supports('-webkit-filter', 'drop-shadow(0 0)') + ) } } diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js index 7c375206..cff81c40 100644 --- a/src/services/style_setter/style_setter.js +++ b/src/services/style_setter/style_setter.js @@ -110,6 +110,24 @@ const getCssShadow = (input) => { ]).join(' ')).join(', ') } +const getCssShadowFilter = (input) => { + if (input.length === 0) { + return 'none' + } + + return input + // drop-shadow doesn't support inset or spread + .filter((shad) => console.log(shad) || !shad.inset && Number(shad.spread) === 0) + .map((shad) => [ + shad.x, + shad.y, + // drop-shadow's blur is twice as strong compared to box-shadow + shad.blur / 2 + ].map(_ => _ + 'px').concat([ + getCssColor(shad.color, shad.alpha) + ]).join(' ')).join(', ') +} + const getCssColor = (input, a) => { let rgb = {} if (typeof input === 'object') { @@ -384,7 +402,12 @@ const generateShadows = (input) => { return { rules: { - shadows: Object.entries(shadows).map(([k, v]) => `--${k}Shadow: ${getCssShadow(v)}`).join(';') + shadows: Object + .entries(shadows) + // TODO for v2.1: if shadow doesn't have non-inset shadows with spread > 0 - optionally + // convert all non-inset shadows into filter: drop-shadow() to boost performance + .map(([k, v]) => `--${k}Shadow: ${getCssShadow(v)}; --${k}ShadowFilter: ${getCssShadowFilter(v)}`) + .join(';') }, theme: { shadows @@ -467,5 +490,6 @@ export { generateFonts, generatePreset, composePreset, - getCssShadow + getCssShadow, + getCssShadowFilter }