Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prefix Bootstrap 4 classes to avoid css classes conflict

I am working on building small applications that will live in a website. The website that will host these applications may or may not be using a css framework. I Want to prefix all Bootstrap classes with my own unique prefix.

To avoid "ANY INSTANCE or CHANCE" of conflict I want to prefix all Bootstrap CSS classes with - let's say - "year19-" prefix. So, for example, all the col- classes would now be year19-col- and all the .btn classes would now become .year19-btn, .year19-btn-primary, etc... I know if I use the sass theme, new classes, then we would get around some of that as we can create our own prefixes using the theming approach, but JS would still remain a source of conflict if two versions of the same framework live on the same page. There was a Github project for Bootstrap 3 with the namespacing feature where you could just add your prefix in the namespace variable then compile the entire code to a CSS and JS package. Bootstrap 4 doesn't seem to have that package yet.

Also, I don't want to wrap the project with a css class. That approach is fine for some things, but not the right approach. I wouldn't even call that namespace. That is just wrapping the classes.

year19-btn-primary { then this would be whatever the code that already existed there before, not touched.}

like image 941
karimlo Avatar asked Sep 17 '25 02:09

karimlo


1 Answers

I managed to get classes prefixed for Bootstrap 5.1.3. You'll need to make the following changes before compiling Bootstrap yourself. My full implementation is available here: https://github.com/Robpol86/sphinx-carousel/tree/85422a6d955024f5a39049c7c3a0271e1ee43ae4/bootstrap

package.json

"dependencies": {
  "bootstrap": "5.1.3",
  "postcss-prefix-selector": "1.15.0"
},

Here you'll want to add postcss-prefix-selector to make use of it in postcss.

postcss.config.js

'use strict'

const prefixer = require('postcss-prefix-selector')
const autoprefixer = require('autoprefixer')
const rtlcss = require('rtlcss')

module.exports = ctx => {
  return {
    map: ctx.file.dirname.includes('examples') ?
      false :
      {
        inline: false,
        annotation: true,
        sourcesContent: true
      },
    plugins: [
      prefixer({
        prefix: 'scbs-',  // ***REPLACE scbs- WITH YOUR PREFIX***
        transform: function (prefix, selector) {
          let newSelector = ''
          for (let part of selector.split(/(?=[.])/g)) {
            if (part.startsWith('.')) part = '.' + prefix + part.substring(1)
            newSelector += part
          }
          return newSelector
        },
      }),
      autoprefixer({
        cascade: false
      }),
      ctx.env === 'RTL' ? rtlcss() : false,
    ]
  }
}

This is where the CSS will be prefixed. I'm using postcss instead of just wrapping bootstrap.scss with a class/id selector so I can use the Bootstrap 5 carousel component on Bootstrap 4 webpages (which is my use case). This will replace https://github.com/twbs/bootstrap/blob/v5.1.3/build/postcss.config.js

rollup.config.js

// ...
const plugins = [
  replace({ // ***COPY/PASTE FOR OTHER BOOTSTRAP COMPONENTS***
    include: ['js/src/carousel.js'],  // ***YOU MAY NEED TO REPLACE THIS PATH***
    preventAssignment: true,
    values: {
      'CLASS_NAME_CAROUSEL': '"scbs-carousel"',  // ***USE YOUR PREFIXES HERE***
      'CLASS_NAME_ACTIVE': '"scbs-active"',
      'CLASS_NAME_SLIDE': '"scbs-slide"',
      'CLASS_NAME_END': '"scbs-carousel-item-end"',
      'CLASS_NAME_START': '"scbs-carousel-item-start"',
      'CLASS_NAME_NEXT': '"scbs-carousel-item-next"',
      'CLASS_NAME_PREV': '"scbs-carousel-item-prev"',
      'CLASS_NAME_POINTER_EVENT': '"scbs-pointer-event"',
      'SELECTOR_ACTIVE': '".scbs-active"',
      'SELECTOR_ACTIVE_ITEM': '".scbs-active.scbs-carousel-item"',
      'SELECTOR_ITEM': '".scbs-carousel-item"',
      'SELECTOR_ITEM_IMG': '".scbs-carousel-item img"',
      'SELECTOR_NEXT_PREV': '".scbs-carousel-item-next, .scbs-carousel-item-prev"',
      'SELECTOR_INDICATORS': '".scbs-carousel-indicators"',
    }
  }),
  babel({
    // Only transpile our source code
// ...

Lastly rollup replace plugin is used to add the prefixes in the compiled javascript file. I wasn't able to find a way to just prefix the consts so I had to resort to having the entire const replaced and hard-coded with the full class names. This means you'll need to do this for every Bootstrap component that you're including in your final build (for me I just need the carousel so it's not a big deal).

like image 113
Robpol86 Avatar answered Sep 18 '25 14:09

Robpol86