Reputation: 38392
I want to achieve the following in css. How do i do it in a cross browser way?
url('../img/icons/' + attr('type') + '_10.png')
Upvotes: 56
Views: 81617
Reputation: 7140
I can provide a solution to concatenate strings for the CSS URL property without considering the attr('type') of each element, and here is an example:
// You can convert all the paths to be in your desired paths format in JS:
let rootElement = document.querySelector('#my-root-element');
for (const [prop, val] of rootElement.computedStyleMap()){
if (prop.startsWith('--var-')) {
var updatedValue = `url("${'../img/icons/' + val}")`;
console.log(updatedValue);
rootElement.style.setProperty(prop, updatedValue);
}
};
for (const child of rootElement.children) {
child.textContent = window.getComputedStyle(child).getPropertyValue('background-image');
}
/* In your CSS, you can define some variables like this: */
#my-root-element{
--var-a: btn_10a.png;
--var-a-img: img_10a.png;
--var-b: btn_10b.png;
--var-c: btn_10c.png;
--var-d: btn_10d.png;
}
#my-button-a{
background-image: var(--var-a);
}
#my-button-a-img[type="img"]{
background-image: var(--var-a-img);
}
#my-button-b{
background-image: var(--var-b);
}
#my-button-c{
background-image: var(--var-c);
}
.my-button{
display: block;
margin: 10px;
}
div#my-button-a-img{
border: 1px solid black;
display: inline-block;
}
<!-- Let's say your HTML is like this: -->
<div id="my-root-element">
<button class="my-button" id="my-button-a" type="button"></button>
<div class="my-button" id="my-button-a-img" type="img"></div>
<button class="my-button" id="my-button-b" type="button"></button>
<button class="my-button" id="my-button-c" type="button"></button>
<div>
Here is the link of the pen: https://codepen.io/lerner-zhang/pen/dyaOOmQ?editors=1111
Upvotes: 0
Reputation: 273
CSS performs concatenation without using any operator (e.g. +, &, etc). Keep your strings in quotes combine the strings, attr, var, etc into one line.
Examples:
url('not/very' '/useful/concatenation'); // not/very/useful/concatentation
url('../img/icons/' attr('type') '_10.png'); //../img/icons/${type}_10.png
url(attr('href') '#hash'); // https://${href}/#hash
url(var(--hello) ' world'); // Hello World
Upvotes: -2
Reputation: 179196
You can't do dynamic string interpolation in the way that you're suggesting, but if you have a limited number of possible values for the [type]
attribute, you could create styles for each one:
.your .selector[type="foo"] {
background-image: url('../img/icons/foo_10.png');
}
.your .selector[type="bar"] {
background-image: url('../img/icons/bar_10.png');
}
.your .selector[type="baz"] {
background-image: url('../img/icons/baz_10.png');
}
If you've got an unreasonable number of types, then you'll probably need to come up with a better solution than I've listed here.
Upvotes: 4
Reputation: 3410
No, you can't do this in plain CSS because the CSS language hasn't control structures or anything like that wich will allow you to dinamically generate CSS code.
Instead, you can use a javascript solutions or a solution based on CSS variables coded in PHP.
Upvotes: 4
Reputation: 324750
I don't think you can. In the content
property you can "concatenate" just by separating with a space, but in other places I don't think there is such a feature. Which is a shame.
You'll probably be best off specifying this style in a style
attribute whenever the type
attribute is used.
Upvotes: 32