# Profile Skins Profile skins customize Bliish profile pages with sanitized HTML and passive CSS. Skins are edited in the profile editor under **Skin HTML** and shared from **Skins -> Submit skin**. The skin field is limited to 20,000 characters. Profile skins may be empty. Shared skins must save to non-empty sanitized skin HTML. Profile and shared skin forms sanitize skin HTML before saving. Profile rendering sanitizes profile skin HTML again before rendering. ## Quick Start Use one or more `
Optional custom skin HTML appears on the profile.
``` ## Rendering Model Skin CSS is collected from sanitized ` ``` ```html ``` ## CSS Selector Rules Every skin CSS selector must include at least one supported hook. Supported hooks are `[data-skin-page]`, `[data-skin-root]`, `[data-skin-version="2026"]`, and supported `[data-skin-part="..."]` values. Bare page selectors are limited to `[data-skin-page]` or `[data-skin-version="2026"]` by themselves. Use `[data-skin-root]` or `[data-skin-part="..."]` before descendant selectors. This is allowed: ```css [data-skin-part="bio"] a:hover { color: red; } ``` This is dropped because it is a descendant of the body hook rather than a profile part: ```css [data-skin-page] a { color: red; } ``` This is dropped because it has no skin hook: ```css body { color: red; } ``` Selectors with unsupported attribute selectors are dropped. Selectors using `:has()`, `:is()`, or `:where()` are dropped. Simple `:not(...)` selectors can survive when the `:not(...)` contents only use simple class, id, tag, or spacing characters. If any selector in a comma-separated selector list is unsafe, the whole rule is dropped. Selectors longer than 500 characters are dropped. The sanitizer removes `<` and `>` from CSS before parsing, so do not use child combinators. Use descendant selectors instead of `>`. ## CSS Declaration Rules Most ordinary CSS property names are accepted. The properties `behavior` and `-moz-binding` are blocked. `position:absolute`, `position:fixed`, and `position:sticky` are blocked. `position:relative` is not blocked by the skin sanitizer. CSS custom properties are accepted when the name starts with `--` and does not use a blocked app-owned prefix. CSS values are dropped if they contain CSS escapes, `expression(...)`, `javascript:`, `vbscript:`, `behavior:`, `-moz-binding`, `attr(...)`, `<`, or `>`. A declaration containing an unsafe `url(...)` is dropped. Other safe declarations in the same rule can still survive. CSS comments are removed. Malformed CSS rule blocks may be dropped. ## CSS At-Rules `@import` is only kept for `https://fonts.googleapis.com/...` stylesheets. Other `@import` rules are removed. `@media` rules can survive when the media prelude uses the sanitizer's supported simple characters. `@keyframes` rules can survive when the animation name is alphanumeric, underscore, or hyphen. Keyframe selectors can be `from`, `to`, or percentages. Other CSS at-rules are removed. ## URLs And Media Links and resources use different URL rules. Link `href` values can be local paths, hash links, `http:`, `https:`, or `mailto:`. Link `rel` is rewritten to `nofollow noopener noreferrer`. Link `target` is kept only when it is `_blank`. Image `src`, table `background`, and CSS `url(...)` resources can be local app paths or `https:` URLs. Resource URLs using `http:`, `data:`, `file:`, `javascript:`, or `vbscript:` are removed. Invalid image URLs are replaced with an empty ``. CSS declarations with invalid `url(...)` values are removed. ## Embeds Skins can include sanitized `