Javascript Widget Affecting Style of the Page it is embedded in - css

I'm currently developing a widget that can be embedded within a page. However, when embedded, it affects the style (font, text, layout, etc.) of the page it is embedded in.
I wonder how Clearspring and other widget frameworks encapsulate their widgets so as not to affect the embedding page.
Thanks.

Make your widget, say under one div with a unique Id (or class if there will be multiple) that is least likely to clash with others on the host page. A good example might be #company-widjet-name. See how jQuery UI does it (.ui-widget input).
Then you might need to perform a sort of localised reset, to avoid the parent page's CSS from stuffing up your design. Modify something like Eric Meyer's reset to suit. Please avoid the #uniqueId * { padding: 0, margin: 0 } as it can cause headaches.
As long as you do
#uniqueId a {
property: value;
}
The specificity should be strong enough to style the elements correctly without letting the host page's CSS from changing it unintentionally.

Related

Switch background colors between active/inactive tabs

I'm migrating my site from Bootstrap to Tailwind 3 and, in the process, built-in solutions (Dropdown, Tabs, Accordion...) needed to be replaced with alternatives. The section I'm working on right now is a custom Comments Editor I created.
I'll leave a link to what Tailwind's Playground generated for me in a CodePen because the code is longer than the maximum number of allowed characters here. The decision to create a Pen is only because in the Playground it doesn't work as the anchors open in new windows/tabs.
Anyway, the code that really matters, what makes the tabs work, is this one:
[data-target] {
scroll-margin-top: 10rem;
}
[data-target]:last-of-type + [role="tabpanel"], :target + [role="tabpanel"]{
display: flex;
}
[role="tabpanel"], :target ~ [data-target]:last-of-type + [role="tabpanel"]{
display: none;
}
As the title says, I'm looking for a way to change the background-color of the tabs, hinting to the User which one is currently active.
To accomplish that, I would need to switch Tailwind's bg-color-0 with bg-color-100 and take border-b-color-0 out of the once active tab and give it to the new one. But I don't know if I can do that only with CSS.
Not add/remove the classes per se, only their corresponding styles
I've seen a lot of implementations of Pure CSS Tabs, and all of them used hidden <input> fields. Though this implementation doesn't use them, I've added and named them accordingly, but I could only target them with CSS if the User clicked exactly where they're positioned (top-left of the tabs) instead of any part of them.
I'm aware I'll eventually have to add JS to switch the ARIA attributes, but is the basic functionality possible to be accomplished with CSS only? If not, is there an alternative implementation with which I could?
Thank you for your time :)

How-to style links without crashing Admin UI?

