Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have a set of image sizes for WordPress that look like this:

add_image_size('1039', 1039, 697);
add_image_size('960', 960, 644);
add_image_size('800', 800, 537);
add_image_size('768', 768, 515);
add_image_size('640', 640, 429);
add_image_size('480', 480, 322);
add_image_size('320', 320, 215);
add_image_size('240', 240, 161);

So basically each defined image size has the name of it's own width (and I forced the '1039' to be the maximum allowed upload size), and these widths correspond to eight different media sizes, which I set using this:

div.container {width: 1039px;}
@media only screen and (min-width: 960px) and (max-width: 1038px) {div.container {width: 960px;}}
@media only screen and (min-width: 800px) and (max-width: 959px) {div.container {width: 800px;}}
@media only screen and (min-width: 768px) and (max-width: 799px) {div.container {width: 768px;}}
@media only screen and (min-width: 640px) and (max-width: 767px) {div.container {width: 640px;}}
@media only screen and (min-width: 480px) and (max-width: 639px) {div.container {width: 480px;}}
@media only screen and (min-width: 320px) and (max-width: 479px) {div.container {width: 320px;}}
@media only screen and (max-width: 319px) {div.container {width: 240px;}}

Now, I with this basic setting and any chosen image as background-image (with a size of 1039x697) it will just resize the div.container when a different media views it. However, I want to apply the image-sizes I added, so that it applies the correct image-size to fit the size of the media used (rather than load the huge image and resize it with CSS, it should load the image that is fitted for that resolution).

At current I use this solution:

var body = jQuery('body').css("width");
var body = parseInt(body);
var image = jQuery('.container').css("background-image");
if (body >= 1039) {
    var img_width = 1039;
    var img_height = 697;
} else if (body >= 960 && body < 1039) {
    var img_width = 960;
    var img_height = 644;
    var image = image.replace('.jpg")', '-'+img_width+'x'+img_height+'.jpg")');
} else if (body >= 800 && body <= 960) {
    var img_width = 800;
    var img_height = 537;
    var image = image.replace('.jpg")', '-'+img_width+'x'+img_height+'.jpg")');
} else if (body >= 768 && body < 800) {
    var img_width = 768;
    var img_height = 515;
    var image = image.replace('.jpg")', '-'+img_width+'x'+img_height+'.jpg")');
} else if (body >= 640 && body < 768) {
    var img_width = 640;
    var img_height = 429;
    var image = image.replace('.jpg")', '-'+img_width+'x'+img_height+'.jpg")');
} else if (body >= 480 && body < 640) {
    var img_width = 480;
    var img_height = 322;
    var image = image.replace('.jpg")', '-'+img_width+'x'+img_height+'.jpg")');
} else if (body >= 320 && body < 480) {
    var img_width = 320;
    var img_height = 215;
    var image = image.replace('.jpg")', '-'+img_width+'x'+img_height+'.jpg")');
} else if (body >= 240 && body < 320) {
    var img_width = 240;
    var img_height = 161;
    var image = image.replace('.jpg")', '-'+img_width+'x'+img_height+'.jpg")');
} else if (body < 240) {
    var img_width = 240;
    var img_height = 161;
    var image = image.replace('.jpg")', '-'+img_width+'x'+img_height+'.jpg")');
}
jQuery('.container').css("background-image", image);

And this does in fact apply the correct image for the right media, but it is fully dependent on JavaScript being enabled.

Is there some way I could achieve the same result using just CSS? Or perhaps there is a more elegant solution to this? If so I would love to hear how!

share|improve this question
add comment

2 Answers

First off, kudos to this pretty cool solution.

I think you're on the right track and not sure how much more you could do. You could certainly replicate the above with PHP & CSS, thus not requiring jQuery. It would require you to have an array of your sizes and just loop through them. This would be a PHP file in your /CSS directory, and can be enqueued like any other stylesheet.

<?php

// Tag as CSS file

header("content-type: text/css");

include '../../../../wp-load.php';

ob_flush();

// Pull in Sizes & Image Size Names

$array = array (
    'size1' => array ( 'b_min' => '960', 'b_max' => '1039', 'img_size' => '1039' ),
    'size2' => array ( 'b_min' => '800', 'b_max' => '960', 'img_size' => '960' )
);

// Loop

foreach ( $array as $size ) : 

    echo '@media only screen and (min-width: ' . $size->b_min . 'px) and (max-width: ' . $size->b_max . 'px) {';

         echo 'div.container {background-image: /* Your image url code */ }';

    echo '}';

