How do I sandbox a particular element on a web page? - javascript

I have this thing on my webpage... I guess it could be called a widget...
How do I separate it's CSS and JS from the containing page's CSS and JS? preferably without using an iframe?
In my app the user can customize the CSS of the content, so, I'd need a clean slate.

On the outermost element of your widget, set a relatively unique class name. For example:
<div class="my_spiffy_widget">
<!-- Insert spiffy widget here -->
</div>
Put the Javascript and CSS in their own files. For the CSS, structure all of your selectors like this:
.my_spiffy_widget P { /* paragraph rules */ }
.my_spiffy_widget A { /* anchor rules */ }
.my_spiffy_widget UL { /* unordered list rules */ }
That ensures your rules do not accidentally get overridden by other CSS rules.
Likewise with the JavaScript, prefix your functions with a common, distinctive prefix:
function my_spiffy_widget_doSomething() {...}
Avoid global variables if possible, but if you cannot, prefix them as well:
var my_spiffy_widget_firstTime = true;

You could add the !important declaration in the properties, making it harder for the user to override the settings.
eg:
div.widget #header {
padding-left: 10px !important;
padding-right: 5px !important;
}
And/or you could grab a CSS reset script (such as Eric Meyer's) and preface each selector with the name of your container DIV.

You can give all elements outside very complex css class names and make sure they don't collide with the ones the user will choose (like "KAFHxyz_..."). This way, all sane class names and default styles will only apply to the "widget".
This will be some effort since you'll need to set all the standard CSS styles using !important (so the user can say "body { font ... }" and it will only apply to his area.
Alternatively, you could try to write some javascript which fetches all styles of all elements, then add the "widget" (and it's JS/CSS) and then reset all styles to what they were before. Should be possible but the performance will probably suck.
[EDIT] That said, you do know that you can create an iframe with JavaScript and manipulate the content (the DOM inside) to your hearts content, yes? In this scenario, the IFrame will just be a Div-like element which adds a "namespace" for CSS and JS files.

Related

What do multiple css classes do?

My application uses multiple classes using CSS modules.
open is a boolen variable to determine if Paper should shift or not.
<Paper className={`${classes.paper} ${open && classes.paperShift}`}>
Question: Why are multiple classes being used, and how can they render differing results?
Note, I looked at this other post: using css modules how do I define more than one style name
The rules of each CSS class are simply combined together by the browser and all the rules are applied to the element. (If any of the rules contradict each other, the browser will decide which has precedence - if you learn more about CSS you can start to understand how that works in detail).
So, multiple classes can be used to apply various different styles to an element at the same time. Those rules might be split up into different classes to make the visual design more flexible and the rules more re-usable.
Classes defined on an element can potentially also be used by JavaScript code to select certain elements (or groups of elements) in order to perform actions on them or get information from them.
Those are HTML classes, not CSS classes.
It just means that the element is a member of multiple classes.
Anything (CSS, JS, anything else) that tries to reference the element by either class will find it. Anything that tries to reference by both classes will find it.
console.log(Array.from(document.querySelectorAll('.one')));
console.log(Array.from(document.querySelectorAll('.two')));
console.log(Array.from(document.querySelectorAll('.one.two')));
.one {
font-family: monospace;
font-size: 1.5em;
}
.two {
background: yellow;
}
<div class="one">one</div>
<div class="two">two</div>
<div class="one two">one two</div>

Consternation on testing non-inherited-yet-inherited CSS display property

I have created a modal component in Angular. In a unit test, the modal is appearing in the DOM as shown:
However, I start out with a style on app-modal2 that includes display:none, so what actually renders is just the fixed text above the modal -- the content of the modal is correctly omitted:
When the user takes an action that adjusts the style to include display:block then the content of the modal correctly appears. Which is to say, the code is working exactly as I expect.
What I am confounded about is a unit test.
So: why my title ("Consternation on testing non-inherited-yet-inherited CSS display property") ?
Well, according to the docs, the display property is NOT inherited:
Using browser dev tools, I have confirmed that is true: descendant elements have values other than none for the display property. So even though descendant elements are affected by an ancestor having display: none it is because the subtree rooted at the ancestor is removed -- and this is not considered inheritance. Well, OK, potayto, potahto... Not technically inherited, but acts like it.
The visibility of my modal is controlled by the display property. It is set either to display: none or display:block depending on user actions. But that is strictly dealing with visibility, not existence. That is, #myContent is present with either display value. Since I therefore cannot test for existence of #myContent I must test strictly for visibility.
So how do I check an element for visibility controlled by some ancestor's display value, since display is not inherited? Is there a way to check for any ancestor having display:none? Or is there some other way to do this?
You can try using the jQuery parent() method, and put the style as the first argument.
I found out pretty disturbing your question. I think is one of the most hard questions to answer because goes right to the core of cascading and inheritance.
As far as I could find, display property is the only property that can't be specified (but computed) on how should be display by UA. HTML tags are pre-defined styles, those styles are display on UA without any CSS file, e.g. p elements are display as inline.
I tested it too with devtools; forgetting JS at all for very front-end purposes. (Maybe I'll check with with JS later as -second part-). This answer is intended for all audiences, newbies and experienced devs.
Before declare what is going to be styled, we may note that we have dependencies from the browser (User Agent) that parses the stylesheet.
We do not define all universe of properties to be styled, so when is not defined, a property needs to be set and the user agent roles to set a property (doesn't have to be its initial value), there's no official specification on how UA must render websites, it's expected them to be display as the stylesheet specifies, which often, does not act likely according browsing experience.
Cascading
One of the fundamental design principles of CSS is cascading.
What does an User Agent (UA) cascades? Elements? Properties? Objects?
Well, UA treat HTML tags as elements, and those elements are called as box tree, as the same, text included inside an element are called as text node.
Since CSS syntax and its parsing is a perfect cascade, that is the only word that remains if we need to figure out about how (UA) must display HTML documents. The UA also applies its own style sheet. This means that rendering also depends on the way (units) we use to specify values, if we specify a lot of different values e.g. pixels, cm, percentages, relative units (em, rem), etc, the more information UA needs to parse to be displayed, that's why front-end developers should be encouraged to perform clean css styles with homogeneous units to squeeze every milisecond out of browsing perfomance (such important in mobile experiences).
Inheritance
When no declarations try to set a the value for an element/property
combination. In this case, a value is be found by way of inheritance
or by looking at the property’s initial value.
What is called for inheritance, it's just the css properties that can be inherited (those are already established).
So, if a css property seems to be inherited, it's not really inheritance behavior, it's cascading behavior, and it's inheritance becomes by the nature of the syntax for the specified css property.
Answer
The display property is not inherited, but when none property is set, all the descendants elements will no generate any box-model subtree nor text node, (JS could be forcing the element to be display for testing purposes).
In the case of display:none; when the box tree and text node descendants are hidden by the parent element, the style applied of none is by cascading, not by inheritance.
In the example below, the span that is descendant of the fourth div element has set the background property as inherit, but the background can't be inherited, that's why the span element does not display any color background. Otherwise, the span that is descendant of the third div element inherits the color property. The fourth div element has display set: inline; once again, display can't be inherited, that's why the span element does not inherit that property and is displayed as block by the UA.
*{
border: 1px solid black;
}
.one {
display:block;
}
.two {
}
.three{
background:cornsilk;
}
.childthree{
color:red;
}
span{
background: inherit;
position: relative;
top:80px;
border: 5px solid black;
padding: 5px;
margin:5px;
}
.four{
display:inline;
}
canvas{
background:#99e6ff;
}
html {
padding:1em;
}
<div class="wrapper">
<div class="one">one</div>
<div class="two">two</div>
<div class="three">three
<div class="childthree">I'm a subtree inside the third div<br><span>I'm span tag</span></div>
</div>
<div class="four">four<p>i'm a p tag with thext content<span>I'm a span element inside a p element</span></p</p>
<canvas></canvas>
</div>

Can I use JQuery with inline html? If so how?

I learned html and css a week ago. I completed my first project only to find that a div tag I used was not resizing to mobile formats. I have done some research and it seems the answer may reside with JQuery or .JS. I am working within a contained environment, Wordpress.com, and I don't know Java Script yet, but I am familiar with if then statements from studying logic for years.
So I effectively have two problems:
Can I use JQuery with inline html: no css?
How do I do it?
I know I am way off here. I am in the process of going through a .JS tutorial on codeacademy, but I am not finished.
Just thought I would try for advice here. I may not even be in the ballpark!
Here is my div tag and here is what I attempted:
<div style="width:950px;height:5px;background-color:#FFFFFF;"></div>
$(window).resize(function() {
if ($(this).width() < 951) {
$('.divIWantedToHide').hide(<div style="width:950px;height:5px;background-color:#FFFFFF;"></div>);
} else {
$('.divIWantedToHide').show(<div style="width:450px;height:5px;background-color:#FFFFFF;"></div>);
}
});
Javascript is kind of over-kill for this kind of thing.
I would suggest using CSS media queries.
Paste this in and it should work just fine :)
<style>
#YourDiv{
height:5px;
background-color:#FFFFFF;
}
#media only screen and (min-width:951px){
#YourDiv{width:950px;}
}
#media only screen and (max-width:950px){
#YourDiv{width:450px;}
}
</style>
<div id="YourDiv"></div>
Instead of having your style defined in the div tag, your div now has a unique name (an id) that can be styled separately. This is incredibly useful, and most would argue necessary, once you start building more complicated pages. The #media tags do basically the same thing as your if statements, where min-width:951px will set the style when your window is AT LEAST 951px and max-width:950px sets the style when your window is AT MOST 950px. The rest of the styles that don't change are set above ONE time because they are the same regardless of window size.
And now, just for fun I'll show you how to do it in pure Javascript as well:
http://jsfiddle.net/AfKU9/1/ (test it out by changing the preview window size)
<script>
var myDiv = document.getElementById("myDiv");
window.onresize = function(){
var w = window.innerWidth;
if (w > 600){
myDiv.setAttribute("style",'position:absolute;height:50px;background-color:#CCC;width:400px;' )
}
else{
myDiv.setAttribute("style", 'position:absolute;height:50px;background-color:#333;width:100px;' )
}
}
</script>
$('.divIWantedToHide').hide() will hide the div !!
In order to apply css to this div you need to use css:
$('.divIWantedToHide').css('width':'950px','height':'5px','background-color':'#FFFFFF');
If you want to append any div and apply css to it then use append/html
$('.divIWantedToHide').append('<div style="width:950px;height:5px;background-color:#FFFFFF;"></div>');
or
$('.divIWantedToHide').html('<div style="width:950px;height:5px;background-color:#FFFFFF;"></div>');
No, at wordpress.com you won't be able to use inline JavaScript. Not in regular posts using the HTML editor nor using the Custom Design upgrade that only includes a CSS editor.
Maybe you'll benefit from the following:
Preprocessor
WordPress.com has support for CSS preprocessors LESS and Sass (SCSS Syntax). This is an advanced option for users who wish to take advantage of CSS extensions like variables and mixins. See the LESS and Sass websites for more information. You can select which syntax you would prefer to use at the bottom of the Appearance -> Customize -> CSS panel.
If you want to resize or apply another style to some elements adapted to the device screen size, yout can just use the #media css property.
#your_div_id {
width: 950px;
/* ... */
}
#media (max-width: 38em) {
#your_div_id {
display:none;
}
}
You are trying to hide a div with class '.divIWantedToHide'. But your div does not have any class.
So you should add to your div the class:
<div class="divIWantedToHide" style="width:950px;height:5px;background-color:#FFFFFF;"> </div>
And then, you can show and hide it like here:
$(".divIWantedToHide").hide()
$(".divIWantedToHide").show()

