I am writing this article in the spirit of the scientific principle that negative results should be published (but there is some helpful stuff later on.)
Many of us today are not developing new applications but ones which must work with, or sit within other applications that generate HTML and JavaScript. One very common example is developing a WordPress plug-in, others include portlets and working with a home-grown PHP application.
It is possible, and indeed likely, that the WordPress plug-in author wants to carefully control the appearance and positioning of the elements rendered by his plug-in. In my own case I am using a sophisticated JavaScript library that comes with its own style-sheet.
In this case it is necessary to ensure that styles declared in the outer application (WordPress theme) do not apply to the elements rendered by the plug-in. I have tried several approaches to enforcing this but have not been able to create a general solution to the problem.
The starting point for any solution is to create a named DIV To contain the HTML for the plug-in. This HTML could be static, generated by PHP (ASP) or JavaScript.
<DIV ID="myPlugin"> .... </DIV>
The next step is to create a stylesheet, or modify the stylesheet for your JavaScript library, so that it applies strictly to the contents of your div. This ensures that your own plugin’s styles only apply with your application and don’t break the outer application.
/* Simple example of a stylesheet that applies only to a single div */ /* Define attributes common to many elements */ div#myPlugin <selector 1>, div#myPlugin <selector 2>, div#myPlugin <selector 3>{ attribute1:value1 ... } /* Define attributes for library styles */ div#myPlugin .<library style 1>{ attribute1:value1 ... }
We have now protected the outer application from our plug-in, but how can we protect our plug-in from styles in the outer application?
You cannot sandbox a div from the outer application
The problem is that the outer application can always create a CSS selector that is more specific than the ones in your plug-in stylesheets. This is a fundamental problem because a well-designed plug-in stylesheet will use as few selectors as possible and rely on the CSS cascade to style the HTML elements that are rendered. Therefore in general plug-in selectors are weakly specific nd will frequently be overwritten by rules in the outer application.
The rules for calculating the specificity of CSS selectors are defined here. It should also be understood that any rule that applies to a particular element is more specific than a rule that applies to its parent. Consider this HTML fragment,
<div id="themeContent"> <div id="myPlugin"> <table class="myPlugClass1"> <tr> <td>
We might expect at the table cell, <td> Would be styled using a rule in our stylesheet
div#myPlugin .myPluginClass1{ border-width:3 /* this is essential */ }
But if the following rule exists in the theme, then that will dominate
div#themecontent <table> <tr> <td> { border-width:0 }
We can see that in general it is not possible to protect our plug-in because the author of the application theme can always write a more specific selector even after we have deployed the application.
Failed approaches
When creating a new stylesheet for an application or theme it is common practice to “reset” the browser by defining styles that set the browser to a known condition. This raises the possibility of “resetting a div”. However this is not possible, the authors of reset stylesheets have a good understanding of the default behaviour of web browsers, hence they only need to reset known values. However in our scenario we have no idea about what styles are applied by the outer application.
Final approach
The problem cannot be solved in general and even when it is solved in particular, the solution is not robust because of changes to styles in the outer application can break the plug-in.
Thus the final approach must be one of configuration management. The plug-in must be tested with a particular theme in the outer application. So for example, in the WordPress scenario it might be tested with well-known themes such as Twenty-Ten, Twenty-Eleven … .
Debugging
It is likely that your plug-in will not be styled correctly initially and you will need to create an additional stylesheet to fix issues caused by a particular theme. So for example you may have two stylesheets your plug-in,
- myPlugIn.css
- myPlugIn-Fixes-For-Twenty-Ten.css
To find out what I needed to put into myPlugIn-Fixes-For-Twenty-Ten.css I got my plug-in to render some simple tables and and lists. So for example
<table class="myPlugClass1"> <tr> <td> What style is applied to me? </td> </tr> </table>
I rendered the page and selected the cell text and then used the browser’s development tools to “Inspect element”. By moving through each of the elements in turn it is possible to see where selectors in the outer stylesheet are affecting your plug-in. So, referring back to the example above I can create a new rule in my fix stylesheet.
div#myPlugin <table> <tr> <td> { border-width:3 /* this is essential*/ }
In conclusion
CSS does not provide the ability to sandbox a div and it is not possible to robustly protect the styling of the plug-in. It is possible to manually create rules that will ensure your application is styled correctly but the solution is only robust if changes to the style-sheets of the outer application are carefully controlled.
and finally
This is a very technical area and it is possible to have made a mistake or that you have a better approach, if so the please add a comment below.
This has a great article confirming what I have been battling with for the past few days. I know the post is dated somewhat but I wanted to add to it. I mean, what would WordPress be without plugins for example.
Yet, there’s no rush to address the issue by tech community. Firstly, there’s no such thing as the perfect theme, I’ve tried around thirty so far, and many use the ‘underscores’ framework which is extremely good at providing the best possible base for theme design.
Looking for well designed base themes, I reasoned, was the safest way to rely on a theme’s integrity and the operational environment surrounding your code. The Underscores template is minimal HTML but has a full scope, addressing responsiveness, viewpoints and media types.
However, in the hands of enthusiastic developers, the theme functionality is unnecesseraly restrictive in terms of what it may be possible for the user to do with it.
The developer need only tuck away some code for handling :focus events and that’s enough to break your site. Consider :hover and :focus states that underline clickable content; it may look nice, especially the under-lining of menus, but coding generic code messes with your plugins too. It also gives the user a headache.
I mean where did modular programming techniques go. There was a time when modular programming was a state of the art. If you are going to place under-lining under your drop down menu using js, then that’s fine, but why is there the need to define that action globally, so now everything on the site has an underline, not just the menu.
For example, in your freshly installed theme, you want to transfer some lovely buttons from your last theme, but oh dear, every time there’s an onmouse: event, the button shows a black box where one should not exist.
Trying to track this with browser element inspectors will not lead you to usable classes or id tags, because the on-state event is driven by a function call, for example a simple a:focus definition is calling js code to fancify your button.
Now imaging your logo which always points to the root, because it is a link, it will now have a silly black line under it or black box popping out of its div when you hoever across it. Now conside the image is a .png and you can see how ugly the effect – there is nothing you can do about it. The developer, the reviewer and the WP guy were all out on that day.
Your buttons are now useless in this environment. I found at least three themes that I otherwise liked very much that had this issue, two of them using ‘Underscores’ templates. The first place to start looking is the initialised settings in the stylesheet, that are referred to in the original poster’s article.
Even if you redefine all selectors to have no text decoration, and no background color, and even if you redefine block elements to ‘display: inline’, it just doesn’t work.
Here is the simple css that is probably the single most powerful way to influence your link states globally, and bear in mind that states can be applied to any tag, not just anchor links a:.
a:focus,
a:active,
a:hover,
a:visited,
a:link,
a {text-decoration: none !important; background: none !important; outline:none !important;}
This just brings more !important tags to the picnic. “display:hidden” is no good in these situations as nothing at all will be shown, not even the button. Likewise removing the background will remove most of the unwanted block but not the text line height that is the js waiting state in the background.
One theme I liked so much I was adding content for hours before I realised how fragile it was. Probably the best looking code under the hood, but my gravatar just kept collapsing. Seriously, the guys at WP rely on volunteer testers and half of the themes that are on the WP database should not be there.
So all this leads to looking for answers. Sure, there are some js fixes but none worked for me. Because you cannot always influence styling that is hard coded at a higher level, and by that I am also referring to the css order of specificity.
There should be some way of putting a sandbox in place but there doesn’t appear to be. Surely to defined a unique tag and assign an id=”” to a div, should be it, but nothing works.
This is the reasoning of programmers though, because it’s easily done in most other languages, think PHP where functions operate protected within their sphere. Variables can be assigned globally but even then, a certain level of protection exists.
The realms of css can only take you so far even though keyframing has arrived, it’s still just a styling concept.
I have finally settled on a theme even though it will not allow me to place any buttons anywhere on the site. Coming across this article made me realise that there really is no way to solve the issue. There is no sandbox.
Thank you for a very interesting comment. I have found that if I just want to gain control of a single page then creating a blank page template helps. https://blog.jamesbayley.com/2015/06/03/how-to-render-a-blank-wordpress-page/
You could use something like this to accomplish this: https://github.com/premasagar/cleanslate
I have not tested this but it look very good. Thank you very much for the link.
There is one way and works great. IFRAME. You create one, write to its document’s body and resize it accordingly to the content size (body.offsetHeight). It can look like a DIV, you have complete control over the contents aspect and it is 100% sandboxed.
Absolutely awesome Vlad. I would like change the title of the case to say [Fixed]. Do you have a public facing example of this technique I could reference?