Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
文:https://www.smashingmagazine.com/2019/07/margins-in-css/
譯者:前端小智
為了保證的可讀性,本文采用意譯而非直譯。
為了回饋讀者,《大遷世界》不定期舉行(每個月一到三次),現金抽獎活動,保底200,外加用戶贊賞,希望你能成為大遷世界的小錦鯉,快來試試吧
當我們學習CSS時,我們大多數人學到的第一件事是CSS中盒子的各個部分的細節,這部分通過叫做 CSS盒、模型。“盒模型”中的元素之一是margin,即盒子周圍的透明區域,它會將其他元素從盒子內容中推開。
CSS1中描述了 margin-top、margin-right、margin-bottom和margin-left屬性,以及一次設置所有四個屬性的簡寫 margin。
margin看起來是一個相當簡單的事情,但是,在本文中,咱們將看一些在使用margin一些讓人迷惑有有趣的事情。 特別是,margin之間如何相互作用,以及 margin 重疊效果。
想閱讀更多優質文章請猛戳GitHub博客,一年百來篇優質文章等著你!
CSS 盒模型
CSS 盒模型指的是一個盒子的各個部分——content、padding、border和margin,它們各自之前是如何布局及相互作用的, 如下所示:
盒子的的四個margin屬性和maring縮寫都在CSS1中定義。
CSS2.1規范有一個演示盒模型的插圖,還定義了用來描述各種盒子的術語,其中包括 content box、填padding box、border box和 margin box。
現在有一個 Level 3 Box Model specification 的草案。這個規范引用了CSS2作為盒模型和margin的定義,因此我們將在本文的大部分內容中使用CSS2定義。
margin 重疊
CSS1 規范定義了margin,也定義了垂直 margin 重疊。如果考慮到在早期,CSS被用作文檔格式語言,那么 margin 重疊是有意義的。 margin 重疊意味著,當一個有底部margin的標題后面跟著一個有頂部 margin 的段落時,它們之間就不會出現較大的空白。
當兩個 margin 發生重疊時,它們將組合在一起,兩個元素之間的空間取較大的一個。 較小的 margin 在較大的里面。
在以下情況下,margin 會重疊:
依次來看看這些場景。
相鄰的兄弟姐妹
對 margin 重疊的最初描述是演示相鄰兄弟姐妹之間的 margin 是如何重疊的。除了下面提到的情況之外,如果有兩個元素在正常流中依次顯示,那么第一個元素的底部 margin 將與下面元素的頂部 margin 一起重疊。
在下面示例中,有三個div元素。第一個 div 的頂部和底部的margin都是50px。第二個 div 的頂部和底部 margin 都是20px。第三個 div 的頂部和底部 margin 都是3em。前兩個元素之間的 margin 是50px,因為較小的頂部 margin 與較大的底部 margin 相結合。第二個元素與第三個元素之間的 margin 是 3em,因為3em大于第二個元素底部margin 20px。
html
<div class="wrapper"> <div class="box example1"> margin-top: 50px; margin-bottom: 50px; </div> <div class="box example2"> margin-top: 20px; margin-bottom: 20px; </div> <div class="box example3"> margin-top: 3em; margin-bottom: 3em; </div> </div>
css
.wrapper { border: 5px dotted black; } .example1 { margin: 50px 0 50px 0; } .example2 { margin: 20px 0 20px 0; } .example3 { margin: 3em 0 3em 0; } body { font: 1.4em/1.3 "Gill Sans", "Gill Sans MT", Calibri, sans-serif; margin: 2em 3em; } .box { background-color: rgb(55,55,110); color: white; padding: 20px; border-radius: .5em; }
運行效果:
完全空盒子
如果一個盒子是空的,那么它的頂部和底部 margin 可能會相互重疊。在下面的示例中,class為empty的元素的頂部和底部 margin 各為50px,但是,第一項和第三項之間的 margin不是100px,而是50px。這是由于兩個 margin 重疊造成的。如果向空盒子中放入內容就會阻止 margin 合并。
html
div class="wrapper"> <div class="box"> A box </div> <div class="box empty"></div> <div class="box"> Another box </div> </div>
css
.wrapper { border: 5px dotted black; } body { font: 1.4em/1.3 "Gill Sans", "Gill Sans MT", Calibri, sans-serif; margin: 2em 3em; } .box { background-color: rgb(55,55,110); color: white; border-radius: .5em; } .empty { margin: 50px 0 50px 0; }
運行效果:
父元素和第一個或最后一個子元素
margin 重疊讓人猝不及防,因為它有時候不是很直觀。在下面的示例中,有一個類名為 wrapper 的div,給這個div一個紅色的outline,這樣就可以看到它在哪里了。
這個div里面的三個子元素的 margin 都是50px。但是你會發現實際的效果是第一項和最后一項與父元素的的margin齊平,好像子元素和父元素之間沒有50px的margin一樣。
html
<div class="wrapper"> <div class="box"> Item 1 </div> <div class="box"> Item 2 </div> <div class="box"> Item 3 </div> </div>
css
.wrapper { outline: 1px solid red; } .box { margin: 50px; } body { font: 1.4em/1.3 "Gill Sans", "Gill Sans MT", Calibri, sans-serif; margin: 2em 3em; } .box { background-color: rgb(55,55,110); color: white; padding: 20px; border-radius: .5em; }
運行效果:
這是因為子節點上的margin會隨著父節點上的任何一邊的margin相互重疊,從而最終位于父節點的外部。如果使用DevTools檢查第一個子元素,就可以看到這一點,顯示的黃色區域就是是 margin。
僅塊元素 margin 重疊
在CSS2中,只指定垂直方向的 margin 重疊,即元素的頂部和底部 margin。因此,上面的左右邊距不會重疊。
值得注意的,margin 只在塊的方向上重疊,比如段落之間。
阻止 margin 重疊
如果一個元素是絕對的定位,或者是浮動的,那么它的margin永遠不會重疊。然而,假設你遇到了上面示例中的幾種情況,那么如何才能阻止 margin 重疊呢?
例如,一個完全空的盒子,如果它有border或padding,它的上下 margin就不會重疊。在下面的例子中,給這個空盒子添加了1px的padding?,F在這個空盒子的的上方和下方都有一個50px的 margin。
html
<div class="wrapper"> <div class="box"> A box </div> <div class="box empty"></div> <div class="box"> Another box </div> </div>
css
.wrapper { border: 5px dotted black; } body { font: 1.4em/1.3 "Gill Sans", "Gill Sans MT", Calibri, sans-serif; margin: 2em 3em; } .box { background-color: rgb(55,55,110); color: white; border-radius: .5em; } .empty { margin: 50px 0 50px 0; padding: 1px; }
運行效果:
這背后是有邏輯,如果盒子是完全空的,沒有border或padding,它基本上是不可見的。 它可能是CMS中標記為空的段落元素。 如果你的CMS添加了多余的段落元素,你可能不希望它們在其他段落之間造成較大的空白,這時 margin 重疊就有一定的意義。
對于父元素和第一個或最后一個子元素 margin 重疊,如果我們向父級添加border,則子級上的margin會保留在內部。
... .wrapper { border: 5px dotted black; } ...
同樣,這種行為也有一定的邏輯。如果出于語義目的而對元素進行包裝,但這些元素不顯示在屏幕上,那么你可能不希望它們在顯示中引入大的 margin。當web主要是文本時,這很有意義。當我們使用元素來布局設計時,它的重疊行為就沒有多大的意義了。
創建格式化上下文(BFC)
BFC(Block Formatting Context)格式化上下文,是Web頁面中盒模型布局的CSS渲染模式,指一個獨立的渲染區域或者說是一個隔離的獨立容器。
BFC 可以阻止邊距的重疊。 如果我們再看父元素和第一個或最后一個子元素的示例,可以在 wrapper 元素加上 display: flow-root就會創建一個新的BFC,從而阻止 margin 合并
... .wrapper { outline: 1px solid red; display: flow-root; } ...
display: flow-root 是CSS3新出來的一個屬性,用來創建一個無副作用的 BFC。將overflow屬性的值設為auto也會產生同樣的效果,因為這也創建了一個新的BFC,盡管它也可能創建一些在某些場景中不需要的滾動條。
flex 和 grid 容器
flex 和 grid 容器為其子元素建立flex和grid格式化上下文,因此它們也能阻止 margin 的重疊。
還是以上面的例子為例,將 wrapper 改用 flex 布局:
... .wrapper { outline: 1px solid red; display: flex; flex-direction: column; } ...
網站 margin 策略
由于margin 會重疊,最好能找到一種一致的方法來處理網站的 margin。最簡單的方法是只在元素的頂部或底部定義 margin。這樣,就很少會遇到 margin 重疊的問題,因為有margin的邊總是與沒有margin的邊相鄰。
這個解決方案并不能解決你可能遇到的問題,因為子元素的margin會與父元素相互重疊。這個特定的問題往往不那么常見,但知道它為什么會發生可以幫助你想出一個解決方案。
對此,一個理想的解決方案是給元素設置 display: flow-root,但有的瀏覽器并不支持,可以使用overflow創建BFC、或將父元素設置成flex容器,當然還可以設置padding來解決。
百分比 margin
當你在CSS中使用百分比的時候,它必須是某個元素的百分比。使用百分比設置的 margin(或 padding)始終是父元素內聯大小(水平寫入模式下的寬度)的百分比。這意味著在使用百分比時,元素周圍的padding大小都是相同的。
在下面的示例中,有一個200px 寬的 d當,里面是一個類名為 box 的div,它的 margin值為10%,也就是 20px (200*10%)。
html
<div class="wrapper"> <div class="box"> I have a margin of 10%. </div> </div>
css
* { box-sizing: border-box; } .wrapper { border: 5px dotted black; width: 200px; } .box { background-color: rgb(55,55,110); color: white; padding: 20px; border-radius: .5em; margin: 10%; } body { font: 1.4em/1.3 "Gill Sans", "Gill Sans MT", Calibri, sans-serif; margin: 2em 3em; }
我們在本文中一直在討論垂直 margin ,然而,現代CSS傾向于以相對于流的方式而不是物理方式來考慮事情。因此,當我們討論垂直邊距時,我們實際上是在討論塊維度的邊距。如果我們在水平寫作模式下,這些 margin 將是頂部和底部,但在垂直寫作模式下,這些 margin 將是右側和左側。
一旦使用邏輯的、流相關的方向,就更容易討論塊的開始和結束,而不是塊的頂部和底部。為了簡化這一過程,CSS引入了邏輯屬性和值規范。這將流的相關屬性映射到物理屬性上。
還有兩個新的快捷鍵,可以同時設置兩個塊或者兩個內嵌塊。
在下面示例中,使用了這些流相關關鍵字,然后更改了盒子的編寫模式,你可以看到 margin 是如何遵循文本方向的:
html
<div class="wrapper horizontal-tb"> <div class="box"> A box with a horizontal-tb writing mode. </div> </div> <div class="wrapper vertical-rl"> <div class="box"> A box with a vertical-rl writing mode. </div> </div>
css
* { box-sizing: border-box; } .wrapper { border: 5px dotted black; inline-size: 200px; } .horizontal-tb { writing-mode: horizontal-tb; margin-bottom: 1em; } .vertical-rl { writing-mode: vertical-rl; } .box { background-color: rgb(55,55,110); color: white; padding: 20px; border-radius: .5em; margin-block-start: 30px; margin-block-end: 10px; margin-inline-start: 2em; margin-inline-end: 5%; } body { font: 1.4em/1.3 "Gill Sans", "Gill Sans MT", Calibri, sans-serif; margin: 2em 3em; }
需要了解更多,可以閱讀有關MDN上的邏輯屬性和值的更多信息。
代碼部署后可能存在的BUG沒法實時知道,事后為了解決這些BUG,花了大量的時間進行log 調試,這邊順便給大家推薦一個好用的BUG監控工具 Fundebug。
交流
干貨系列文章匯總如下,覺得不錯點個Star,歡迎 加群 互相學習。
https://github.com/qq449245884/xiaozhi
我是小智,公眾號「大遷世界」作者,對前端技術保持學習愛好者。我會經常分享自己所學所看的干貨,在進階的路上,共勉!
關注公眾號,后臺回復福利,即可看到福利,你懂的。
山河依舊,網站、App 從此再無灰色、黑色情況?。。?/p>
夢中清醒,哦,又是一個陽光明媚的早上。
致敬英雄,市面上 App、網站等都已置灰。
緬懷的同時,突然冒出一個問題,怎么做到的?難不成一個個調整圖片,調整對應的控件色值?
顯然不應該。想來想去還不如直接調試一番,找找感覺。
Chrome 打開 B 站,直接打開開發者模式,html 根節點有個 class=“gray”,好奇點點看看有什么反映:
一個 class 搞定嗎?抱著懷疑的心態找了掘金:
共同點,都是使用了 filter:grayscale。
filter CSS屬性將模糊或顏色偏移等圖形效果應用于元素。濾鏡通常用于調整圖像,背景和邊框的渲染。
官方給出一個小例子:
找到對應將圖像轉為灰色圖像屬性:
俗話說得好,好記性不如爛筆頭,自己親自動手才是最實際的。
效果很明顯,如果想讓整個頁面圖片灰度發生變化,只需要按照前輩們的方案,直接在 html 設置 class 即可,方案采用掘金:
附上對應 CSS 樣式:
.mourning {
-webkit-filter: grayscale(100%); /* 兼容 Chrome、Safari 瀏覽器 */
-moz-filter: grayscale(100%); /* 兼容 FireFox 火狐瀏覽器 */
-ms-filter: grayscale(100%); /* 兼容 IE 瀏覽器 */
-o-filter: grayscale(100%); /* 兼容 Opera 瀏覽器 */
filter: grayscale(100%);
filter: #808080;
}
哪有什么歲月靜好,不過是有人替你負重前行。
心懷感恩。
最后,再次希望所有的網站再也不要有變成灰色、黑色的情況!?。?/strong>
永遠也不要有了?。?!
/ Google研究院軟件工程師,Tingbo Hou & Tyler Mullen
譯者 / Alpha
技術審校:斗魚前端專家,王興偉
原文 /https://ai.googleblog.com/2020/10/background-features-in-google-meet.html
在人們的工作和生活中,視頻會議變得越來越重要。我們可以通過增強隱私保護,或者添加有趣的視覺效果來改善視頻體驗,同時幫助人們將注意力集中在會議內容上。我們最近宣布的在Google Meet中模糊和替換背景的方法,就是為了實現這一目標而邁出的一小步。
我們利用機器學習(ML)來更好地突出參與者,從而忽略他們周圍的背景環境。盡管其他的解決方案需要安裝額外的軟件,但Meet的功能是由尖端的Web ML技術提供支持的,這些技術是用MediaPipe構建的,可以直接在你的瀏覽器中工作——不需要額外的步驟。
開發這些功能,有一個關鍵目標,即它可以給幾乎所有現代設備提供實時的瀏覽器內性能,通過XNNPACK和TFLite,我們將高效的設備上ML模型、基于WebGL的效果渲染,還有基于Web的ML推理結合起來,進而實現了這一目標。
背景模糊和背景替換,由網頁端的 MediaPipe 提供支持。
網絡Web ML方案概述
Meet中的新功能是與MediaPipe一起開發的,MediaPipe是谷歌的開源框架,用于為直播和流媒體提供跨平臺的,可定制的ML解決方案,它還支持設備上實時性的手、虹膜和身體姿勢追蹤等ML解決方案。
任何設備上解決方案的核心需求,都是實現高性能。為了實現這一點,MediaPipe的Web工作流利用了WebAssembly,這是一種專為網絡瀏覽器設計的底層二進制代碼格式,可以提高計算繁重任務的速度。在運行時,瀏覽器將WebAssembly指令轉換為本機代碼,執行速度比傳統JavaScript代碼快很多。此外,Chrome84最近引入了對WebAssembly SIMD的支持,每條指令可以處理多個數據點,性能提升了2倍以上。
首先,我們的解決方案通過將用戶,和他們的背景進行分割(稍后將詳細介紹我們的分割模型),來處理每個視頻幀,使用ML推理來計算出一個低分辨率的蒙版?;蛘?,我們還可以進一步細化蒙版,以使其與圖像邊界對齊。然后通過WebGL2使用蒙版來渲染視頻,實現背景的模糊或替換。
WebML Pipeline:所有計算繁重的操作都是用C++/OpenGL實現的,并通過WebAssembly在瀏覽器中運行。
在當前版本中,模型推理在客戶端的CPU上執行,以實現低功耗和最大的設備覆蓋范圍。為了達到實時性能,我們設計了高效的ML模型,通過XNNPACK庫加速推理,XNNPACK庫是第一個專門為新的WebAssembly SIMD規范設計的推理引擎。在XNNPACK和SIMD的加速下,該分割模型可以在Web上以實時速度運行。
在MediaPipe靈活配置的支持下,背景模糊/替換解決方案可根據設備能力,調整其處理過程。在高端設備上,它運行完整的工作流,以提供最佳的視覺質量,而在低端設備上,通過使用輕量級的ML模型進行計算,并且繞過蒙版細化,它仍然可以保持較高的性能。
分割模型細分
設備上的機器學習模型必須是超輕量級的,以實現快速推理、低功耗和較小的下載大小。對于在瀏覽器中運行的模型,輸入分辨率會極大地影響處理的每一幀所需的浮點運算(FLOP)的數量,由此也必須很小。我們將圖像下采樣,得到較小的尺寸,然后再將其提供給模型。從低分辨率圖像中,盡可能精確地恢復分割蒙版,這增加了模型設計的挑戰。
整個分割網絡具有關于編碼和解碼的對稱結構,而解碼器塊(淺綠色),也與編碼塊(淺藍色)共享對稱層結構。具體地說,在編碼器和解碼器模塊中,都采用了應用有全局池化層技術的通道注意力機制,這有利于高效的CPU推理。
采用MobileNetV3編碼器(淺藍色)和對稱解碼器(淺綠色)的模型架構。
我們修改MobileNetV3-Small為編碼器,經過網絡結構搜索的優化,以最低的資源需求,獲得最佳的性能。為了減少50%的模型尺寸,我們使用Float16量化技術將模型導出到TFLite,僅權重精度略有下降,但對質量沒有明顯的影響。得到的模型有193K參數,大小只有400KB。
效果渲染
分割完成后,我們使用OpenGL著色器進行視頻處理和效果渲染,其中的挑戰就是在不引入偽影的情況下進行高效渲染。在細化階段,我們采用聯合雙邊濾波器對低分辨率蒙版進行平滑處理
渲染效果時會減少瑕疵減少的渲染效果。左:聯合雙邊過濾器平滑分段分割蒙版。中:可分離濾鏡移除背景模糊中的光暈瑕疵。右:替換背景中的燈光包裹包裝(light wrapping)。
模糊著色器通過與分割蒙版值成比例的方式,調整每個像素的模糊強度,來模擬波克(bokeh)效果,類似于光學中的混淆圓(CoC)。像素按其CoC半徑加權,因此前景像素不會滲入背景。我們為加權模糊實現了可分離的過濾器,而不是流行的高斯金字塔,因為它去除了人周圍的光暈偽影。為了提高效率,模糊以低分辨率執行,并以原始分辨率與輸入幀混合
背景模糊示例
對于背景替換,我們采用了一種稱為燈光包裹(Light wrapping)的合成技術,用于混合分割的人物和定制的背景圖像。光線包裹允許背景光溢出到前景元素上,從而使合成更具沉浸感,這有助于柔化分割邊緣。當前景和替換的背景之間,存在較大的對比度時,它還有助于最大限度地減少光暈偽影
背景替換示例
性能
為了優化不同設備的體驗,我們提供多種輸入尺寸(即當前版本中的256x144和160x96)的模型變體,根據可用的硬件資源自動選擇最佳模型。
我們在兩款常見設備上評估了模型推理和端到端傳遞的速度:搭載2.2 GHz 6核英特爾酷睿i7的MacBook Pro 2018和搭載英特爾賽揚N3060的宏碁Chromebook 11。對于720p的輸入,MacBook Pro可以以120 FPS的速度,運行較高質量的模型,以70 FPS的速度運行端到端的傳遞途徑;而Chromebook則以62 FPS的速度運行推理,使用較低質量的模型,端到端運行在33 FPS。
高端(MacBook Pro)和低端(Chromebook)筆記本電腦上的模型型號推斷速度和端到端管線傳遞。
為了定量評估模型的精度,我們采用了目前流行的交集-并集(IOU)和邊界F-度量。這兩種型號都有不俗的表現,而且還是在這樣一個輕量級網絡的情況下
模型準確性的評估,通過 IOU 借條和邊界 F-分數來衡量。
我們還為我們的分割模型發布了隨附的模型卡,其中詳細介紹了我們的公平性評估。我們的評估數據包含來自全球17個地理分區的圖像,并附有膚色和性別的注釋。我們的分析表明,該模型在不同地區、膚色和性別上的表現是一致的,只有很小的IOU指標偏差。
結論
我們推出了一個全新的瀏覽器端的機器學習解決方案,用于模糊和替換你在Google Meet中的背景。使用這個方案,機器學習模型和OpenGL著色器就可以在Web上高效運行。所開發的功能即使在低功耗設備上也能以低功耗實現實時性能
致謝:特別感謝Meet團隊的成員和參與此項目的其他人員,特別是Sebastian Jansson,Rikard Lundmark,Stephan Reiter,Fabian Bergmark,Ben Wagner,Stefan Holmer,Dan Gunnarson,Stéphane Hulaud以及所有與我們一起從事技術工作的團隊成員:Siargey Pisarchyk,Karthik Raveendran,Chris McClanahan, Marat Dukhan,Frank Barchard,Ming Guang Yong,Chuo-Ling Chang,Michael Hays,Camillo Lugaresi,Gregory Karpiak,Siarhei Kazakou,Matsvei Zhdanovich,Matthias Grundmann。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。