css-featured-image

object-fit在IE與Edge的對應處理

今天要介紹的是如何在不支援object-fit的IE與新皮IE骨的Edge裡處理容器內元素形變的問題。有點饒舌,簡單來說就是IE不支援它怎麼辦 TvT?

關於object-fit元素作用為何,在此就不贅述了。有興趣的可以到某貓這篇文章看看,可以直接看到object-fit效果 :保持正圓或正方形的圖片

1.開始之前

有點進文章看過,或是已經知道object-fit效果的同學,應該就知道無論圖片是直長方形、橫長方形,還是不規則形,只要容器有設定長與寬,容器內被設定object-fit的元素便會根據設定值「自動符合容器的形狀」吧?

對於有些會開放給使用者自定圖片的網站來說,這真是超級好用的效果(處理圖片的排版真是心酸血淚史,更別提那些要高沒寬的形變和不遵守上傳圖片尺寸規定的使用者 TvT)

重點來了!當這個效果在不支援object-fit的 IE 系列裡會發生什麼事呢!(驚嘆號?

登登!!

登登登!!!

其實也不會發生什麼事,就只是容器內的元素形變而已。(茶

如果容器內的元素是圖片的話,那圖片的寬與高會變成容器設定的寬與高,如此一來只要圖片本身的長寬比跟容器不相同,就會看到一張被壓扁的長方形圖片⋯⋯那種形變不用說,除非網站已經放棄IE跟 Edge,否則一定得處理。

2. 怎麼處理

以下的解法參考自 Neat trick for CSS object-fit fallback on Edge (and other browsers) by Primož Cigler,已實作成功,英文程度尚可的可直接看原文。

以下不會是原文翻譯,注意,不會是原文翻譯,某貓自己的英文也是慘兮兮(文章理解部分G_G),而是某貓看完原文後實作得出的心得喔。

上述 ok 的話正題就開始吧。

2.1. 判斷瀏覽器是否支援 object-fit

這個步驟有兩個選擇肢,一,使用 javascript plugin 「Modernizr」。二,用原生 javascript 進行判斷。兩條選擇肢有各自的使用方法和好處,端看各位的選擇。

Modernier 是一個相當好用的外掛,它可判斷使用者瀏覽器是否支援網站使用的HTML、CSS和Javascript元素,舊文整理新貼當下最新版本是 3.5.0(2018年8月)。它最好的點是可以自由選擇要偵測的內容!點擊網站上方 Download ,可以看到它支援偵測的所有元素,選擇完要偵測的元素後,點擊 Build,便可得到一份 js 檔案。

其他如這份 js 檔案要不要是 minify 版本(壓縮版)、需不需要增加 CSS classes(除了使用 js 偵測外,它也可以使用 css class)等都可以在左邊側邊欄進行設定。預設是檔案為modify版本,且增加Css classes。

以今天要偵測的object-fit為例,在眾多元素中找到 CSS object fit 後,選擇它,點擊 Build後,將得到的 js 檔丟進網站資料夾底下並進行載入動作。

使用上很簡單,確定檔案載入後,只要這樣:

  1. if(!Modernizr.objectfit){
  2. //如果瀏覽器不支援 object-fit的話執行這邊
  3. }

對,很簡單,偵測部分就這樣解決了。

第二個選擇支則是利用原生 javascript 進行偵測,偵測方法如下:

  1. if(document.documentElement.style.objectFit==undefined){
  2. //如果瀏覽器不支援 object-fit的話執行這邊
  3. }

或者是

  1. if(“objectFit” in document.documentElement.style==false){
  2. //如果瀏覽器不支援 object-fit的話執行這邊
  3. }

是的別懷疑,這樣就解決了,無需任何外掛。

以上兩種方法就看各位各自的需求擇一即可。某貓目前是使用 Modernizr 進行判斷,因為之後可能出現其他需要判斷的支援,所以先用plugin(其實是懶)。

2.2. 針對object-fit進行處理

某貓針對object-fit的設定是增加了兩個全站共用的 class.fit-cover.fit-contain。因為效果上只會用到這兩個所以也就只設定兩個。

使用上則是這樣:

之前說過object-fit的容器可以是圖片外層的div,也可以是圖片本身,這邊某貓是將外層div作為圖片的容器,並強制將圖片的寬與高設定為100%,以符合容器尺寸。如此一來像範例使用.fit-cover的話,圖片便會無變形,並且完全填滿外層的div容器。

而外層div上的那個class,有看到他嗎?它就是負責在IE系列裡處理不支援object-fit問題的class啦!

還記得剛剛用來判斷瀏覽器是否支援object-fit的程式嗎?現在要來完成它!

並且增加兩個額外的 class.no-fit-cover.no-fit-contain。會需要分成兩個是因為個別的css設定不太一樣。

setObjectfit.js建議放在</body>之上,並且每個頁面都載入,至少有使用object-fit的頁面都要載入。如此一來在每個頁面載入時,如果瀏覽器不支援object-fit,這支程式便會針對頁面上所有使用.has-objectfit的容器進行圖片的處理。

它的處理其實也很簡單,既然object-fit不支援,但我又需要他的效果,那就找一個瀏覽器支援,效果又相同的來用,於是我們找到了background-image

background-image系列有一個background-size,這就是我們需要的功能,他能設定背景圖片的效果是backfround-size:cover;還是backfround-size:contain;,效果看起來就跟object-fit設定成covercontain一樣!

所以處理來講就是這樣:如果瀏覽器不支援->抓出有.has-objectfit的容器->將容器內圖片的連結抓出來,設定到容器上(使用background-image)—>根據圖片設定的class類型(.fit-cover.fit-contain)將容器設定對應的class(.no-fit-cover.no-fit-contain)。

以上就是處理方法~

3. Q&A 時間

Q.既然background-image支援全瀏覽器,那為何還要用object-fit呢?

A.用background-image有個前提,<img>這個tag的圖片需要隱藏,或者乾脆不使用,但這樣對SEO是不利的。一來蜘蛛爬不到圖片(乾脆不用<img>這tag),二來怕被判別成是使用隱藏內容刷關鍵字(<img>不顯示的話)。

所以為了SEO,還是用object-fit吧。

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s