endforeach;

?>

This would solve your reliance on javascript.

share|improve this answer
    
That's a great idea! Few errors in the PHP above (that's an array, not an object), but I made it into a working example, will post result in a few minutes. –  OleVik Jan 12 '12 at 0:29
    
Hmmm, having some issues with getting generated data into the file. Basically, I need the php file that generates the CSS to get hold of some variables from functions.php, but how do I pass variables to the file when it is enqueued using wp_enqueue_style? –  OleVik Jan 12 '12 at 1:05
    
wp-load needs to have the right path and then you'll be able to call any options you want or other data through the conventional means :) –  Noel Tock Jan 12 '12 at 7:15
    
I really want to avoid the wp-load method due to the increase in server load (ottopress.com/2010/dont-include-wp-load-please). A temporary solution I've applied is hooking <style></style> into wp_head, but I am hoping for some better solution. –  OleVik Jan 12 '12 at 14:40
    
Cool, there certainly are ways to reduce the above, or state it in a different area. –  Noel Tock Jan 12 '12 at 15:59
add comment

Many thanks to the answer from Noel Tock, I got a solution that works great; created style.css.php inside the theme folder, which contains:

<?php
header('Content-type: text/css');
global $media_sizes;
$background = get_option('background');
$background_height = get_option('background_height');
$front_background = get_option('front_background');
$back_background = get_option('back_background');
?>
<?php
foreach ($media_sizes as $size) {
    echo '@media only screen';
    if ($size['min']) {
        echo  ' and (min-width: ' . $size['min'] . 'px)';
    }
    if ($size['max']) {
        echo ' and (max-width: ' . $size['max'] . 'px)';
    }
    echo ' {' . "\n";
    $back = $background['image'];
    $front_back = $front_background['image'];
        $front_back = str_replace('.jpg', '-'.$size['min'].'x'.$size['height'].'.jpg', $front_back);
    $back_back = $back_background['image'];
        $back_back = str_replace('.jpg', '-'.$size['min'].'x'.$size['height'].'.jpg', $back_back);
    echo '.content {width: '.$size['min'].'px; height: '.$size['height'].'px;}' . "\n";
    echo '.wrapper {width: '.$size['min'].'px; height: '.$size['height'].'px;}' . "\n";
    if ($size['min'] > 480) {
        echo '.container#front {min-height: '.($size['height']+75).'px; background-image: url("'.$back.'");}' . "\n";
        echo '.container#back {min-height: '.($size['height']+125).'px; background-image: url("'.$back.'");}' . "\n";
    } else {
        echo '.container#front {background-image: url("");}' . "\n";
        echo '.container#back {background-image: url("");}' . "\n";
    }
    echo '.container#front .wrapper .content {background-image: url("'.$front_back.'");}' . "\n";
    echo '.container#back .content {background-image: url("'.$back_back.'");}' . "\n";
    echo '}' . "\n";
}
?>

Which outputs the following:

@media only screen and (min-width: 1039px) {
    div.container {background: url("example-1039x697.jpg");}
}
@media only screen and (min-width: 960px)and (max-width: 1038px) {
    div.container {background: url("example-960x644.jpg");}
}
@media only screen and (min-width: 800px)and (max-width: 959px) {
    div.container {background: url("example-800x537.jpg");}
}
@media only screen and (min-width: 768px)and (max-width: 767px) {
    div.container {background: url("example-768x515.jpg");}
}
@media only screen and (min-width: 640px)and (max-width: 639px) {
    div.container {background: url("example-640x429.jpg");}
}
@media only screen and (min-width: 480px)and (max-width: 479px) {
    div.container {background: url("");}
}
@media only screen and (min-width: 320px)and (max-width: 319px) {
    div.container {background: url("");}
}
@media only screen and (min-width: 240px)and (max-width: 239px) {
    div.container {background: url("");}
}

And to get it into WordPress I used the following in functions.php:

function example_vars($public_query_vars) {
    $public_query_vars[] = 'example_vars';
    return $public_query_vars;
}
add_filter('query_vars', 'example_vars');
function example_dynamic_css(){
    $css = get_query_var('example_vars');
    if ($css == 'true'){
        include_once (TEMPLATEPATH . '/style.css.php');
        exit;
    }
}
add_action('template_redirect', 'example_dynamic_css');

And in header.php:

<link rel="stylesheet" href="<?php bloginfo('url'); ?>/?example_vars=true" type="text/css" media="screen" />

And this all results in the Media Queries being dynamically generated using options from the database, and completely without JavaScript.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.