admin管理员组文章数量:1318183
Im trying to generate responsive background images for my page header, using a modified version of this gist, but I cant get it to work correctly, and Im not sure if the issue is with wp_get_attachment_image_srcset
, wp_calculate_image_sizes
or the loop itself.
Here's my code:
Responsive Image Size Attributes
function adjust_image_sizes_attr( $sizes, $size ) {
$width = $size[0];
if($width >= 1260){
$sizes = '(max-width:575px) 575px, (max-width:767px) 767px, (max-width:991px) 991px, (max-width:1199px) 1199px, 1260px)';
}
elseif($width >= 900){
$sizes = '(max-width:767px) 100vw, (max-width:991px) 631px, (max- width:1199px) 839px, 900px)';
}
elseif($width >= 600){
$sizes = '(max-width:767px) 100vw, 600px';
}
else{
$sizes= '(max-width: ' . $width . 'px) 100vw, ' . $width . 'px';
}
return $sizes;
}
add_filter( 'wp_calculate_image_sizes', __NAMESPACE__ . '\\adjust_image_sizes_attr', 10 , 2 );
Generate Responsive Background Image CSS
function gsc_responsive_bg_images($attachment_id, $img_size, $selector)
{
$img_srcset = wp_get_attachment_image_srcset( $attachment_id, $img_size );
$sizes = explode( ", ", $img_srcset );
$css = '';
$prev_size = '';
foreach( $sizes as $size ) {
// Split up the size string, into an array with [0]=>img_url, [1]=>size
$split = explode( " ", $size );
if( !isset( $split[0], $split[1] ) )
continue;
$background_css = '.gsc-page-title-bar {
background-image: url(' . esc_url( $split[0] ) . ')
}';
// Grab the previous image size as the min-width and/or add the background css to the main css string
if( !empty( $prev_size ) ) {
$css .= '@media only screen and (min-width: ' . $prev_size . ') {';
$css .= $background_css;
$css .= "}\n";
} else {
$css .= $background_css;
}
// Set the current image size as the "previous image" size, for use with media queries
$prev_size = str_replace( "w", "px", $split[1] );
}
return $css;
}
**My Output: (in shorthand) ** default.jpg (original dimensions: 1170w)
@min-width: 1170px -> 768w.jpg
@min-width: 768px -> 120w.jpg
@min-width: 120px -> 500w.jpg
@min-width: 500px -> 700w.jpg
@min-width: 700px -> 200w.jpg
@min-width: 400px -> 600w.jpg
@min-width: 600px -> 800w.jpg
I was expecting
Seeing this, Im left with a bunch of questions:
- Why is this the CSS code thats being returned? Shouldnt it be the smallest size being returned at the default breakpoint and the largest size at
@min-width:1170px
? Why does@min-width: 768px -> 120w.jpg
, and@min-width: 700px -> 200w.jpg
? - Why are these the srcset images that are being generated? Shouldn't they be 900px, 767px, 839px, 631px?
Any and all help appreciated!
Im trying to generate responsive background images for my page header, using a modified version of this gist, but I cant get it to work correctly, and Im not sure if the issue is with wp_get_attachment_image_srcset
, wp_calculate_image_sizes
or the loop itself.
Here's my code:
Responsive Image Size Attributes
function adjust_image_sizes_attr( $sizes, $size ) {
$width = $size[0];
if($width >= 1260){
$sizes = '(max-width:575px) 575px, (max-width:767px) 767px, (max-width:991px) 991px, (max-width:1199px) 1199px, 1260px)';
}
elseif($width >= 900){
$sizes = '(max-width:767px) 100vw, (max-width:991px) 631px, (max- width:1199px) 839px, 900px)';
}
elseif($width >= 600){
$sizes = '(max-width:767px) 100vw, 600px';
}
else{
$sizes= '(max-width: ' . $width . 'px) 100vw, ' . $width . 'px';
}
return $sizes;
}
add_filter( 'wp_calculate_image_sizes', __NAMESPACE__ . '\\adjust_image_sizes_attr', 10 , 2 );
Generate Responsive Background Image CSS
function gsc_responsive_bg_images($attachment_id, $img_size, $selector)
{
$img_srcset = wp_get_attachment_image_srcset( $attachment_id, $img_size );
$sizes = explode( ", ", $img_srcset );
$css = '';
$prev_size = '';
foreach( $sizes as $size ) {
// Split up the size string, into an array with [0]=>img_url, [1]=>size
$split = explode( " ", $size );
if( !isset( $split[0], $split[1] ) )
continue;
$background_css = '.gsc-page-title-bar {
background-image: url(' . esc_url( $split[0] ) . ')
}';
// Grab the previous image size as the min-width and/or add the background css to the main css string
if( !empty( $prev_size ) ) {
$css .= '@media only screen and (min-width: ' . $prev_size . ') {';
$css .= $background_css;
$css .= "}\n";
} else {
$css .= $background_css;
}
// Set the current image size as the "previous image" size, for use with media queries
$prev_size = str_replace( "w", "px", $split[1] );
}
return $css;
}
**My Output: (in shorthand) ** default.jpg (original dimensions: 1170w)
@min-width: 1170px -> 768w.jpg
@min-width: 768px -> 120w.jpg
@min-width: 120px -> 500w.jpg
@min-width: 500px -> 700w.jpg
@min-width: 700px -> 200w.jpg
@min-width: 400px -> 600w.jpg
@min-width: 600px -> 800w.jpg
I was expecting
Seeing this, Im left with a bunch of questions:
- Why is this the CSS code thats being returned? Shouldnt it be the smallest size being returned at the default breakpoint and the largest size at
@min-width:1170px
? Why does@min-width: 768px -> 120w.jpg
, and@min-width: 700px -> 200w.jpg
? - Why are these the srcset images that are being generated? Shouldn't they be 900px, 767px, 839px, 631px?
Any and all help appreciated!
Share Improve this question edited Jun 11, 2017 at 21:39 Dovid Levine asked Jun 11, 2017 at 21:26 Dovid LevineDovid Levine 416 bronze badges1 Answer
Reset to default 1I haven't tested your code, but I recently spent a few hours hacking something together to solve the same issue -- making background images set via the WordPress customizer load responsively. Feel free to use / modify the code below to your needs, and send any questions my way. I'm not a PHP expert by any measure, however.
3 things to note about the code below:
- I'm assuming you have already set up your customizer code, or are ok with just adding this CSS somewhere else via an echo / filter.
- This code uses a function to get an attachment's ID based on its URL that was created by Micah Wood, who in turn credits this function developed by Andrey Savchenko (a.k.a. “Rarst”). I've included it as the second function below, but be sure to check out both links for more info.
- I've only targeted -webkit- with the pixel density, if you want to add other vendor prefixes (eg: -o-), that could be done.
Responsive Customizer Backgrounds
/**
* Create CSS Rules for Responsive BGs set via the Wordpress Customizer.
*
* @uses get_attachment_id() Gets attachment id from $img_url
* @link https://wpscholar/blog/get-attachment-id-from-wp-image-url/
*
* @param string $selector The css selector set via customizer
* @param string $img_url The attachment url set via customizer
*
* @return string $responsive_css CSS rules on success, 0 on failure
*/
function responsive_customizer_bgs($selector='', $img_url='') {
// return var
$responsive_css = 0;
// get attachment id based on url (uses helper func)
$image_id = get_attachment_id( $img_url );
// get the src string from WP
$srcset_string = wp_get_attachment_image_srcset( $image_id, 'full' );
// parse srcset string into [url][int][width-or-pixel-density]
preg_match_all(
"/([^\s]*)\s(\d*)([w|x])/",
$srcset_string,
$srcset_matches,
PREG_SET_ORDER
);
// check if regex match was successful
if( is_array($srcset_matches) ) {
// cast int string into integer
for ($i=0; $i < count($srcset_matches); $i++) {
$srcset_matches[$i][2] = (int) $srcset_matches[$i][2];
}
// sort array of sizes by integer
usort($srcset_matches, function($a, $b) {
return $a[2] >= $b[2] ? -1 : 1;
});
// indexed loop to walk multi-dimensional array returned by regex
for ($i=0; $i < count($srcset_matches); $i++) {
// set media query statement based pixel size or pixel density
if ($srcset_matches[$i][3] === 'w') {
$media_query_match = 'max-width: ' . $srcset_matches[$i][2] . 'px';
} else if ($srcset_matches[$i][3] === 'x') {
$media_query_match = '-webkit-min-device-pixel-ratio: ' . $srcset_matches[$i][2];
}
// create css rules and add to return string
$responsive_css .= PHP_EOL
. '@media only screen and (' . $media_query_match . ') {' . PHP_EOL
. ' ' . $selector . ' {' . PHP_EOL
. ' background-image: url(' . $srcset_matches[$i][1] . ');' . PHP_EOL
. ' }' . PHP_EOL
. '}';
}
// return that beautiful responsiveness
return $responsive_css;
}
}
Get Attachment ID Via URL
/**
* Get an attachment ID given a URL.
*
* @param string $url
*
* @return int Attachment ID on success, 0 on failure
*/
function get_attachment_id( $url ) {
$attachment_id = 0;
$dir = wp_upload_dir();
if ( false !== strpos( $url, $dir['baseurl'] . '/' ) ) { // Is URL in uploads directory?
$file = basename( $url );
$query_args = array(
'post_type' => 'attachment',
'post_status' => 'inherit',
'fields' => 'ids',
'meta_query' => array(
array(
'value' => $file,
'compare' => 'LIKE',
'key' => '_wp_attachment_metadata',
),
)
);
$query = new WP_Query( $query_args );
if ( $query->have_posts() ) {
foreach ( $query->posts as $post_id ) {
$meta = wp_get_attachment_metadata( $post_id );
$original_file = basename( $meta['file'] );
$cropped_image_files = wp_list_pluck( $meta['sizes'], 'file' );
if ( $original_file === $file || in_array( $file, $cropped_image_files ) ) {
$attachment_id = $post_id;
break;
}
}
}
}
return $attachment_id;
}
本文标签: functionsGenerating Responsive Background Image Sizes in PHP
版权声明:本文标题:functions - Generating Responsive Background Image Sizes in PHP 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741992487a2409387.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论