css: changing the ruleset vs using selectors to switch classes/apply styles

Lately I wondered about editing elements styles not by switching their classes on dom, but by changing the actual ruleset for the css class or selector.
So instead of something like
$('.some').hide()
or
$('.some').addClass('hidden')
Why not alter a rule directly with document.styleSheets and stuff?
Wouldn't this approach be generally more performant, at least with many elements, as we'd let the browser handle the ruleset changes natively?
You could for example add an style to .some, like display: none; and all .some elements would be immedeatly be hidden. There is no need to iterate over all those elements in js and hide them manually(like the example above).
Changing rulesets directly would more likely encourage classes that are context aware(or however you would call this..), as you'd hide all #persons > .item or something.
I still don't know best practices regarding classes that are named with context in mind, like for example control names like .calendar .ticket .item, versus single functionality classes like .hidden .left .green, as I usually need both types of conventions.
I am just asking what you think about this and what are benefits and drawbacks of the modifiying stylesheet approach versus how libraries like jquery handle changing styles?
Also, what do you think is good practice, what do you regard more as a hack?
cough javascript and hacking cough
Manipulating document.styleSheets is tricky due to differing implementations and the lack of a rule selector API. Currently if you want to manipulate a rule in a stylesheet you have to go through this process:
iterate over document.styleSheets
iterate over rules within current styleSheet object
if rule matches our class, edit the rule styles
Then there's the cascading issue. How do you know that a particular style on the rule you've matched won't be overridden by a different rule somewhere in the pages stylesheets? If you just bail out after changing the first matching rule you find, you can't be sure that the styles you set will actually be applied to the element, unless you stick an !important on each one, which will leave you with a whole different set of problems.
Even when you've manipulated the style sheet rules, the browser still has the same job to do — it has to recalculate all the styles by applying the cascade.
So, manipulating styleSheets doesn't look too appealing now, does it? Stick to class switching, trust me. Using jQuery and modern APIs like querySelectorAll make it plenty fast and the browser still does all the hard work like recomputing the style values.
Such a tricky question :(
But if you take boilerplate for instance, it has a some standard classes to use like:
/* Hide from both screenreaders and browsers: h5bp.com/u */
.hidden { display: none !important; visibility: hidden; }
/* Hide only visually, but have it available for screenreaders: h5bp.com/v */
.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: ; position: absolute; width: 1px; }
/* Hide visually and from screenreaders, but maintain layout */
.invisible { visibility: hidden; }
Where it gets tricky is, IF it is something you need to hide because of JS, then you should ONLY hide it with JS. Then it will function if JS is disabled.
If it is something that is not JS dependent, then you hide it in the HTML.
So JS function = hide with JS (either by using JS or adding hide classes)
Basic HTML hide = hide with HTML class
Styleswitching vs JS switching
Basicly JS switching gives you the oppertunity to add effect etc, just using predefined classes limits that somewhat. But would love to see some ressource comparisons :)

