Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
在網路上搜尋了與 srcset 相關的文章後,我認為〈img 的 srcset、sizes 和 picture 元素〉(簡體中文)這篇文章的敘述最淺顯易懂,所以主要的說明會根據這篇文章的介紹,改寫成我自己的理解。
這次的實作使用了 WordPress 外掛 Advanced Custom Fields (ACF)。ACF 是一套可以將 WordPress 客製化能力更上一層樓的外掛,非常適合有客製化需求的人使用。
內容目錄
為了幫助客戶寫客製化的精選圖片功能:在手機與桌面使用完全不同設計的兩張圖,因此一開始使用了 wp_is_mobile() 來判斷,並針對不同的裝置,直接載入對應的圖片。
但是由於加裝了快取外掛,因此頁面快取後,會出現「在桌機上看到行動裝置專用的圖片」的狀況,因此重新改用 img 標記中的 srcset 屬性來實作。
一開始是透過 wp_is_mobile 這個方法去判斷,在行動裝置上載入比較小的圖片。會這麼做最主要的原因,是因為行動裝置上顯示的,並非是使用 WordPress 自動產生的縮圖。但是誠如一開始提到的,這個做法,一旦頁面被快取了,很有可能在桌機上看到手機上快取的版本,也就是畫質比較差的圖片。
<?php if ( ! function_exists( 'huanyi_post_thumbnail' ) ) : /** * Displays an optional post thumbnail. * * Wraps the post thumbnail in an anchor element on index views, or a div * element when on single views. */ function huanyi_post_thumbnail() { if ( post_password_required() || is_attachment() || !has_post_thumbnail() ) { return; } if ( wp_is_mobile() ) : //如果是行動裝置,用自訂的 mobile_fv 圖片取代原本的精選圖片 ?> <div class="post-thumbnail"> <?php if (!empty(get_field('mobile_fv'))) : $img = get_field('mobile_fv');?> <img src="<?php echo $img['url']; ?>" alt="<?php echo $img['alt']; ?>" title="<?php echo $img['title']; ?>"> <?php else : //如果沒有設定 mobile_fv 的圖案,維持預設精選圖片 the_post_thumbnail(); endif; ?> </div><!-- .post-thumbnail --> <?php elseif ( is_singular() ) : ?> <div class="post-thumbnail"> <?php the_post_thumbnail(); ?> </div><!-- .post-thumbnail --> <?php else : ?> <a class="post-thumbnail" href="<?php the_permalink(); ?>" aria-hidden="true" tabindex="-1"> <?php the_post_thumbnail( 'post-thumbnail', array( 'alt' => the_title_attribute( array( 'echo' => false, ) ), ) ); ?> </a> <?php endif; // End is_singular(). } endif;
雖然上網查了文件,嘗試了幾次,但是因為在設定 srcset 的時候,使用的單位並非我們習慣看到的 px,而是 w,因此花了較多的時間去消化。看到喵不留行寫的文章,很仔細的介紹了這些單位應該如何運用,建議可以去參考他的說明。
<!-- 一般的 img 標記長得像這樣:--> <img src="path/to/image.png" alt="alt text" title="title" /> <!-- 加入 srcset 的屬性會是這樣 --> <img src="path/to/image.png" sizes="(max-width: 768px) 50vw, 100vw" srcset="image-480px.png 480w, image-1024px.png" alt="alt text" title="title />
一般來說,會將 w 設定為圖片的原始寬度,而不是在頁面上的寬度。對我來說主要是易讀性,讓開發者比較容易預期會讀取哪一張圖片。
至於實際上瀏覽器的判斷流程是這樣的:
這裡稍微再補充一下,這種做法對於 Retina 顯示的螢幕也有效。瀏覽器在偵測到 Retina 時,會自動將媒合圖片的基準乘以相對應的倍數,藉此找到適合的圖片。
將原本的程式做以下的改寫:
<?php function huanyi_post_thumbnail() { if ( post_password_required() || is_attachment() || !has_post_thumbnail() ) { return; } if ( !empty( get_field( 'mobile_fv' ) ) ) : ?> <div class="post-thumbnail"> <?php $img = get_field('mobile_fv');?> <img src="<?php echo $img['url']; ?>" sizes="(max-width: 768px) 50vw, 100vw" srcset="<?php echo $img['url']; ?> 480w, <?php echo get_the_post_thumbnail_url(); ?>" alt="<?php echo $img['alt']; ?>" title="<?php echo $img['title']; ?>"> </div><!-- .post-thumbnail --> <?php elseif ( is_singular() ) : ?> <div class="post-thumbnail"> <?php the_post_thumbnail(); ?> </div><!-- .post-thumbnail --> <?php else : ?> <a class="post-thumbnail" href="<?php the_permalink(); ?>" aria-hidden="true" tabindex="-1"> <?php the_post_thumbnail( 'post-thumbnail', array( 'alt' => the_title_attribute( array( 'echo' => false, ) ), ) ); ?> </a> <?php endif; // End is_singular(). }
一開始會看不懂相關的文件,很重要的原因是不懂 vw 這個單位。vw 代表的是佔螢幕畫面的百分比寬度,也就是說,在寬度 1440px 的裝置裡,10vw 就相當於 144px、在 768px 的裝置裡則是 76.8px。
其實還有更直覺的做法,就是使用 HTML 5 中的 picture 標記,但是在最後呈現的時候,就會比 img 標記的做法多出了兩個標籤,作法上比較不那麼輕巧。
這篇文章提出的寫法,主要是在 WordPress 中自訂 tag 的時候使用。除了這種自訂的 tag 之外,應該也能夠透過 apply_filter 這種勾點的方法,覆寫原本 the_post_thumbnail() 呈現圖片的方式。