aWebDeveloper
aWebDeveloper

Reputation: 38392

string concatenation in css

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

Answers (5)

Lerner Zhang
Lerner Zhang

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

Klaus Veber
Klaus Veber

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

zzzzBov
zzzzBov

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

Goran
Goran

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

Niet the Dark Absol
Niet the Dark Absol

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

Related Questions