Issue #1041✓ SolvedOpened April 13, 2018by tommedema4 reactions

Optionally insert styles from StyleManager with !important

快速解答by tommedema2

added PR at #1056

Read full answer below ↓

Question

I'd like to suggest a feature that can be enabled through config: styleAsImportant: true (defaults to false, i.e. non-breaking). I thought this was already possible by configuring the cssComposer, though I've now learned that this is not the case (see below for an explanation).

I am working with templates that sometimes were generated from pre-compilers that excessively use the !important flag. For example a button in a template might be styled as:

._style_wxcCz {
  border-style: solid !important;
  margin: 0 !important;
  padding-right: 20px !important;
  padding-top: 11px !important;
  padding-bottom: 11px !important;
  background-color: #377037 !important;
  font-family: ff-clan-web-pro, "Helvetica Neue", Helvetica, sans-serif !important;
  font-weight: 600 !important;
  border-color: #377037 !important;
  border-radius: 0 !important;
  padding-left: 20px !important;
  border-width: 2px !important;
  color: #ffffff !important;
  cursor: pointer !important;
  display: inline-block !important;
  font-size: 14px !important;
  line-height: 18px !important;
  outline: none !important;
  overflow: visible !important;
  position: relative !important;
  text-align: center !important;
  text-decoration: none !important;
  text-transform: uppercase !important;
  vertical-align: middle !important
}

As a result, styling this button with Grapes has absolutely no effect. The most obvious way to make it work with grapes, is to ensure that:

  1. the grapes styling also has !important (this feature)
  2. the grapes styling comes after the template's styling (should already be the case, right?)

I guessed that the proper way would be to make CssRule.js#36 configureable. I tried to set this important flag using:

var editor = grapesjs.init(
        {
            cssComposer: { important: true },
        ... 
        }
);

But this does not seem to have an effect. Moreover, when I hardcode it to true in the code, I see that there are two issues with this implementation:

  1. it also adds !important to rules that come from the template. This feature suggestion is specifically for rules that are manually added through the style manager, because these should overwrite the template's styles. Otherwise there is no added value.
  2. it adds !important twice if there is already an important statement in rules from the template, causing the rendering to fail due to having invalid css properties:
<img width="325" alt="screen shot 2018-04-13 at 12 11 02 pm" src="https://user-images.githubusercontent.com/331833/38753659-f2020aba-3f13-11e8-9b0f-7b722f985d71.png">

Therefore my suggestion is to create a new config value styleAsImportant: true (defaults to false, i.e. non-breaking). After some initial debugging I found that this change makes this happen:

style_manager/index.js line 283:

from:

rule = cssC.add(valid, state, deviceW);

to:

rule = cssC.add(valid, state, deviceW, { important: config.styleAsImportant });

This seems to work well. It does not add !important to rules from the template, and it does add it to rules set by the style manager. This is the desired behavior.

Do you agree? Should I submit a PR?

Cheers

Answers (3)

👍 Most helpfultommedemaApril 20, 2018

added PR at #1056

artfApril 14, 2018

It might be a good idea, but what about improving those events (eg. pass model/pr to callbacks) to allow such customizations

artfApril 19, 2018

@tommedema Components and CssRules implement Styleable, therefore you would get it in all case.

do you mean that we'd have to then write plugins to listen to those events and add additional styling to the component?

Not additional, you overwrite the style triggered on that model, eg.

	// eg. your configs
	const styleImportant = 1;
	// ...
    editor.on('styleable:change', (model, property) => {
      const value = model.getStyle()[property];
      console.log('Styled ', property, value);
      if (styleImportant) {
        model.addStyle({ [property]: value + ` !important` });
      }
    });

Related Questions and Answers

Continue research with similar issue discussions.

Paid Plugins That Match This Issue

Curated by issue keywords and label relevance to help you ship faster.

View all plugins

Loading paid plugin recommendations...

Free option

Check the open-source GrapesJS plugins on GitHub or run a quick search in our free catalog.

Browse free plugins →
Premium option

Premium plugins ship with support, regular updates, and production-ready features — save days of integration work.

Browse premium plugins →

Related tutorials

In-depth guides on the same topic.

All tutorials →

Browse Plugin Categories

Jump directly to plugin category pages on the marketplace.