Pcss
Guidelines for writing scalable and maintainable style-sheets
Install / Use
/learn @dsheiko/PcssREADME
PCSS
ver. 1.2.2
Pragmatic CSS is a collection of guidelines for writing scalable and maintainable style-sheets. PCSS divides the whole UI into portable and reusable components. Every component is described in a separate CSS (SASS/LESS/etc) module. PCSS's naming convention makes it easier to locate a module corresponding to a problem and encourages developer on producing optimized object-oriented CSS.
PCSS is standing on the shoulders of giants. It borrows Base, State and Theme rules from SMACSS, element and subclass (modifier) naming conventions from BEM, the idea of common OOP principles in CSS (inheritance, OCP, SRP) from OOCSS, context-independent cascading from Modular CSS naming conventions
Contents
- Key concepts
- File Structure Example
- Naming Conventions
- Selector Conventions
Component
Class | Location
----|----
.panel | ./component/panel/_index.scss
.nav-bar | ./component/nav-bar/_index.scss
Component is a reusable module of UI (e.g. nav-bar, panel, form).
Component consists of elements (e.g. form__title) and can be extended by subclasses.

Element
Class | Location
----|----
.panel__header | ./component/panel/_index.scss
Component is built of elements. Elements is an integral parts of a component and cannot be reused outside of component scope.
Subclass
Class | Location
----|----
.panel--primary | ./component/panel/_primary.scss
Following OOP practices, we inherit from a base component to a subclass
For example, when we are required of a dialog window, we create ./component/dialog/_index.scss where we put the base styles for
any dialogs in the application. Then we add ./component/dialog/_alert.scss where we set the extending styles
for the concrete modal window. Now we refer to a concrete component in the HTML like that:
<div class="dialog dialog--alert">..</div>
<div class="dialog dialog--prompt">..</div>
Subclasses and elements
Elements are styled in scopes of subclasses:
.shopping-cart {
// Base styles
}
.shopping-cart--default {
.shopping-cart__heading {
color: $color-white;
}
}
.shopping-cart--inverse {
.shopping-cart__heading {
color: $color-block;
}
}
Here we have an abstract component .shopping-cart extended by .shopping-cart--default and .shopping-cart--inverse
where the first has white heading and the second black one.
Component Example

HTML
<div class="progressbar progressbar--big">
<output class="progressbar__status">
Install is 70% complete
</output>
<progress class="progressbar__progress" value="70" max="100"></progress>
<div class="progressbar__actions">
<div class="icon icon--pause">pause</div>
<div class="icon icon--play is-hidden">resume</div>
</div>
</div>
./component/progressbar/_index.scss
.progressbar {
position: relative;
}
.progressbar__progress {
border: 0;
position: absolute;
width: 100%;
bottom: 0;
left: 0;
appearance: none;
&::-webkit-progress-bar {/*..*/ }
&::-webkit-progress-value {/*..*/ }
&::-moz-progress-bar {/*..*/ }
}
.progressbar__status {
display: flex;
position: relative;
font-size: 1rem;
}
.progressbar__actions {
position: absolute;
bottom: 0;
right: 0;
> .icon { /*..*/ }
}
./component/progressbar/_big.scss
.progressbar--big > .progressbar__status {
font-size: 1.6rem;
text-transform: uppercase;
padding: 16px;
}
./component/progressbar/_small.scss
.progressbar--small > .progressbar__status {
font-size: 1.1rem;
text-transform: lowercase;
padding: 11px;
}
<p align="right"><a href="#contents">Top</a></p>
State
States are toggable sets of rules that:
- describe component/element states:
.is-expanded,.is-hidden,.has-error. - alternate presentation:
.is-uppercase,.is-sticky,.is-pointer.
State CSS classes usually consist of a few rules. Unlike components they do not represent entities, but modify object state.
HTML
<div class="main has-error">
<aside class="sidebar is-hidden">...</aside>
</div>
./component/_main.scss
.main {
/* default style */
&.has-error {
/* state modified style */
}
}
./base/_global-state.scss
/* Global state */
.is-hidden {
display: none !important;
}
<p align="right"><a href="#contents">Top</a></p>
Theme
Theme classes used to alternate the style of a component depending on the context.
HTML
<html class="theme-foo">
<div class="l-main">
<aside class="sidebar">...</aside>
</div>
</html>
./component/sidebar/_index.scss
.sidebar {
/* default style */
}
.theme-foo .sidebar {
/* alterntive style */
}
Programmatic Theming
If we need components to change styles according to a set theme (.theme-baz and
.theme-qux), we can use a mixin like:
@mixin theme-dialog($theme) {
$bg: get-theme-style($theme, "bg");
.theme-#{$theme} .dialog {
background-color: #{$bg};
}
}
@each $theme in $themes {
@include theme-dialog($theme);
}
Where we have in ./base/_defenitions.scss:
$themes: baz qux;
@function get-theme-style($theme, $key) {
$baz-map: (
"bg": $baz-bg
);
$qux-map: (
"bg": $qux-bg
);
@if $theme == "baz" {
@return map-get( $baz-map, $key );
}
@if $theme == "qux" {
@return map-get( $qux-map, $key );
}
@return map-get( $baz-map, $key );
}
Theme Example

