@brandocms/europacss

中文文档
1.0.0-beta.16发布于 2026/05/07MITCommonJS构建来源已验证近 30 天下载 2926

Europa CSS system

原始使用文档
文档目录22 节
  1. USAGE WITH POSTCSS
  2. NOTES
  3. CONFIG
  4. Token References (Design Token Aliasing)
  5. Typography
  6. AT-RULES
  7. @responsive {breakpointQuery} {block} (alias: @mq )
  8. @color {fg/bg/stroke/fill/border/border-[top|bottom|left|ri…
  9. @grid
  10. @display [displayType[/flexDirection][/flexWrap]] [breakpoi…
  11. @order {orderNumber} [breakpointQuery]
  12. `@embed-responsive {aspectRatio}
  13. @space {decl} {sizeQuery} [breakpointQuery]
  14. @font {fontFamily} [fsQuery]
  15. @fontsize {fsQuery} [breakpointQuery]
  16. ease() function
  17. @if {value} {block}
  18. @column {sizeQuery} [breakpointQuery]
  19. @iterate {iterable} block
  20. @unpack {object}
  21. LOCAL DEVELOPMENT
  22. POSTCSS PLUGINS IN USE

«On the count of ten you will be in...»

Build Status npm version


EuropaCSS originally began as a collection of SASS mixins and functions that came in handy when working with design agencies that had very specific designs over different breakpoints. These design systems translate pretty well to configurations and allows weeding out a lot of the boilerplate involved.

USAGE WITH POSTCSS

Example postcss.config.js:

module.exports = {
  plugins: [
    require('@univers-agency/europacss')({
      // You can specify your config in one of these ways:

      // 1. Default: Automatically looks for ./europa.config.js or ./europa.config.cjs

      // 2. Path to config file:
      // config: './path/to/europa.config.js',

      // 3. Direct configuration object:
      // config: { /* Your europacss config */ },

      // 4. PostCSS Preset Env options:
      presetEnv: {
        // browsers: ['> 1%', 'last 2 versions'],
        // features: { /* specific features */ },
        // preserve: false,
        // disable: false  // Set to true to disable postcss-preset-env entirely
      }
    }),
    require('postcss-reporter')({ clearReportedMessages: true, throwError: false })
  ]
}

Note: You no longer need to include autoprefixer or css-mqgroup as those are now handled internally by EuropaCSS.

NOTES

  • Remember to keep your @import statements at the top of your .css file
  • Add
@europa arrows;
@europa base;

to your main stylesheet

CONFIG

setMaxForVw

If you have a set max size for your largest container, you should enable setMaxForVw. This will ensure that the largest breakpoint of your vw based sizes will be set to a fixed size.

For instance, if you have:

{
  setMaxForVw: true,
  theme: {
    container: {
      maxWidth: {
        mobile: '100%',
        tablet: '100%',
        desktop: '1920px'
      }
    },
    typography: {
      sizes: {
        h1: {
          mobile: '18px',
          tablet: '4vw',
          desktop: '4vw'
        }
      }
    }
  }
}

we will replace the desktop key's 4vw with 1920/100*4 so that the font will not scale beyond the container's maxWidth.

dpxViewportSize and dpxViewportSizes

When working with design pixel units (dpx), you can specify reference viewport widths to convert design pixels to viewport width units. This is especially useful when working with Figma designs that are created at specific widths for different device sizes.

You can set a global reference width with dpxViewportSize, or specify different reference widths for individual breakpoints and breakpoint collections using dpxViewportSizes:

{
  // Global fallback reference width (used if no specific width is defined)
  dpxViewportSize: 1440, // Default is 1440px if not specified

  // Per-breakpoint and per-collection reference viewport widths
  dpxViewportSizes: {
    // Direct breakpoint references
    xs: 375,
    sm: 768,

    // Breakpoint collections
    $desktop: 1440,
    $tablet: 768,
    $mobile: 375
  },

  theme: {
    typography: {
      sizes: {
        heading: {
          mobile: '25dpx', // Uses 375px reference (from $mobile collection)
          tablet: '35dpx', // Uses 768px reference (from $tablet collection)
          desktop: '45dpx' // Uses 1440px reference (from $desktop collection)
        }
      }
    }
  }
}

For example, when using 25dpx at the $mobile reference viewport width of 375px, it will be converted to 6.667vw ((25/375)*100). The same value in the $desktop collection would use the 1440px reference, resulting in 1.736vw ((25/1440)*100).

When processing dpx units, Europa looks for a reference width in this order:

  1. A direct match in dpxViewportSizes for the current breakpoint (e.g., xs, md, etc.)
  2. A match in dpxViewportSizes for a collection that includes the current breakpoint (e.g., $mobile, $desktop)
  3. The global dpxViewportSize value
  4. Default fallback of 1440px

This makes it easy to maintain the exact sizing from design files while keeping the responsive behavior of viewport units across different device sizes.

Token References (Design Token Aliasing)

You can reference other theme values from within the config using {path.to.value} syntax. This is useful for creating semantic tokens that reference primitive tokens, aligning with design token systems like Style Dictionary and Figma Tokens.

module.exports = {
  theme: {
    colors: {
      red: '#f00',
      blue: '#00f'
    },

    button: {
      // Full reference — resolves to '#f00'
      primary: '{colors.red}',
      secondary: '{colors.blue}'
    },

    spacing: {
      xs: { xs: '10px', sm: '15px', md: '15px', lg: '15px', xl: '15px' },
      // Object reference — copies the entire breakpoint object
      block: '{spacing.xs}'
    },

    border: {
      // Partial interpolation — resolves to '1px solid #f00'
      default: '1px solid {colors.red}'
    }
  }
}

Full references ('{colors.red}'): When the entire string is a single {ref}, the resolved value preserves its original type (string, object, array).

Partial interpolation ('1px solid {colors.red}'): Each {ref} is string-replaced. Only works when the referenced value is a string or number.

Chained references are supported — a token can reference another token that itself is a reference.

Circular references and missing paths throw descriptive errors.

Typography

Sizes

typography sizes size_name breakpoint_name: value

Examples

A regular setup:

  typography: {
    sizes: {
      base: {
        mobile: '16px'
      }
    }
  }

If value is an object, all properties will be added to the selector, i.e:

  typography: {
    sizes: {
      base: {
        mobile: {
          'font-size': '16px',
          'line-height': 1.25
        }
      }
    }
  }

Hierarchical Typography (New in beta.6):

You can organize your typography using slash notation for better design system alignment:

typography: {
  sizes: {
    // Traditional flat structure (still supported)
    xs: { mobile: '12px', tablet: '14px' },

    // Hierarchical structure using literal slash keys
    'header/large': { mobile: '32px', tablet: '40px', desktop: '48px' },
    'header/medium': { mobile: '24px', tablet: '28px', desktop: '32px' },
    'body/regular': { mobile: '14px', tablet: '16px', desktop: '18px' },

    // OR use nested structure for path traversal
    header: {
      small: { mobile: '18px', tablet: '20px', desktop: '24px' }
    },
    body: {
      small: { mobile: '12px', tablet: '14px', desktop: '16px' },
      caption: { mobile: '10px', tablet: '12px', desktop: '14px' }
    }
  },

  families: {
    // Traditional flat structure
    main: ['Helvetica', 'Arial', 'sans-serif'],

    // Hierarchical structure using literal slash keys
    'body/regular': ['Inter', 'Helvetica', 'sans-serif'],
    'header/display': ['Playfair Display', 'Georgia', 'serif'],

    // OR use nested structure for path traversal
    body: {
      strong: ['Inter-Bold', 'Helvetica-Bold', 'sans-serif']
    }
  }
}

This allows for more intuitive usage that matches design tools like Figma:

@font header/display;        /* Uses literal 'header/display' key or header.display path */
@fontsize body/regular;      /* Uses literal 'body/regular' key or body.regular path */
@fontsize header/large/1.2;  /* With line-height */
@fontsize header/small;      /* Uses nested header.small structure */
@font body/strong;           /* Uses nested body.strong structure */

Priority: Literal string keys are checked first, then path traversal is attempted if no literal key is found.

Reduce Repetition with __base__ (New in beta.9):

Use the special __base__ key to define common properties that apply to all breakpoints, reducing configuration repetition:

typography: {
  sizes: {
    'body-large': {
      // Common properties applied to parent rule (outside media queries)
      __base__: {
        'line-height': '135.2%',
        'letter-spacing': '-0.02em'
      },
      // Breakpoint-specific properties (in media queries)
      xs: { 'font-size': '20px' },
      sm: { 'font-size': '25px' },
      md: {
        'font-size': '30px',
        'line-height': '140%'  // Overrides __base__ line-height for md
      }
    }
  }
}

Usage:

h2 {
  @fontsize body-large;
}

Generated CSS:

h2 {
  line-height: 135.2%;
  letter-spacing: -0.02em;
}
@media (width <= 739px) {
  h2 { font-size: 20px; }
}
@media (width >= 740px) and (width <= 1023px) {
  h2 { font-size: 25px; }
}
@media (width >= 1024px) {
  h2 {
    font-size: 30px;
    line-height: 140%;  /* Overrides base */
  }
}

Function Callbacks in __base__:

You can use function callbacks in __base__ to reference other parts of your theme configuration. This is especially useful for referencing font families:

typography: {
  families: {
    main: ['Inter', 'system-ui', 'sans-serif'],
    'header/display': ['Playfair Display', 'Georgia', 'serif']
  },
  sizes: {
    'body-text': {
      __base__: {
        // Function receives theme object and automatically joins arrays
        'font-family': theme => theme.typography.families.main,
        'letter-spacing': '0.01em'
      },
      xs: '14px',
      sm: '16px',
      md: '18px'
    },
    heading: {
      __base__: {
        // Works with hierarchical keys too
        'font-family': theme => theme.typography.families['header/display'],
        'text-transform': 'uppercase'
      },
      xs: '24px',
      sm: '28px',
      md: '32px'
    }
  }
}

Functions can return:

  • Arrays: Automatically joined with appropriate separator (, for font-family, space for transform, etc.)
  • Strings: Used directly
  • Supported array properties: font-family, background-image, box-shadow, text-shadow, transition, animation, filter, transform

This is particularly useful for typography styles where line-height, letter-spacing, font-family, or other properties remain consistent across breakpoints while only font-size changes.

AT-RULES

todo

@responsive {breakpointQuery} {block} (alias: @mq)

EXAMPLE:

@responsive desktop_md {
  display: none;
}

@responsive <=ipad_portrait {
  color: red;
}

You can also use @mq as a shorter alias:

@mq desktop_md {
  display: none;
}

Custom ranges with arrow syntax:

For ad-hoc media queries that don't match your defined breakpoints, use the arrow syntax:

/* Custom min and max */
@mq 359px->740px {
  font-size: 14px;
}

/* Open-ended min (no max) */
@mq 500px-> {
  display: flex;
}

/* Open-ended max (no min) */
@mq ->800px {
  padding: 10px;
}

@color {fg/bg/stroke/fill/border/border-[top|bottom|left|right]} {colorName/hex}

Tries to get colorName from theme.colors, otherwise passes the color through. Nested colors can be accessed with dot or slash notation (headings.h2 or headings/h2).

EXAMPLE:

h2 {
  @color fg headings.h2;
  @color fg headings/h2;  /* equivalent */
  @color bg transparent;
}

@grid

Sets column gap to your gutter configuration across all breakpoints.

EXAMPLE:

.my-grid {
  @grid;
  grid-template-areas: "a b"
                       "a c";
  grid-template-columns: 6fr 6fr;

  .a {
    grid-area: a;
  }

  .b {
    grid-area: b;
  }

  .c {
    grid-area: c;
  }
}

This creates a 6 columns wide stacking grid.

@display [displayType[/flexDirection][/flexWrap]] [breakpointQuery]

Add shortcut for responsive display decls.

EXAMPLE:

article {
  @display flex $mobile;
}

article {
  @display flex/row/wrap $mobile;
}

@order {orderNumber} [breakpointQuery]

Add shortcut for responsive order decls.

EXAMPLE:

article {
  @order 1 $mobile;
}

`@embed-responsive {aspectRatio}

PARAMS:

{aspectRatio}

  • 16/9

@space {decl} {sizeQuery} [breakpointQuery]

PARAMS:

{decl}

  • container (does not accept sizeQuery, only [breakpointQuery])
  • margin-x, margin-y, padding-x, padding-y
  • translateX, translateY, translateZ, scale
  • Any prop that accepts the values you give it.

{sizeQuery}

  • xs > Gets XS from theme.spacing map.
  • -xs > Gets negative value of XS from theme.spacing map.
  • 2 > Gets 2 times the gutter padding.
  • 1/3 > Calcs a fraction.
  • 3:1/6 > Calcs a 3/6 fraction but with 1 added gutter unit
  • xs/2 > Gets half of the XS from theme.spacing map.
  • between(20px-50px) > Scales the value from 20px at the start of breakpoint to 50px at the end of breakpoint.
  • container > Gets value from theme.container.padding for breakpoint.
  • -container > Gets negative value of theme.container.padding for breakpoint.
  • vertical-rhythm(theme.typography.sizes.xl) > Grabs object for breakpoint and multiplies with default line-height.
  • vertical-rhythm(theme.typography.sizes.xl, 1.2) > Grabs object for breakpoint and multiplies with 1.2 as line-height.
  • calc(100vw - var[container] + var[1]) > Switches out var[container] and var[1] with correct values for container padding and 1 gutter unit per breakpoint.
  • 20dpx > Design pixel units that scale with viewport width based on the dpxViewportSize setting (defaults to 1440px).
  • negate(currentGap, desiredGap) > Negates the current gap and adds the desired gap. Used to override flex column gaps on individual children. Always outputs margin-top. The desired gap can include arithmetic: negate(block, block+xs), negate(block, block-2vw).

EXAMPLES:

.block {
  @space margin-y xl/2;

  &:first-of-type {
    @space margin-top xl;
  }

  &:last-of-type {
    @space margin-bottom: xl;
  }
}

.overlap {
  /* Use negative named spacing to create overlaps */
  @space margin-top -block;
}

.flex-column-child {
  /* Override flex column gap: negate the parent gap and add desired gap */
  @space negate(block, 25px);
  /* Or use expressions: negate(block, block+xs) */
}

.powerful-stuff {
  /* move element 4 columns + a gutter size to the left */
  @space translateX calc(var[4:1/12] * -1);
}

If you need the set properties to be marked as !important you can use @space!

  @space! margin-left xs;

@font {fontFamily} [fsQuery]

Selects a font family. Can also be passed a font size query.

PARAMS:

{fontFamily}

  • picks fontFamily from typography.families
  • Hierarchical keys: Use slash or dot notation for organized typography (e.g., body/regular or body.regular, header/display or header.display)
  • Both notations support path traversal (e.g., body/regular and body.regular both work for 'body/regular': [...] and body: { regular: [...] })

[fsQuery]

  • can also be passed. Will then create a @fontsize rule with fsQuery as params

Example with hierarchical typography:

@font body/regular;        /* Uses 'body/regular' from families config */
@font header/display xl;   /* Uses 'header/display' font with 'xl' size */

@fontsize {fsQuery} [breakpointQuery]

PARAMS:

{fsQuery}

  • lg > Picks the lg key from theme.typography.sizes across breakpoints
  • lg/2.0 > Also sets line-height to 2.0
  • lg(2.0)/2.0 > Adds a modifier (2.0) that gets used as a multiplier in a calc() for the final font-size.
  • between(18px-22px) > Responsive font sizing, from 18px to 22px. Needs a breakpoint to function properly.
  • product.size or product/size > Traverses the keypath product.size within theme.typography.sizes
  • 20dpx > Design pixel units that scale with viewport width based on the dpxViewportSize setting (defaults to 1440px)
  • Hierarchical keys: Use slash or dot notation for organized sizes (e.g., header/large or header.large)
  • Both notations support path traversal (e.g., header/large and header.large both work for 'header/large': {...} and header: { large: {...} })

[breakpointQuery]

  • xs > Only for the xs breakpoint
  • >=md > Only for larger or equal to md

Example with hierarchical typography:

@fontsize header/large;        /* Uses 'header/large' size from config */
@fontsize body/small/1.5;      /* Uses 'body/small' size with line-height 1.5 */
@fontsize header/large >=md;   /* Responsive: header/large for md and up */

Note: The parser intelligently differentiates between hierarchical keys (e.g., header/large) and line-height syntax (e.g., 24px/1.5) by checking config keys first.

ease() function

Provides easing functions as CSS cubic-bezier values. This function can be used in any CSS property that accepts transition-timing-function values.

PARAMS:

type

  • Standard: ease, ease.in, ease.out, ease.inOut
  • Sine: sine.in, sine.out, sine.inOut
  • Quad: quad.in, quad.out, quad.inOut
  • Cubic: cubic.in, cubic.out, cubic.inOut
  • Quart: quart.in, quart.out, quart.inOut
  • Quint: quint.in, quint.out, quint.inOut
  • Expo: expo.in, expo.out, expo.inOut
  • Circ: circ.in, circ.out, circ.inOut
  • Back: back.in, back.out, back.inOut
  • Power1-4: power1.in, power1.out, power1.inOut through power4.in, power4.out, power4.inOut

EXAMPLES:

.element {
  transition: transform 300ms ease('power3.out');
}

.another-element {
  transition: opacity 500ms ease('sine.inOut'), transform 800ms ease('back.out');
}

Note: If an invalid easing name is provided, an error will be thrown during CSS processing.

@if {value} {block}

Renders {block} if {value} is true. Ignores it otherwise.

PARAMS:

{value}

  • theme.typography.optimizeLegibility > Checks value in theme config.

EXAMPLES:

@if theme.typography.optimizeLegibility {
  article {
    text-rendering: optimizeLegibility;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
  }
}

@column {sizeQuery} [breakpointQuery]

Creates a flex column inside rule.

PARAMS:

{sizeQuery}

  • 1/3 > Takes up one third of container, across all breakpoints
  • 3:1/6 > Takes up one third of container, across all breakpoints, with 1 unit of gutter
  • calc(var[container] + var[6/12]) > 6/12 columns + width of container gutter

[breakpointQuery]

  • xs > For xs breakpoint only
  • xs/sm/xl > For xs, sm and xl breakpoints
  • <=md > Less and equal to the md breakpoint

EXAMPLES:

article {
  @column 1/3;
  @column 3/3 xs;
}
/* Column is 1/3 wide on all devices, except xs, which is 3/3. */

@iterate {iterable} block

Iterates through a config object.

PARAMS:

{iterable}

  • a path in the theme.object, I.E theme.header.padding.small

EXAMPLES:

article {
  @iterate theme.header.padding.small {
    @responsive $key {
      padding-top: $value;
      padding-bottom: $value;
    }
  }
}

This creates a media query for each key in theme.header.padding.small

@unpack {object}

Unpacks a config object.

PARAMS:

{object}

  • a path in the theme object, I.E theme.typography.sections.navigation

EXAMPLES:

article {
  @unpack theme.typography.sections.navigation;
}

results in

  @media (min-size: 0) and (max-size: 749px) {
    article {
      font-size: 1.2rem;
      line-height: 1.6;
    }
  }

  @media (min-size: 750px) and (max-size: 1039px) {
    article {
      font-size: 1.4rem;
      line-height: 1.5;
    }
  }

  /* ... */

LOCAL DEVELOPMENT

To test a local development version of EuropaCSS in a real project without publishing, use pnpm's file: protocol. Do not use pnpm link — it creates a symlink that causes the plugin to resolve its own postcss instance instead of sharing the project's, which leads to silent processing failures.

In the consuming project's package.json:

{
  "devDependencies": {
    "@brandocms/europacss": "file:/path/to/europacss"
  }
}

Then run pnpm install. After making changes to the plugin source, rebuild (yarn build) and run pnpm install in the consuming project to pick up the changes.

When done, switch back to the registry version:

{
  "devDependencies": {
    "@brandocms/europacss": "1.0.0-beta.14"
  }
}

POSTCSS PLUGINS IN USE

This would not be possible without the following great plugins:

  • postcss-extend-rule
  • postcss-functions
  • postcss-nested
  • postcss-preset-env
  • postcss-combine-duplicated-selectors
  • postcss-nesting

版本与发布记录

@brandocms/europacss 共发布 33 个版本,首次发布于 2021/03/17;过去 12 个月发布了 6 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.0.0-beta.16latest2026/05/076 个月前
1.0.0-beta.152026/05/056 个月前
1.0.0-beta.142026/02/258 个月前
1.0.0-beta.13beta2026/02/258 个月前
1.0.0-beta.122026/02/188 个月前
1.0.0-beta.112025/12/1110 个月前

关于 @brandocms/europacss 的常见问题

@brandocms/europacss 是什么?

Europa CSS system

如何安装 @brandocms/europacss?

在项目目录运行 npm install @brandocms/europacss,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:postcss(^8.0.5)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@brandocms/europacss 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/brandocms__europacss 是否存在。

@brandocms/europacss 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@brandocms/europacss 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=14.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@brandocms/europacss 可以商用吗?

@brandocms/europacss 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@brandocms/europacss 的下载量有多少?

根据 npm 官方下载统计,@brandocms/europacss 在 2026/10/09 – 2026/11/07 这 30 天内被下载 2,926 次,日均约 98 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@brandocms/europacss 还在维护吗?

最新版本 1.0.0-beta.16 发布于 2026/05/07(6 个月前);至今共发布 33 个版本,其中过去 12 个月发布了 6 个;首次发布于 2021/03/17。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。