Change stylesheet based on month/season in jQuery

I'm trying to find a way to change stylesheets based on what season it is with jquery because at this point it is unknown if I can use php or ruby at all on this site. Thanks for your responses!
The simplest is to scope your CSS styles and add a class at a high level. I usually do this at the body element. The CSS looks like:
body.summer ul { background-color: green; }
body.fall ul { background-color: orange; }
body.winter ul { background-color: white; }
body.spring ul { background-color: pink; }
Then, use JS to set the body class:
...</body>
<script ...>
var season = (new Date()).getMonth...;
$('body').addClass(season);
</script>
</html>
As you can see, I placed this immediately after closing the body tag. I think this is the first place you can put it and get it to work, but you'll have to check. The reason to put it here is to prevent the flash of unstyled content-- if you have lots going on on the page, you'll want to execute this Javascript before the on ready callback. That being said, I actually haven't had much problem just putting most of my code in the ready callback.
You can also load different stylesheets easily-- probably at the same place. Just create a style node and insert it into the head as the last node. You'd do this if you have major differences between your styles. Pretty tricky to maintain.
$("head").append("<style type=\"text/css\" src=\"" + season + ".css\"">");
I would suggest you narrow down the items that you want to change on the page, since the CSS file would already be loaded and jQuery would just be applying the css after the static css is loaded. You could leave these specific style declarations out of the css or keep them as default. For example, if the background image changes, you could set it to white in the default css declaration. This way, on load, it looks normal and you're only using JavaScript to load necessary items.
You could then use the JavaScript month function to get the current month
var month = new Date();
month = month.getMonth();
Then, you could use jQuery to apply those styles to the head with the jQuery ready function. You could have a simple switch of if/else statement to select one of four statements depending on the month number. For example, if you want to change the background
$("head").append("<style type=\"text/css\">body {background-color: #FFF !important;}</style>");
Just a quick example, but it would make it more efficient than loading a whole sheet I think.
put all your declarations in one css at the form of
.someStyle{ color:blue;}
.summer .someStyle{color:yellow;}
.winter .someStyle{color:purple;}
...
all classes under .summer will override the default style for summer
then on the server/client when the page is ready - add this class to the body
the only problem with doing it at the client is that the default style will render first and then switch to the new one (just pick the season most common to your site's users - if it was Israel i would choose summer ;-)

Categories

Resources