Dynamical CSS image URLs within Javascript - javascript

I have a button that can have a focus css class associated with it and I instantiate this at runtime within Javascript.
This is all provided by a bespoke Javascript framework so can not be changed.
Normally I would provided 2 additional CSS class for this button,
e.g.
btn { background-image: url(/btn.png);}
btn.focus { background-image: url(/btn-focus.png);}
This will give me 2 different images based on whether the button is 'focused' or not.
The problem I have now is that the image urls are dynamically loaded at runtime, and there is no way of specifying them with a static CSS file.
I'm thinking one possible solution is to 'somehow' generate a new style element with the btn and btn.focus classes in it (with the dynamic URLs) and either append it to the head or embedded it in the markup prior to instantation of the Button itself. This solutions doesn't seem ideal.
Can anyone suggest anything else?
Thanks in advance.

If your case is specifically about images that represent different states of a single object (e.g. focused or non-focused state of a button) then it's a good idea to use sprites.
That is creating a single image with all button states and loading it (dynamically if you want).
Then you can write a universal rule in your CSS:
btn {background-position: 0 0;}
btn.focus {background-position: 0 -20px;} /* 20px is the height of your button*/

Are you saying this doesn't work because their css styles "inline" ones are overriding your ones? If so then do this instead
btn { background-image: url(/btn.png) !important;}
btn.focus { background-image: url(/btn-focus.png) !important;}

Related

How can I dynamically style programmatically generated SVG?

I am using a js library (mermaid) to generate svg on a web page. I need to dynamically apply styling to parts of the svg as the user activates various commands using keyboard shortcuts, Particularly, I need to highlight the element in the svg that is currently designated as the selected one in the logical model. Looking at other questions on dynamically styling svg deal with inlined static svg, so they probably don't apply to my case and none of the methods I tried so far have worked.
The style I am trying to apply is
border-radius : 2rem; box-shadow : 0 0 3rem red;
when applied to regular html, this gives the element a glowing red border.
First thing I've tried was to include this as a class in a element in like this :
<style>
.highlight {
border-radius : 2rem;
box-shadow : 0 0 3rem red;
}
</style>
Adding the class to a regular html element 's class list like an , , or , would produce the desired styling. However when I would programmatically get a element and add the class to its class list, then it would remain without the glowing border. Inspecting the svg using chrome developer tools revealed that the relevant class has been added to the element's class list. Using the same method was successful for regular html. For reference here is the method I used to add the class:
graphicDiv.querySelector(selector).classList.add('highlight')
This having failed, I thought maybe the svg had some styling inside its internal element that overrode my styling, so I added !important to my styles so they would have highest precedence. This still failed to work, so next I tried to set the style property for the element, which should have the highest precedence like this:
graphicDiv.querySelector(selector).setAttribute('style', 'border-radius : 2rem !important; box-shadow : 0 0 3rem red !important;')
This still failed to produce any difference in the styling of the svg. Inspecting the element in chrome dev tools revealed the style attribute was indeed set.
I also tried adding my style definition to the svg's own element, by getting it after the svg is generated, and appending my class style definition to its text content. It would still not work.
Finally, I thought those css properties might not be supported by , so I changed them to background-color: green; instead, since I think I saw in an article on styling svg with css that this css prop was used on an . This didn't work. I tried applying to a element in the svg. Didn't work either.
I am completely baffled why none of this is working. I would massively appreciate if anyone could help me understand how I could dynamically change the styling of svg elements!
While normal CSS attributes can be given to SVG elements, most do nothing as SVG elements by definition adhere to a different set of styling rules.
A simple example is that in normal CSS you might set left: 25px but for SVG you would need to set x: 25.
For the styling you want, border radius is usually achieved with stroke-width. For background colour just use fill. As for a shadow, it may be a little more complex but you should have a look at feDropShadow.
Besides that, applying those styles with css rules should be roughly the same.
I hope that's at least some help.

Best way to apply Style to every other div when an outside style sheet that I have no access to is coming into play?

