/** * This is tested and works, but will most likely need to be adjusted depending on your particular set-up. Have added some comments that may help with tweaking. * * The function below will loop through all projects and generate CSS for each project image. Roughly works like this: * * - Loops through all project posts * - For each project, CSS is generated for the image sizes and stored in an array * - The CSS class for each project image needs to be unique, so the post thumbnail ID is used to help generate the CSS class name * - This means you'll need to set up your archive template to match the CSS class name dynamically from the post thumbnail ID * - When all projects have been looped through, all of the required CSS has been generated and is printed inline to the `<head>` * * Example output: * I have two projects with featured images attached: * - project 1 has an image with post thumbnail ID of 10 * - project 2 has an image with post thumbnail ID of 20 * * The generated CSS will be: * <style id="[stylesheet-handle]-css-inline-css"> * .banner-10{background-image:url(https://example.com/wp-content/uploads/2021/02/project-1-500x500.jpg);}@media(min-width:75em){.banner-10{background-image:url(https://example.com/wp-content/uploads/2021/02/project-1-1600x600.jpg}} * .banner-20{background-image:url(https://example.com/wp-content/uploads/2021/02/project-2-500x500.jpg);}@media(min-width:75em){.banner-20{background-image:url(https://example.com/wp-content/uploads/2021/02/project-2-1600x600.jpg}} * </style> * * On the front end, your image containers will need to have matching CSS classes applied: * <div class="banner-10">Project 1</div> * <div class="banber-20">Project 2</div> */function responsive_background_images_for_archive_page() { // wp_add_inline_style must reference an existing stylesheet wp_enqueue_style( 'theme-css', get_template_directory_uri() . '/style.css' ); // Initialise an array to hold each loop of generated CSS. $projects_css = array(); // Target all the project posts that need CSS generated. $args = array( 'post_type' => 'post', // If your projects are a custom post type, set this value to the post type name. // 'category_name' => 'projects', // If your projects are posts with a "projects" category, set this value to the category name. 'posts_per_page' => -1, // Set this to a reasonable cap when live. ); $projects = new WP_Query( $args ); // Loop through all projects. if ( $projects->have_posts() ) { while ( $projects->have_posts() ) { $projects->the_post(); // Get the featured image for this project. $featured_id = (int)get_post_thumbnail_id(); if ( !empty ( $featured_id ) ) { // Get the featured image sizes for this project. $banner_s = wp_get_attachment_image_src( $featured_id, 'banner-s' )[0]; $banner_l = wp_get_attachment_image_src( $featured_id, 'banner-l' )[0]; // Generate the CSS for this project. Note the difference here is the CSS class name has included the post thumbnail ID to make it unique. $project_css = '.banner-' . $featured_id . '{background-image:url(' . esc_url ( $banner_s ) . ');}@media(min-width: 75em){.banner-' . $featured_id . '{background-image:url(' . esc_url( $banner_l ) . ');}}'; // Store the CSS for this project before the next project loop starts array_push( $projects_css, $project_css ); } } } /* echo '<pre>'; var_dump( $archive_css ); echo '</pre>'; */ // Uncommenting the above will print the final generated CSS to the front-end, might be helpful for quick testing... $archive_css = implode( '', $projects_css ); // wp_add_inline_style() expects a string. // Set the CSS inline wp_add_inline_style( 'theme-css', $archive_css );}add_action( 'wp_enqueue_scripts', 'responsive_background_images_for_archive_page' );
Comments (1)
Daniel Shaw
One more thought: adding an is_archive() check before running anything inside this function will make sure this only runs in the relevant place and doesn’t affect your single project posts (if your projects are a custom post type: is_post_type_archive(NAME_OF_YOUR_POST_TYPE) is the one to use).
HTTPSSSH
You can clone a snippet to your computer for local editing.
Learn more.
One more thought: adding an
is_archive()
check before running anything inside this function will make sure this only runs in the relevant place and doesn’t affect your single project posts (if your projects are a custom post type:is_post_type_archive(NAME_OF_YOUR_POST_TYPE)
is the one to use).