0

As we all know inline styles are not good practice and they are not compatible with e.g. the Content Security Policy.

This is what I want to achieve without inline styles:

<?php
$spacer_height = 390; // this is a dynamic value from user input could be any integer
?>
<div class="spacer" style="height:<?php echo $spacer_height; ?>"></div>

This is what I want:

HTML:

<?php
$spacer_height = 390; // this is a dynamic value from user input
?>
<div class="spacer spacerheight-<?php echo $spacer_height; ?>" data-height="<?php echo $spacer_height; ?>"></div>

External Stylesheet:

.spacer {
  height: spacer_height + "px"; // this line is dummy code
}

Is where a way to achieve this with CSS only. No JavaScript. No Polyfill.

What I have already found is this 5 year old question: CSS values using HTML5 data attribute

However is there a solution meanwhile or is there a CSS solution not using attributes? Is there at least a solution for integers?

Edit: Even a working polyfill may be a welcome answer if there is no other solution.

Community
  • 1
  • 1
Blackbam
  • 17,496
  • 26
  • 97
  • 150
  • Maybe `". ".spacer {". "height: $spacer_height". "}". "";` ? – Akshay Mar 06 '17 at 16:15
  • Nah thats a workaround in order to define not directly as inline style but it does not really solve the problem ;-) – Blackbam Mar 06 '17 at 16:21
  • If you put that at the end of the `body` it will work – Akshay Mar 06 '17 at 16:22
  • This is why I mentioned the content security policy which requires you to define styles in an external stylesheet. Ofc I could gather all possible spacer heights and generate an external stylesheet then but thats not really what I want. I want to select and apply dynamically somehow. – Blackbam Mar 06 '17 at 16:23
  • Why don't you just do the CSS solution you came up with already? That's what I would do, except I wouldn't bother with the `data-height` attribute - doesn't do anything in your example and doesn't seem necessary. – Michael Coker Mar 06 '17 at 16:33
  • Because it will not work? Except I would define each element from .spacerheight-1 to .spacerheight-1000? Furthermore it sucks if I want to have a mobile height with `data-height-mobile="otherpx"` for example. – Blackbam Mar 06 '17 at 16:38

2 Answers2

2

As you can't do this CSS only (yet, since the attr() function only returns string value), here is a simple script that will do something similar what attr() does, though this parse the data and sets it dynamically using cssText.

Let me know if I got this right

window.addEventListener("load", function() {
    var mb = isMobile();
    var el = document.querySelectorAll('[data-css]');
    for (i = 0; i < el.length; i++) {
        var what = el[i].getAttribute('data-css');
        if (what) {
            what = what.split(',');
            el[i].style.cssText = what[0] + ': ' + ((mb) ? what[2] : what[1]) + 'px';
        }
    }
});

function isMobile() {
  //function that check if user is on mobile etc.
  return false;  // return false for this demo
}
html, body {
  margin: 0;
}

div {
    background-color: lightgreen;
    padding: 10px 0;
    height: auto;
    box-sizing: border-box;
}

div ~ div {
    margin-top: 10px;
}
<div data-css="height,60,30"></div>
<div></div>
<div></div>
<div data-css="height,60,30"></div>
<div></div>

Another option would be to run something server side, where you simply create the CSS rule and class and insert it into CSS file and markup respectively, before sending to the client

Asons
  • 84,923
  • 12
  • 110
  • 165
  • Yes thats a good workaround :-) It should be possible to extend it in order to listen to attribute changes, too. However I am very disappointed that there is no CSS only solution I can not think of a good reason for this restriction :-( – Blackbam Mar 06 '17 at 19:46
  • 1
    @Blackbam Lets hope they extend `attr()` so it can evaluate its value type properly, then that will be a good one :) .... for attribute changes, use [MutationObserver](https://developer.mozilla.org/en/docs/Web/API/MutationObserver) – Asons Mar 06 '17 at 19:51
0

You might consider moving the dynamic part from being inline to being referenced in a <style>.

<style>
.spacer {
    height:<?php echo $spacer_height; ?>
}
</style>
<?php
$spacer_height = 390; // this is a dynamic value from user input could be any integer
?>
<div class="spacer"></div>
GlennFriesen
  • 302
  • 4
  • 15