30 KiB
Using Color
Add color via props
Alerts support Pastel attributes. Buttons accept Color and Variant attributes. Cards accept Pastel, Variant, Neutral and Raised attributes.
<Card solid red title='🌈' />
Add color to a any component or Html tag
- Choose either:
- base color (
primary | secondary | destructive
) or - pastel color (
blue | red | green | yellow
) or - neutral beige or gray (
default
) for surfaces
- base color (
- Choose a variant (
solid | ghost | outline
) - Add interactivity and raise the surface
<script setup>
import { color } from "~/composables/color.ts";
</script>
<template>
<div v-bind="color({}, ['primary', 'solid', 'interactive', 'raised'])()" />
</template>
Make your component accept color props
color
accepts two parameters. The first is your props object, the second is a list of defaults.
In this case, if the user of your component doesn't specify any color, it will be 'primary'. Since the user cannot specify the variant, it will always be 'default'.
<script setup>
import { type ColorProps, color } from "~/composables/colors.ts";
const props = defineProps<{
...
} & ColorProps>()
</script>
<template>
<div v-bind="color(props, ['primary', 'solid'])()" />
</template>
Base colors
Keep most of the screen neutral. Secondary surfaces indicate actionability. Use them sparingly. Primary and destructive surfaces immediately catch the eye. Use them only once or twice per screen.
Neutral
Use neutral colors for non-interactive surfaces
Color
Primary
Only use for at most one call-to-action on a screen
Secondary
Use for interactive items and non-permanent surfaces such as menus and modals
Destructive
Use for dangerous actions
Pastel
Use Blue
, Red
, Purple
, Green
, Yellow
for user-defined tags and for friendly messages such as
Alerts
Variant
You can de-emphasize interactive elements by hiding their background and/or outline.
Solid
(default), Ghost
, Outline
:
Interactive and/or Raised
Use raised surfaces sparingly, about ¼ of the screen. Only use raised surfaces to highlight one area of a component over others. Good examples are aside
s such as the sidebar or info-boxes.
Space out interactive surfaces.
Normal
Raised
neutral |
---|
secondary |
primary |
(normal) | interactive | disabled | pressed |
---|
Palette
The color palette consists of Blues, Reds, Grays, Beiges, as well as pastel blue/red/green/yellow.
fw-blue-010 - 100 - 400..900
fw-red-010 - 100 - 400..900
fw-gray-100..800 - 850 - 900 - 950 - 960 - 970
fw-beige-100..400
fw-pastel-blue-1..4
fw-pastel-red-1..4
fw-pastel-purple-1..4
fw-pastel-green-1..4
fw-pastel-yellow-1..4
In addition, we have a single shade of orange used for secondary indicators such as active tabs: fw-secondary
Theme
Many browsers automatically turn on "night mode" to lower the light emission of the screen. Users can override the browser theme in their settings menu.
In both "dark mode" and "light mode", the colors must provide adequate contrast and consistency.
Read more about style modules in the corresponding vue docs.
For testing purposes and side-by-side comparisons, you can add the classes force-dark-theme
and force-light-theme
.
Semantic colors
We use semantic color variables that can mean a different shade depending on the currently chosen theme
- primary
- secondary (default)
- destructive
Color variants
For each semantic color, we set a foreground and a background. In addition, we need to check context: A button should have a stronger shade when the mouse is hovering over it. When a surface is raised over another surface, it should have a stronger shade, too.
Variants:
-
ghost (default for most things except buttons)
affects text color but leaves the border and background transparent. Make sure to provide a surface beneath with adequate contrast.
-
outline
affects text color and border and leaves the background transparent Make sure to provide a surface beneath with adequate contrast.
-
solid (default for buttons)
affects text color, border color and background color
Variants can optionally be made interactive and/or raised:
-
no alteration (default)
-
raised
affects text color, border color and background color
-
interactive
user interaction affects text color, border color and background color
- can be disabled
- can be active
- can be exact-active
- can be hovering
-
interactive-raised
combine
raised
andinteractive
-> Example: #interactive-and-or-raised
Theme color definitions
All colors are defined in front/src/style/colors.scss
.
Its structure is as follows:
Defining all funkwhale color values
both for light and dark theme, and both normal and raised:
- default
- secondary
- primary
- destructive
- blue
- red
- purple
- green
- yellow
(for all elements not managed by vitepress)
- (a) Applying colors to things with no explicit Variant props, such as headings and paragraphs, simple links, focusable elements
- (b) Applying colors to things with explicit Variant props: - solid (and default buttons) - ghost - outline
Change a color value
For example, you want to make all blue hues more cyan-ish or mute all reds.
- Find the color value you want to change in section 1 (Palette)
- Change it
- Keep this page open and check under Palette if the colors are still in harmony with each other. Also make sure all recommended color combinations still meet the relevant WCGA2 recommendations for contrast
Alter the shade of a color
In funkwhale components, we use semantic color names such as primary
, destructive
, default
(neutral). Now, you find, for example, that a secondary button has low contrast in light mode, and you decide to alter the text color.
- Find the relevant section in section 2 (hoosing the semantic colors from the palette). In our example, it's
.secondary
undertheme-light
. - You see that the values are
--color: var(--fw-gray-700);
and--background-color: var(--fw-gray-200);
, and you change--color
tovar(--fw-gray-900)
. - Test your changes. If nothing changes, then there is a Css rule with higher precedence. Find and eliminate these sorts of competing rules.
Choose a different style for a specific variant
For example, you want to add visible lines around ghost links and buttons when the user hovers over them.
- Find the variant class in section 3 (Applying colors). In our example, it is
.ghost
. - In our example, we would add the line
border-color: var(--hover-border-color);
under&:hover
to make the outline on interactive items visible on hover. - Make sure to test all affected components before committing and merging the changes
Overview of current styles
Make sure that:
- Contrasts meet WCAG2 requirements
- Colors and outlines communicate the correct dose of prominence
- All styles are different enough from each other to not be confused
Here is the meaning the styles should convey:
- active: The user has chosen this option
- Here: The user is exactly here
- raised: Things on this surface complement the main area (sidebar, aside, ...)
- default: Background of the app
- secondary: This is interactive! As of now, secondary things need a secondary background.
- primary: Important!
Links and buttons
Inline Link and Link
Here ghost outline solid raised Elsewhere ghost outline solid raised
Button Button ghost Button outline Button solid Button active Button disabled Button primary
Button raised Button raised ghost Button raised outline Button raised solid Button active Button disabled
Inline Link and LinkHere ghost outline solid raised Elsewhere ghost outline solid raised
Button Button ghost Button outline Button solid Button active Button disabled Button primary
Button raised Button raised ghost Button raised outline Button raised solid Button active Button disabled
Inline Link and LinkHere ghost outline solid raised Elsewhere ghost outline solid raised
Button Button ghost Button outline Button solid Button active Button disabled Button primary
Button raised Button raised ghost Button raised outline Button raised solid Button raised active Button raised disabled
Inline Link and LinkHere ghost outline solid raised Elsewhere ghost outline solid raised
Button Button ghost Button outline Button solid Button active Button disabled Button primary
Button raised Button raised ghost Button raised outline Button raised solid Button active Button raised disabled