Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Namespace CSS? #391

Closed
tomichal opened this issue Oct 6, 2017 · 15 comments
Closed

Namespace CSS? #391

tomichal opened this issue Oct 6, 2017 · 15 comments
Labels

Comments

@tomichal
Copy link
Contributor

tomichal commented Oct 6, 2017

Hi there,
Is there a way to setup the grapesjs editor such that the CSS generated for the HTML content is namespaced? In other words, how to avoid the style rules defined for the content created/edited in the editor to leak out to the rest of the website page?

In the case of my website the user can edit a large part of the page, but not all of it - the rest of the page HTML content and CSS is dynamically generated by the server (this is a Rails + Angular site).

I find that if e.g. I use a row with columns, the CSS generated by grapesjs editor will have a definition for a "row" class (i.e. ".row { ... }"). However, I use a CSS library that provides its own definitions for a "row" class, and so the grapesjs definition conflicts with my site-wide CSS.

Thanks for any help and tips to this issue!

@artf artf mentioned this issue Oct 9, 2017
32 tasks
@artf
Copy link
Member

artf commented Oct 9, 2017

Hi @tomichal at the moment it's not possible but I think it's a good feature, so I'll add it to the Roadmap

@artf artf added the feature label Oct 9, 2017
@tomichal
Copy link
Contributor Author

tomichal commented Oct 9, 2017

OK, thanks @artf

@danfitz36
Copy link

do you think you could just prefix all class names generated by grapejs? if instead of .row you use .grape-row or whatever (i'd probably make the prefix a variable), you'll mostly get the effect that @tomichal is after.

@tomichal
Copy link
Contributor Author

Adding a prefix per @danfitz36 suggestion sounds great from my POV.

@webnoob
Copy link

webnoob commented Feb 11, 2018

I think this should go further than just pre-fixing with grapesjs-. For instance, I have created 2 templates which I would like to display side by side on the same page. If I could specify a namespace per template / grapesjs editor instance then it would mean there would be no danger of the templates styling crossing.

@grizzm0
Copy link

grizzm0 commented May 23, 2018

Is there any ETA on this?

I guess I have to parse the CSS in PHP and prefix each selector with a scope or similar for now.

@danfitz36
Copy link

danfitz36 commented May 23, 2018

The templating could just have a top level class so you’d reference ‘.template .grapejs-button’. No need to add it to every component

@grizzm0
Copy link

grizzm0 commented May 23, 2018

For anyone that are using PHP as a save handler you could do the following using this lib https://github.com/sabberworm/PHP-CSS-Parser.

$prefix = '#scope-01';
$parsedCss = (new Sabberworm\CSS\Parser('.foobar { color: red; }'))->parse();

/** @var Sabberworm\CSS\RuleSet\DeclarationBlock[] $blocks */
$blocks = $parsedCss->getAllDeclarationBlocks();

foreach ($blocks as $block) {
    /** @var Sabberworm\CSS\Property\Selector[] $selectors */
    $selectors = $block->getSelectors();

    foreach ($selectors as $selector) {
        $selector->setSelector($prefix . ' ' . $selector->getSelector());
    }
}

$output = $parsedCss->render();

@artf
Copy link
Member

artf commented May 23, 2018

Actually, you can add a listener on new selectors and add a prefix there

    const prefix = 'myprefix-';

	editor.on('selector:add', selector => {
		const name = selector.get('name');

      	if (selector.get('type') === editor.SelectorManager.Selector.TYPE_CLASS && 
			name.indexOf(prefix) !== 0) {
			selector.set('name', prefix + name);
      	}
    });

@karacaenes
Copy link

karacaenes commented Jan 17, 2019

I just wrap all css generated by grapes in a wrapper class then compile it to css with node-sass

.wrapper-classname {
//style generated by grapesjs goes here
}

@VadimsBD
Copy link

I just wrap all css generated by grapes in a wrapper class then compile it to css with node-sass

.wrapper-classname {
//style generated by grapesjs goes here
}

How did you do the wrapping part?

@devmohitagarwal
Copy link

HI,
People looking to sandbox, prefix the exported CSS can give this a try, we had the same use case and took the sass approach.

To do so, I used sass.js (https://github.com/medialize/sass.js/)

Steps:

  1. enclose the cssString with your custom class. say MyCustomClass.
  2. Run sass.compile from the above library to convert the scss to css which is now sandboxed with the class given() ,

This way you wont face the issue of conflicts.

This answer was copied from another question. #2363

@electrotype
Copy link

This is my current hack. It's ugly but seems to work:

let cssPrefix = 'yourPrefix-';
let editor = // create the editor...

let getNewIdOriginal = editor.DomComponents.Component.getNewId;
editor.DomComponents.Component.getNewId = (list) => {
  let id = getNewIdOriginal(list);
  return id.startsWith(cssPrefix)? id : cssPrefix + id;
}; 

@abalyan-quotient
Copy link

@artf What if we add the prefix to all the pre-defined CSS names in the code itself. something like .gjs-row and for the other components.

I can work on it and send a PR for this.

@artf
Copy link
Member

artf commented Feb 24, 2020

@abalyan-quotient the namespacing feature should be applied (configurable) at the CssGenerator level

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

10 participants