How to capture html attribute in a js variable and then assign it in css variable?

4

I want to capture the value of src and pass it to a CSS variable, which is in the inline style of the container parent named --img-url .

The idea that I have in the html, I have this:

<figure class="img-container" style="--img-url: ;">
 <img class="imagen" src="imagen.jpg"/>
</figure>

In the CSS:

.img-container .imagen{ display: none; }
.img-container { background-image: var(--img-url); }

And in jQuery:

$(document).ready(function(){

  var asignarCssvar = function(selector, variable, valor) {
    $(selector).css(variable,valor);
  }

  var capturaAtributo = function(selector, atributo) {
    var valorAtributo = $(selector).attr(atributo);   

    var urlBkg = "url('"+valorAtributo+"')";

    asignarCssvar(".img-container","--img-url",urlBkg);
  }

  capturaAtributo(".img-container .imagen", "src");

});

Functional example:

$(document).ready(function(){
  
  var asignarCssvar = function(selector, variable, valor) {
    $(selector).css(variable,valor);
  }
  
  var capturaAtributo = function(selector, atributo) {
    var valorAtributo = $(selector).attr(atributo);   
    
    var urlBkg = "url('"+valorAtributo+"')";
    
    asignarCssvar(".img-container","--img-url",urlBkg);
  }

  capturaAtributo(".img-container .imagen", "src");
  
});
.img-container {
  background-image: var(--img-url);
  background-size: cover;
  background-position: center;
  background-color: #dddfff;
  padding: 1em;
  width: 100px;
  height: 100px;
}
.img-container .imagen {
  width: 100%;
  height: auto;
  transform: translateX(200%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<figure class="img-container" style="--img-url: ;">
 <img class="imagen" src="https://picsum.photos/900/300"/>
</figure>

But as you can see, I have 2 problems:

  • Something I'm doing wrong, that does not work or can not be done like that
  • How do I take the value of the variable declared in the style without having to write it manually and again in the jquery?
  • Optionally I would like to know how they would do it, but vanillaJW?
  • Update

    I think many do not know about the variables, which are officially known as the Custom Properties of css: Using CSS Variables | MDN documentation and I do know that they are not yet fully implemented, although they have good support according to caniuse that's why mention that I'm doing experiments:)

    I have been able to use the same code in codepen and it works, why will it be? Link to watch demo in Codepen

    Update 2

    Yes, apparently if it works, only with the latest version of jQuery 3.2.1 and there is no official answer as to why. Thanks @ AlvaroMontoro for responding. I already update my code and it works like magic!

      

    On whether it can be done without JavaScript (only with CSS styles)

    As for if I wanted to do it only via CSS, it was not my intention in the question, but how well that by accident also gave me reason why it could not. However, because stubbornness is foolish, maybe this answer is "possible" in the future, since I remembered this article that I read but did not understand until now: Article in this super blog of css that we are going to have some" css functions "or similar, or that we already have one as calc() well supported and that in the future attr() and toggle maybe.

        
    asked by Edgar Gutiérrez 16.01.2018 в 00:01
    source

    2 answers

    3

    As I said in the comments: It does not work here but it does work in Codepen because of the version of jQuery that you are using. I could not find the specific reason why this is so, but if instead of using the 2.x you use the 3.x it seems that the problem is resolved without further code changes:

    $(document).ready(function(){
      
      var asignarCssvar = function(selector, variable, valor) {
        $(selector).css(variable,valor);
      }
      
      var capturaAtributo = function(selector, atributo) {
        var valorAtributo = $(selector).attr(atributo);   
        
        var urlBkg = "url('"+valorAtributo+"')";
        
        asignarCssvar(".img-container","--img-url",urlBkg);
      }
    
      capturaAtributo(".img-container .imagen", "src");
      
    });
    .img-container {
      background-image: var(--img-url);
      background-size: cover;
      background-color: #dddfff;
      padding: 1em;
      width: 100px;
      height: 100px;
    }
    .img-container .imagen {
      transform: translateX(100%);
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <figure class="img-container" style="--img-url: ;">
     <img class="imagen" src="http://lorempixel.com/200/200/sports/1"/>
    </figure>

    Another part of the problem: How could it be done only with pure JS without jQuery? Here I will leave two different ways to do it (you could really do it in jQuery by occupying a lot less). They are commented, but tell me if you do not understand something:

    // OPCIÓN 1: añadir variable directamente al estilo del elemento
    document.querySelector(".img-container").style.cssText = "--img-url: url(" + document.querySelector(".img-container .imagen").src + ")";
    
    /*
    // OPCIÓN 2: crear una etiqueta de estilos y añadir la variable ahí
    
    // crear etiqueta style
    misEstilos = document.createElement("style");
    // añadirla a la cabecera
    document.head.appendChild(misEstilos);
    // insertar regla con variable
    misEstilos.sheet.insertRule(":root { --img-url: url(" + document.querySelector(".img-container .imagen").src + ");}");
    
    */
    .img-container {
      background-image: var(--img-url);
      background-size: cover;
      background-color: #dddfff;
      padding: 1em;
      width: 100px;
      height: 100px;
    }
    .img-container .imagen {
      transform: translateX(100%);
    }
    <figure class="img-container">
      <img class="imagen" src="http://lorempixel.com/200/200/sports/1"/>
    </figure>

    On whether it can be done without JavaScript (only with CSS styles), I think the answer is: No, you can not. At least not for the moment, for two reasons:

  • The src is an HTML attribute of the tag and not a CSS property. Maybe you could change the HTML to add a data-attribute with the value of src and read it from CSS using attr() ... but still, you would have another problem:
  • You would be trying to change the ancestor styles, and at the moment there is no ancestor selector. Or rather: Yes there is one ( ! ), as part of the level 4 selectors, but it is not supported by almost any browser.
  • answered by 16.01.2018 / 07:08
    source
    -1

    I have deleted the background-image with the variable because it is not correct and does not need it. I have changed the style that had the tag figure and I have corrected your code.

    I understand that this is what you need?

            $(document).ready(function () {
            // Añade la ruta de la imagen
            var asignarCssvar = function (selector, valor) {
                $(selector).css({ 'background-image': 'url(' + valor + ')' });
            }
    
            //captura la ruta de la imagen
            var capturaAtributo = function (selector, atributo) {
                var valorAtributo = $(selector).attr(atributo);
                asignarCssvar(".img-container", valorAtributo);
            }
    
            capturaAtributo(".img-container .imagen", "src");
        });
    .img-container {
            background-size: cover;
            background-color: #dddfff;
            padding: 1em;
            width: 100px;
            height: 100px;
        }
    
            .img-container .imagen {
                transform: translateX(100%);
            }
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <figure class="img-container">
        <img class="imagen" src="http://lorempixel.com/200/200/sports/1" />
    </figure>

    Edit:

    This would be an example of use with variables in the CSS.

    :root {
            --imagen-1: url(http://lorempixel.com/200/200/sports/1);
        }
        
        .img-container {
            background-image: var(--imagen-1);
            background-size: cover;
            background-color: #dddfff;
            padding: 1em;
            width: 100px;
            height: 100px;
        }
    
        .img-container .imagen {
            transform: translateX(100%);
            content: var(--imagen-1);
        }
        <figure class="img-container">
        <img class="imagen"/>
    </figure>
        
    answered by 16.01.2018 в 00:38