I've problems related to how-to-separate-apostrophe-syles-from-the-front-end-template.
How can I style <a>-tags without breaking the Admin UI?
Do I have to give each <a> in my own widgets a style-class <a class="mystyle">?
What's the way to style the links of the provided richtext-widget?
Do I have to use .apos-rich-text a to stop changing the admin-control ui of the widget?
Because the following breaks the Admin UI.
.custom-main-container a:hover {
color: #ffffff !important;
}
The menus texts become white on hover and can't be read.
What's the way to handle the styling and to be sure you don't oversee anything?!
The Apostrophe dev team typically stays away from styling at the element level for exactly this reason, however CKEditor doesn't allow you to apply classes on links easily.
An easy and tight way to scope styles to the a element and not interfere with Apostrophe's admin UI is to add a project level class to the rich text widget wrapper.
In your project level /lib/modules/apostrophe-rich-text-widgets/views/widget.html
<div data-rich-text class="apos-rich-text MY-RICH-TEXT">{{ data.widget.content | safe }}</div>
Then in your CSS you can write
.MY-RICH-TEXT a:hover { //whatever }
Be sure to leave data-rich-text in the wrapper, Apostrophe is using that attribute to enhance the widget on the front-end.
My shame... the problem is the !important above.
This makes the specificity too high. Somehow I didn't get this too my mind before.
Although it would be great if the admin UI would get more specificity so that it is not so easy to overwrite its rules by 2 class-selectors.

BEM - Where to include modifiers for specific pages?

I am trying to use BEM naming convention and having some slight difficulty in deciding where to include a modifier for a specific page.
For example, say I have an orange button:
<button class="btn btn-orange">Button A</button>
My project has 3 different pages:
- pageA.html - pageA.scss
- pageB.html - pageB.scss
- pageC.html - pageC.scss
On pageB.html the button should have a margin-top:30px. Is it correct to write the modifier this way:
.btn {
padding: 5px 20px;
background: orange;
margin: 0
&--margin-top {
margin-top: 30px;
}
}
And what is the best way to include a modifier like that only for a specific page? In this case that would be for pageB.html. Should I include that modifier inside the pageB.scss or .buttons.scss?
I think you're confusing two concepts here - BEM, which is Naming Convention with the problem of structuring your projects. Both have nothing to do with each other, and I think BEM is not opinionated in terms of structuring your SASS files.
But, there's a couple of questions you ask here:
Is it correct to write the modifier this way? - it is correct if you want to stick to BEM convention, although I would say, the name you picked .btn--margin-top might not be very fortunate in a long term - imagine, you'll want to include another btn modifier with margin-top property set to, let's say 40px. How will you name it?
What is the best way to include a modifier like that only for a specific page? - These CSS classes you are usually not making for specific page. Whole point of BEM is to enable you, to write more modular CSS, and having this in mind you should use these CSS classes, by assigning them to your Blocks/Elements/Modifiers respectively. Trick here is to determine what is a block/element/modifier in your markup. What you'll achieve by this is reusable CSS, so you can quickly apply same css, by adding BEM classes.
Think in terms of Blocks or Components, NOT pages. You want to use it only on pageB - just add btn--margin-top class to your pageB markup.
Should I include that modifier inside the pageB.scss or .buttons.scss? - it depends on how you structure your project, and I would say that usually, buttons and other UI elements, are in most cases common to whole website/webapp, so there is no need of having them "attached" to specific page (which concept I think you need to drop, if you want to take full advantage of BEM). Besides, whatever suits you will be good for you, and unless you're not working within a team of developers, just stick to your own method, so you'll know in future where to look for things.
In production sites I solve this problem by using a file for the page that is deliberately more specific.
The other answerer is correct, BEM doesn't solve this problem but the solution is available in the css architecture.
I tend to structure projects as follows:
modules
sections
pages
with each getting more specific.
A section might have some specific way of rendering a button, in which case the sass would be like this:
.section {
.button--primary {
// styles
}
}
For a page, the same, but with a page specific key:
.page {
.button--primary {
// styles
}
}
You could even do:
.page {
.section {
.button--primary {
// styles
}
}
}
The key is keeping on top of the specificity in the structure of you sass files. Your button file would not change and you could be sure of dropping it in anywhere in the HTML of your site and having it render correctly and, as a module, it should only contain styles you would want to apply site-wide. For example:
.button--call-to-action {
background-color: $brand-colours__call-to-action;
}
(the hyphens are used to denote that call-to-action is a variation of button and the underscores to denote that call-to-action is one of a set of colours that belong to brand-colours)
Your margin top would then be defined simply as margin-top: 20px; in part of your sass that limited it's effect to the desired portion of the site.
As an aside, usually find that almost everything in the specific page files can be refactored further up the chain into variations of sections and modules, meaning often that they end up empty.

Avoid overriding by css

I have created a UI (for wordpress plugin) in which I give user choice to add text, image, and video in a div ( lets call this div, container).
I have been working on it for a quite sometime. I recently added tinyMCE (WYSIWYG editor) to add text inside container.
Now, I realized that I did a big mistake. The text user writes is being overridden by css rules defined for wp admin panel.
for example,
User enters <h1>Hello</h1> (with the help of tinyMCE), and then I grab that content from tinyMCE and append that in the container.
But here the problem arises, wordpress's admin css can have css rule like this,
h1 {
color : #d6d6d6;
line-height: 40px;
font-size: 30px;
}
So, it looks different in tinyMCE and in my container. (as tinyMCE's code is inside iframe and that remains unaffected by wordpress's css rules, but my container doesnt)
I want something so that any element inside container remains unaffected by wordpress's admin css.
I know a good solution would be putting container inside iframe. But I have written a lot of code without thinking of an iframe and I would need 3-4 days just to adjust everything for iframe. There may be some cross browser issues.
I can reset some wordpress rules, but it will fail sometimes, as user may enter anything. I need something fullproof.
well if you want to undo a specific rule (say the h1 rule you mentioned) you can use css to override it by being more specific.
.container h1 {
color:#000000;
line-height: 24px;
font-size: 24px;
}
This will overwrite the css rule you mentioned with the given values but only when the element is inside the container class, (I'm guessing at the default values you want to use.)
Unfortunately you would have to add in an undo rule for everything that wordpress's admin css changes.
Another possible solution is to edit the page tinyMCE returns in it's frame to add in wordpress's CSS file. This means the end user will see the same formatting when they enter the information as when it gets posted.
Do you have code-level access to the iframe contents tinyMCE creates?
Use !important in your CSS document. This way your CSS will not be overridden as it takes precence over everything, including inline styles.
h1 {
color:#ff0 !important;
}

css shield for widget

I'm creating a bookmarklet. It will display a widget on page. However, some existing css on page can effect to my widget. How to avoid this? I don't want to use iframe.
Use a localised reset.
Take an existing CSS reset (or roll your own), and namespace it by putting your widget's id (or class) in front of it.
Example
HTML
<div id="my-bookmarklet-panel">...</div>
CSS
#my-bookmarklet-panel a,
#my-bookmarklet-panel div,
#my-bookmarklet-panel span {
/* Reset rules */
}
make use of the !important statement in our widget CSS to protect your rules from overriding.

Resources