59

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')
5
  • @zzzzBov how do i do this [class^="connection-"]::after Commented Apr 1, 2013 at 15:00
  • 1
    Can you phrase that in the form of a question? I'm not sure what you're asking me here. Commented Apr 1, 2013 at 15:01
  • @zzzzBov How can i use ::after along with [] selector Commented Apr 1, 2013 at 15:07
  • [type="foo"]:after { style: value; }, basically as you'd shown, which is why I was confused by the question. Did you try it before asking? Commented Apr 1, 2013 at 15:15
  • @zzzzBov yes the one that i had was not not working let me try with single ':' instead of double '::'. Commented Apr 2, 2013 at 12:04

5 Answers 5

34

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.

Sign up to request clarification or add additional context in comments.

4 Comments

I believe this is coming in the specification, just not supported in any browser yet. developer.mozilla.org/en/docs/CSS/attr#Browser_Compatibility
@Fabrício Matté: Unfortunately this is an issue with url() and not with attr() regardless of browser support, and it may never be possible unless they re-spec url(). See my answer here: stackoverflow.com/questions/42932294/…
you can "concatenate" just by separating with a space That's what we're looking for.
you can concatenate content property by separating with a space. eg: content: 'Page: ' counter(page);
5

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.

Comments

4

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.

Comments

0

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

Comments

-2

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

9 Comments

From review queue: May I request you to please add some more context around your answer. Code-only answers are difficult to understand. It will help the asker and future readers both if you can add more information in your post.
I wonder if the author actually tried those examples. It seems it is not possible, at least with the var() example: stackoverflow.com/questions/42330075/…
This does not work in Firefox and shows as invalid CSS.
This suggestion doesn't seem to work in Chrome either. At least I tested it with a concatenation in url() for an image base url kinf of thing: codepen.io/astaco/pen/VwyQwrz
I wonder how this answer could get so many upvotes. The first and last point don't work (tried in the provided codepen) and after reading the background from the other comment I believe the other two shouldn't work either. This is just impossible today. (PS: Most of the answer was edited in later, not all is from the first author!)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.