I'm using BXSlider and attempting to change the background of every even iteration of the slider. The problem is that a css sheet that I do not have access to is affecting all sliders on the page.
Context-
<div class="bx-wrapper">
<div class="bx-viewport">
<div class="bx-slider">
</div>
</div>
</div>
Bx-wrapper and Bx-viewport are added automatically via the bxslider library.
The css sheet (that I have no access to) has the background set to #fff-
.bx-wrapper .bx-viewport {
background: #fff;
}
I am changing the background of the slider with -
.bx-wrapper .bx-viewport:nth-child(even){
background-color: rgb(245,245,245);
}
My main problem is that the original #fff takes precedence and I can only see the above css working when I un-check that style in dev tools. What do you all think the best way to ensure that the above css takes precedence?
It sounds like your style is just being overridden by the existing stylesheet, correct?
To give your style priority over the existing stylesheet, your CSS scoping should be as specific as possible and, if necessary, contain the !important property.
For example, instead of having...
.bx-wrapper .bx-viewport:nth-child(even){
background-color: rgb(245,245,245);
}
... you might want to try...
html body .bx-wrapper .bx-viewport:nth-child(even){ /*or whatever the full scope path to your elements would be*/
background-color: rgb(245,245,245) !important;
}
I hope that's what you're looking for.

How do you separately style two jQuery widgets that both require jquery-ui.css?

I have a page that I've designed which uses two commercial widgets both of which require the jquery-ui.css. When both widgets are on the page, one shows the .ui-slider .ui-slider-range correctly while the other one is absent. One widget uses the jquery-ui without modification while the other widget makes specific changes to the styling of .ui-slider .ui-slider-range. I assume I need to make one a separate class/id/element. How do I do that when it is based on a specific library/template? I tried using !important but that just created other issues.
You are on the right track, you can use the console to try your styles.
What im guessing is that you made changes in a class used by other widgets like .ui-widget, try to not mess with classes like .left, .container, or anything that looks like a generic name.
What you can do to specify the element you want to change is add a container with a different class, and then use it to access the widget classes:
<div class="myFirstContainer">
// Here comes widget 1
</div>
<div class="mySecondContainer">
// Here comes widget 2
</div>
Styles:
.myFirstContainer .ui-slider{
background: red !important;
}
.mySecondContainer .ui-slider{
background: blue !important;
}

Dynamic picture depends on attribute

My target is to have a list of file names, and near every item a picture of that file extension will appear next to it.
there is a nice way to do that:
p[icon^=".gif"]
{
background: url(images/gif.png) no-repeat center left)
}
this checks if the icon attribute of the 'p' element ends with .gif. if it does,
it applies the given style to that element.
but instead of define every file type, i want it to be generic since i have a folder with icons in this format: {file-extansion}.png
in case there is no matching file with the given extansion or there is no file extansion, there will be a default path of "default.png".
There is an option to do that or part of that? if no, what way you advise me doing that?
By the way I am not a css/javascript expert so please given enough details so I can understand your answers.
You can use jQuery library for this:
HTML
<p data-ext=".gif">Text</p>
<p data-ext=".png">Text</p>
<p data-ext=".jpg">Text</p>
CSS
p {
background-repeat: no-repeat;
background-position: 0 50%;
}
JavaScript
$("p[data-ext]").each(function() {
var ext = $(this).data("ext").substring(1);
$(this).css("background-image", "url(images/" + ext + ".png)");
});
It works so that you add data-ext attribute to each p (or whatever) tag. jQuery selects all p tags which have data-ext attribute, then gets attribute value, and changes background-image of each element.
DEMO: http://jsfiddle.net/AEsx4/
Using pure CSS, you can't dynamically reference attributes in the URL, but you can make them content. Here are some lame workarounds using pure CSS and finally a wishful thinking approach :(
Use a class
<div class="jpg">
</div>
/* css */
.jpg {
background: url("/img/jpg.jpg");
}
This works great, but you need one class per extension.
Use an attribute selector
<div data-ext="jpg"></div>
div[data-ext=jpg] {
background: url(/img/jpg.jpg);
}
For more on this approach see:
http://css-tricks.com/attribute-selectors/
I used data-ext, because in HTML you're not really supposed to add random tags, so the HTML creators gave us data-* which is valid HTML5 and we can do whatever want with it. Either way, you need to create a new CSS selector for every extension. Not good.
Closest you can get with pure css
<div data-ext="jpg"></div>
div:after {
content: attr(data-ext);
}
You will see the name of the extension next to the div. This almost works, but it's not quite good enough.
More about CSS Functions: http://www.suburban-glory.com/blog?page=130
What you actually want
<div data-ext="jpg"></div>
div:after {
content: url("/img/jpg." attr(data-ext));
}
Sadly this doesn't appear to work at the moment, but boy would it be awesome.

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

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.

Categories

Resources