A repo containing themes for SDH-CssLoader, a CSS loader for the Steam Deck.
- Some experience in JSON and CSS
- Installed the CSS loader
- (Optional) Installed a Chromium-based browser
There is a sample/template repository available. Feel free to use this to more easily create a theme by using the template.
The CEF debugger is very useful for creating themes, as it allows you to play around directly with the style of the Steam Deck UI.
The debugger allows you to access the multiple tabs that are used for the UI. A few common ones are:
SP
- The main UI of the Steam DeckQuickAccess
- The Quick Access overlayMainMenu
- The Steam menu overlay
- Turn on the "Allow Remote CEF Debugging" setting in the Decky settings.
- Open a Chromium-based browser (ex. Google Chrome, Microsoft Edge, Brave)
- Go to the inspect page of your browser (ex. chrome://inspect, edge://inspect, brave://inspect)
- Under "Discover network targets", click "Configure", and enter "{DECK_IP}:8081"
- You can find the IP of your Steam Deck by going into your internet settings, selecting the current connected network, and looking at the
IP Address
field
- You can find the IP of your Steam Deck by going into your internet settings, selecting the current connected network, and looking at the
- Wait a few seconds, and you will see multiple tabs appear under "Remote Target"
- After selecting a tab, you should be able to see the HTML and CSS used for that specific tab, like the screenshot above
- Turn on the "Allow Remote CEF Debugging" setting in the Decky settings.
- Open a Chromium-based browser (ex. Google Chrome, Microsoft Edge, Brave)
- Connect to {DECK_IP}:8081 in the browser
- You need to be on the same network as your Steam Deck
- You can find the IP of your Steam Deck by going into your internet settings, selecting the current connected network, and looking at the
IP Address
field
- Select a tab
- After selecting a tab, you should be able to see the HTML and CSS used for that specific tab, like the screenshot above
Themes are folders with CSS files and a single theme.json
inside. The theme.json
determines how everything will be displayed, and any dropdown options if the theme has them. The CSS loader loads themes from /home/deck/homebrew/themes
.
For a simple theme, like the image above, theme.json
should look something like this:
{
"name": "Clean Gameview",
"author": "SuchMeme",
"target": "Library",
"manifest_version": 3,
"description": "this is an example description",
"inject": {
"shared.css": ["SP"]
}
}
- The name element describes the theme name. This is also used as the folder name for the theme store.
- The author element describes the theme author.
- An optional field
"version": "v1.0"
can be added. If no version field is found, the version defaults tov1.0
. - The manifest version tells the CSS Loader which version of
themes.json
you are using. The current version is4
. - An optional field
"description": ""
can be added to show a text description in the theme store. - The inject tab is a dictionary of relative CSS file paths as keys, and a list of tabs you want the CSS to be injected into.
- The target field describes what part of the UI your theme themes. This is only useful for submitting a theme. The following options are available, but more can be added through creating an issue:
- System-Wide
- Background
- Keyboard
- Home
- Background
- Library
- Store
- Friends and Chat
- Media
- Downloads
- Settings
- Lock Screen
- Tweak
- Other
A complex theme is a theme with patches. Patches are displayed as dropdown menus that apply additional CSS depending on the selection. The theme.json
for a complex theme should look something like this:
{
"name": "Colored Toggles",
"version": "v1.2",
"author": "SuchMeme",
"target": "System-Wide",
"description": "this is an example description",
"manifest_version": 2,
"inject": {
"shared.css": [
"QuickAccess", "SP", "MainMenu"
]
},
"patches": {
"Theme Color": {
"default": "Orange",
"type": "dropdown",
"values": {
"Orange": {},
"Lime": {
"colors/lime.css": ["QuickAccess", "SP", "MainMenu"]
},
"Red": {
"colors/red.css": ["QuickAccess", "SP", "MainMenu"]
},
"Magenta": {
"colors/magenta.css": ["QuickAccess", "SP", "MainMenu"]
},
"Gradient RGB": {
"colors/gradient_rgb.css": ["QuickAccess", "SP", "MainMenu"]
},
"Gradient Deck": {
"colors/gradient_deck.css": ["QuickAccess", "SP", "MainMenu"]
}
}
}
}
}
The patches section is a dictionary of patch names as key. The value is a dictionary where keys are it's options and their value is the applied CSS, similar to the "inject" section. The special key "default" is required to indicate a default option.
Patches allow for choosing between a dropdown, a checkbox (toggle), or a slider for patch selection using the type
field.
"type": "dropdown"
This is the default value. This type gives a dropdown of all keys in the values
dictionary. Choosing an option injects only the CSS specified within the selected value.
"type": "slider"
This type gives a slider with the labels of the points of all keys in the values
dictionary. Choosing an option injects only the CSS specified within the selected value.
"type": "checkbox"
This type represents the values
field as a toggle. This type is unique in the sense that it limits what options you can put in the values
dictionary. You need to have a Yes
and a No
option in the values
dictionary, otherwise the type falls back to a dropdown. When the toggle is on, Yes
is selected, otherwise No
is selected.
"type": "none"
Displays only a little arrow with the patch name. For use with components
Since CSSLoader v1.2.0, a small dependency system has been added. This is useful for if you want to bundle another theme or want to make small modifications to an existing theme. All dependencies get enabled alongside your theme.
In the themes.json file, specify a field called "dependencies"
. This is a dictionary of which the keys are the name of the theme you want to be dependencies, with their values being another dictionary. This dictionary's keys are the name of any patch this theme has, and the value the name of a value in the patch. If you don't want to modify any patch value, write {}
as value
"dependencies": {
"Switch Like Home": {
"No Friends": "Yes"
},
"Clean Gameview": {}
}
If a theme has a dependencies field like the one above, it will enable both Switch Like Home and Clean Gameview. Switch Like Home's 'No Friends' patch gets forced to 'Yes'
Components are a way to attach extra parts to a selectable patch option.
Components are part of a patch. Inside a patch, you can make a "components"
field (it's value is a list), and put the components inside
The color picker component injects a css variable with a user specified color.
"components": [
{
"name": "Background Picker",
"type": "color-picker",
"on": "_",
"default": "#000",
"css_variable": "test-main-color",
"tabs": ["QuickAccess"]
}
]
name
refers to the of the component. This is shown to the usertype
refers to the type of component. For the color picker it'scolor-picker
on
refers to what patch value the component should be displayed ondefault
refers to what default color the color picker should start out with. Only hex is supported, in 3,4,6 and 8 character variantscss_variable
refers to the name of the css variable that will be injectedtabs
refers to what tabs the css variable will be injected into
The image picker component injects a user supplied file, using a file picker, as url(path/to/file)
as a css variable. Only images from ~/homebrew/themes
can be selected
"components": [
{
"name": "Image Picker",
"type": "image-picker",
"on": "_",
"default": "ThemeName/background.jpg",
"css_variable": "test-main-image",
"tabs": ["SP"]
}
]
name
refers to the of the component. This is shown to the usertype
refers to the type of component. For the color picker it'simage-picker
on
refers to what patch value the component should be displayed ondefault
refers to what default image path the image picker should start out with. The supplied relative path starts in~/homebrew/themes
css_variable
refers to the name of the css variable that will be injectedtabs
refers to what tabs the css variable will be injected into
Since CSSLoader v1.2.0, you can now access images locally from css. You can access images by using the following url: /themes_custom/{your_theme_name}/{image_path}
A pull request to this repository has a specific template to adhere to. Please make sure your theme adheres to these requirements.
- Fork this repository
- Clone the forked repository to your PC using your favorite Git tool
- Create a preview image and place it in the
images/{AUTHOR}
folder- Preferably upload an image in the .jpg format
- Create a JSON file named
{AUTHOR}-{THEME_NAME}.json
in the themes folder with the following content:repo_url
: Required, points to another GitHub repository with the themerepo_subpath
: Optional, defaults to '.', indicates the subpath to the folder containing the themerepo_commit
: Required, the commit in the Git repo you want to releasepreview_image_path
: Required. This image is displayed in the browse themes UI of the plugin and must be located in this repository
- (Optional) Test your theme submission using
py main.py
in the repository folder- Python and Git CLI need to be installed
- If you are missing Python libraries, type
pip install -r requirements.txt
- If the script throws no exception, you are ready to commit
- Make a commit with the image and JSON files
- (Optional) Repeat steps 3 through 6 for any additional themes you would like to add to your pull request
- Create a pull request from your fork to this repository
Here is an example {AUTHOR}-{THEME_NAME}.json
file:
{
"repo_url": "https://github.com/suchmememanyskill/Steam-Deck-Themes",
"repo_subpath": "Clean Gameview",
"repo_commit": "d9f160",
"preview_image_path": "images/SuchMeme/Clean Gameview.jpg"
}
Sometimes, you want to ignore specific files or remove specific files before they get analyzed by the CI of the theme db. This is for example needed if you want to include images in your theme. You can create a file called 'release.json' in the same folder as your 'theme.json' of your theme. Inside, the file should be structured as follows
{
"include": [],
"ignore": ["README.MD", "README.md", "Readme.md", "readme.md"]
}
Any paths in the include field will be included in the theme. Any paths in the ignore field will be ignored.
If you need any help creating or submitting a theme, please use the Steam Deck Homebrew Discord server. Please use the CSS-Loader Support thread in the #support-plugins channel.
If you created a theme and would like to upgrade it to the latest manifest version, please follow this guide. The current highest manifest version is 4.
No breaking changes have been made. Just change manifest_version
from a 3
to a 4
to update a theme to manifest level 4
No breaking changes have been made. Just change manifest_version
from a 2
to a 3
to update a theme to manifest level 3
To upgrade a version 1 themes.json
, all options of a patch need to be put in a values
dictionary, and a manifest_version
field should be added to the root of the .json with value 2
(or 3
/4
). Please see Making a theme compatible with the CSS loader for an example.