<div class="theme-foo">
<article class="entry">
<h2 class="entry__heading">Lorem ipsum dolor</h2>
<time datetime="2008-02-14 20:00" class="entry__time">2 hours ago</time>
</article>
<article class="entry">
<h2 class="entry__heading">Lorem ipsum dolor</h2>
<time datetime="2008-02-14 20:00" class="entry__time">2 hours ago</time>
</article>
<article class="entry">
<h2 class="entry__heading">Lorem ipsum dolor</h2>
<time datetime="2008-02-14 20:00" class="entry__time">2 hours ago</time>
</article>
</div>
<div class="theme-bar>
...
</div>
<p align="right"><a href="#contents">Top</a></p>
<a id="a-fs"></a> File Structure
Styles
├───component
│ ├───btn
│ │ _index.scss
│ │ _primary.scss
│ │
│ └───form
│ │ _index.scss
│ │
│ ├───auth
│ │ _index.scss
│ │ _login.scss
│ │
│ └───nav
│ _index.scss
│ _search.scss
│
└───base
│ _h5b-normalize.scss
│ _base.scss
│ _definitions.scss
│ _global-state.scss
│ _animations.scss
│
└───mixin
_media.scss
<p align="right"><a href="#contents">Top</a></p>
<a id="a-nc"></a> Naming Conventions
- Class name represents source location. Let's say styles for
.form--nav--searchis expected in the filecomponent/form/nav/_search.scssFile Structure). - State classes are prefixed with
is-orhas-(e.g..is-hidden,.has-success). - Theme classes are prefixed with
theme-.
Class | Entity
----|----
.btn, .main-nav | a component (only hyphen delimited names)
.main-nav__title | element (subcomponent)
.btn--primary, .main-nav--landing-page | subclass
.is-hidden, .has-success | a state
.theme-default, .theme-garland | a theme
Further readings
<p align="right"><a href="#contents">Top</a></p><a id="a-sc"></a> Selector Conventions
Keep selectors short
Remember that browser reads selectors from right to left, long selectors may give it an extra workload. Besides it is a unwanted contribution to production style-sheet file size. Deep nesting in CSS-preprocessor sources may cause the described problems even without your awareness. So, keep nesting no more than 3-4 levels.
Avoid excessive @extend-ing in SASS/LESS. It adds a long CSS selectors in a compiled code.
Use classes for styling, IDs and data-attributes to bind JavaScript
IDs can be used in HTML for fragment identifiers and JavaScript hooks, but IDs should never be used in CSS. Functional element attributes can be quite handy for styling (e.g. input[disabled]), but we rather avoid styling via custom attributes (data-attr) for a better separation of concerns. When you use only classes for styling and keep IDs and attributes for JavaScript binding you get much more flexibility in moving styles across the document.
Loose Coupling (Tag Independence)
Avoid qualified selectors (prepended with tag). Thus you will gain additional agility in moving classes around components.
Loose Coupling (Location Independence)
Avoid long selectors with descendant/child combinators (.feed nav ul li h2). Long selectors besides harmful affect on selector performance mean that style rule-set is tied to particular location in the DOM. Independent selectors allow us to move components around our markup more freely.
<p align="right"><a href="#contents">Top</a></p>Further Reading
- When using IDs can be a pain in the class...
- [Code smells in CSS](ht
Related Skills
qqbot-channel
349.0kQQ 频道管理技能。查询频道列表、子频道、成员、发帖、公告、日程等操作。使用 qqbot_channel_api 工具代理 QQ 开放平台 HTTP 接口,自动处理 Token 鉴权。当用户需要查看频道、管理子频道、查询成员、发布帖子/公告/日程时使用。
docs-writer
100.3k`docs-writer` skill instructions As an expert technical writer and editor for the Gemini CLI project, you produce accurate, clear, and consistent documentation. When asked to write, edit, or revie
model-usage
349.0kUse CodexBar CLI local cost usage to summarize per-model usage for Codex or Claude, including the current (most recent) model or a full model breakdown. Trigger when asked for model-level usage/cost data from codexbar, or when you need a scriptable per-model summary from codexbar cost JSON.
Design
Campus Second-Hand Trading Platform \- General Design Document (v5.0 \- React Architecture \- Complete Final Version)1\. System Overall Design 1.1. Project Overview This project aims t
Security Score
Audited on Feb 25, 2026
