CSS: Dynamic classes / attributes and media queries - how to solve this dilemma?

Writing an extension for a plugin I have the opportunity to change all the attributes of an HTML element using PHP.

$attributes["style"] .= 'padding-left:10px;'; array_push($attributes["class"], "long-container"); array_push($attributes["class"], "super smooth"); $attributes["data-whatever"] = "great"; 

Now I want to give the user the opportunity to enter the width / height ratio of the div dynamically (the decision on how to do this is described in the @Web_Designer answer here: Maintain the aspect ratio of the div with CSS ).

Inside the function, where I can change the output of a third-party plugin, I wrote the following code to calculate the height-to-width ratio according to the input. Since the height of my boxes is:

 if( !empty( $args['stretchy-desktop'] ) ) { $sd = array_map('trim',explode(":",$args['stretchy-desktop'])); if(count($sd)==2) { $sd[0] = floatval(str_replace(",",".",$sd[0])); $sd[1] = floatval(str_replace(",",".",$sd[1])); if($sd[0]>0 && $sd[1]>0) { $padding = ($sd[1] / $sd[0])*100; array_push($attributes['class'], 'stretchy-desktop'); $attributes['style'] .= 'padding-bottom:'.$padding.'%;'; } } } 

Good? However, now the user wants to enter a different weight ratio for mobile devices, as well as another dynamic minimum height for mobile devices, and I'm stuck.

1) It is impossible to give @media inline queries right now, otherwise my solution would be like this ( Is it possible to set CSS @media inline rules? ):

 $attributes['style'] .= '@media (min-width:540px) {padding-bottom:'.$padding.'%;}@media (max-width:539px) {padding-bottom:'.$padding_mobile.';}'; 

2) It is not possible to use HTML attribute values ​​in CSS right now ( CSS values ​​using HTML5 data attribute ), otherwise my solution would look like this:

 $attributes['data-desktoppadding'] = $padding; $attributes['data-mobilepadding'] = $padding_mobile; 

In CSS:

 @media (min-width:540px) { .long-container { padding-bottom: attr(data-desktoppadding); } } @media (max-width:539px) { .long-container { padding-bottom: attr(data-mobilepadding); } } 

3) Since the values ​​are dynamic numbers, I cannot define a CSS class for all possible existing floats.

Of course, I could use JavaScript, but we all know the significant flaws (including the ugly page loading).

Can you come up with any CSS solution for this dilemma?

+7
css html5 php css3 media-queries
source share
2 answers

Here is the solution I came up with. It includes creating a wrapper div around the target element. Basically, the way this works is that the outer div is assigned inline styles for mobile mode, and the inner div is assigned inline styles for desktop mode. When the size of the browser window changes below the threshold for the desktop, it resets the built-in styles of the internal div (desktop) to default, therefore, adopt the built-in styles of external div (mobile) . When the size of the browser window changes above the threshold value, it resets the built-in styles of the external div (mobile) by default, therefore, the built-in styles of the internal div (desktop) are used . A way to override inline styles is to use the !important keyword in rule sets in CSS media queries.

I think it goes without saying that the inline styles in the snippet below will be replaced with your $attributes['style'] . But since you will have separate styles of mobile and desktop computers, I think it would be $attributes['style-mobile'] and $attributes['style-desktop'] .

 @media (min-width:540px) { .padding-mobile { padding-bottom:0 !important; width: auto !important; } } @media (max-width:539px) { .padding-desktop { padding-bottom:0 !important; width: auto !important; } } 
 <div class="padding-mobile" style="width:100%;background-color:red;padding-bottom:100%;"> <div class="padding-desktop" style="width:50%;background-color:red;padding-bottom:25%;"> </div> </div> 
+5
source share

The elegant approach that works in the most important browsers is to use custom properties . They are mostly CSS variables. Since writing this (2017-03-27), only IE and Edge do not support this, although they are working on Edge support.

You added variables to $attributes['style'] and applied them in the stylesheet inside the media query. They are then dynamically used by the browser.

I implemented the demo as a snippet, but because it is easier to resize the viewport to JSFiddle , as well as a copy of the demo. Note that a responsive breakpoint is defined in CSS here, and variables are defined in the element's inline styles.

 .container { width: 200px; } .block { position: relative; display: block; box-sizing: border-box; width: 100%; height: 0; padding: 10px; padding-bottom: var(--desktop-ratio); background: #bada55; color: #444; } @media (min-width: 540px) { .mobile { display: none; } } @media (max-width: 539px) { .desktop { display: none; } .block { padding-bottom: var(--mobile-ratio); } } 
 <div class="container"> <div class="block" style="--desktop-ratio: 56.25%; --mobile-ratio: 200%;";> My aspect ratio is set via custom properties. It is <span class="mobile">1:2</span><span class="desktop">16:9</span>. </div> </div> 

This (at least for now), it seems impossible to set a breakpoint using a variable. I.e

 @media (min-width: var(--breakpoint)) { ... } 

apparently did not understand at least Firefox and Chrome at the moment.


Alternatively, relying on Kodos Johnson , answer: if you have only one breakpoint, you can use padding-bottom and padding-top . One of the two determines the aspect ratio on small screens, and the other determines it on large screens. This eliminates the need to add a shell element. Here is an example based on Kodos answer.

 @media (min-width:540px) { .block { padding-top: 0 !important; } } @media (max-width:539px) { .block { padding-bottom: 0 !important; } } 
 <div class="block" style="width: 50%; padding-bottom: 25%; padding-top: 100%; background-color: red;"> </div> 
+4
source share

All Articles