Scopedify: Browserify CSS Scoping

raw JSON →
1.1.1 verified Thu Apr 23 auth: no javascript abandoned

Scopedify is a CSS bundler designed specifically for the Browserify ecosystem, offering a solution for modular and scoped CSS. At version 1.1.1, released in 2016, and with no updates since, it is considered an abandoned project. It functions by transforming inline CSS or external `.css` files during the Browserify build process, applying unique attribute-based namespaces (e.g., `_scope_a68eaa6a`) to both CSS selectors and corresponding HTML elements. This mechanism aims to prevent style conflicts and pollution by isolating component-specific styles, conceptually similar to modern CSS Modules but tailored for Browserify. Key differentiators include its tight integration with Browserify transforms, support for nested and multiple scopes, and the ability to consume CSS from npm packages, albeit without default namespacing for those packages. Its reliance on Browserify and an older approach to CSS scoping means it is not directly compatible with contemporary bundlers like Webpack, Rollup, or Vite.

error Error: Cannot find module 'scopedify/transform' from '...' or 'ReferenceError: css is not defined'
cause The Browserify transform for scopedify was not correctly applied during the build, or the 'scopedify' module was not imported (required) in the JavaScript file.
fix
Ensure you are running Browserify with the -t scopedify/transform flag for CLI usage, or configure it correctly programmatically in your build script. Additionally, verify that your JavaScript file includes const css = require('scopedify') at the top.
error My npm package CSS is not getting scoped, leading to visual inconsistencies.
cause Scopedify, by default, does not namespace CSS imported directly from npm packages, as noted in its documentation. This design choice means those styles are applied globally or based on their original specificity.
fix
This is expected behavior. If you need to strictly scope styles from an npm package, you may need to encapsulate the package's output within your own scoped components or use a different, more manual method to isolate those styles. There is no direct configuration option in scopedify to force namespacing on npm-sourced CSS.
error My scoped styles are unexpectedly overridden by other styles on the page.
cause The CSS cascade and inheritance rules still apply. More specific global CSS rules (e.g., using IDs or `!important`) or inherited properties from parent elements can override scopedify's attribute-based selectors.
fix
Increase the specificity of your scoped CSS rules within scopedify where necessary to ensure they take precedence. Also, consider using initial or unset for inherited properties to explicitly reset them if they are causing unintended side effects.
breaking Scopedify is an abandoned project. Its last update was in 2016 (v1.1.1). It is not actively maintained and may have unaddressed bugs, security vulnerabilities, or compatibility issues with newer Node.js versions or browser features.
fix For new projects, migrate to an actively maintained CSS-in-JS solution (e.g., Styled Components, Emotion) or a modern CSS Modules setup with current bundlers (e.g., Webpack, Vite, Parcel).
gotcha CSS from npm packages will *not* be namespaced by default. This can lead to unexpected global styling or conflicts if those packages are not themselves designed for strict scoping, especially if they use common class names.
fix Manually inspect styles from npm packages. Consider wrapping them in your own scoped components or applying explicit overrides with higher specificity if conflicts arise. There is no direct `scopedify` option to force this behavior on third-party packages.
gotcha Scopedify is tightly coupled with Browserify. It is not compatible with modern bundlers like Webpack, Rollup, or Vite without significant custom integration (e.g., using Browserify as a sub-process) or a complete change in build tooling.
fix Ensure your project uses Browserify as its primary bundler. For new projects or those using contemporary build tools, choose a CSS scoping solution native to your preferred modern bundler.
gotcha CSS inheritance functions normally within scoped elements. Properties like `color` or `font-size` will inherit from parent elements in the DOM, potentially overriding your scoped styles if not explicitly reset or overridden with higher specificity.
fix Use the `initial` or `unset` keywords for CSS properties to reset inherited values (e.g., `color: initial;`). Be mindful of the CSS cascade and specificity when designing components to avoid unintended style bleeding.
gotcha Scopedify relies on attribute selectors (e.g., `[data-scope_a1b2c3d4]`) for its scoping mechanism. While effective, these can sometimes have minor performance implications on very large or deeply nested DOM trees compared to class-based selectors, or be overridden by more specific selectors (e.g., an `!important` rule, ID selectors) if not careful with CSS architecture.
fix Profile rendering performance in complex applications if performance becomes a concern. Ensure your scoped CSS rules have sufficient specificity to override general or global styles as intended. Avoid using `!important` in global styles that could affect scoped components.
npm install scopedify
yarn add scopedify
pnpm add scopedify

Demonstrates defining inline scoped CSS using tagged template literals and applying it to a 'bel' generated HTML tree, along with the necessary Browserify compilation command to process the transform.

const css = require('scopedify');
const html = require('bel'); // 'bel' is a common dependency for creating DOM elements in this ecosystem

// Define inline CSS using a tagged template literal
const scope = css`
  .base h1 {
    text-align: center;
    color: #333;
    background-color: #f9f9f9;
    padding: 15px;
    border: 1px solid #ddd;
    border-radius: 5px;
  }

  .base p {
    font-size: 1.1em;
    line-height: 1.6;
    margin-top: 10px;
  }

  .highlight {
    font-weight: bold;
    color: #007bff;
  }
`;

// Apply the scoped CSS to an HTML tree constructed with 'bel'
const tree = scope(html`
  <section class='base highlight'>
    <h1>My beautiful, centered title</h1>
    <p>This paragraph is part of the <span class="highlight">scoped section</span>. Its styles are isolated by Scopedify.</p>
    <div>
      <small>Additional content here also inherits the scope.</small>
    </div>
  </section>
`);

// Append the rendered HTML to the document body
document.body.appendChild(tree);

// To compile this with Browserify from the command line:
// $ browserify -t scopedify/transform index.js > bundle.js
// Then, include 'bundle.js' in your HTML file to see the effect.