兩欄布局的實現
一般兩欄布局指的是左邊一欄寬度固定,右邊一欄寬度自適應,兩欄布局的具體實現:
利用浮動,將左邊元素寬度設置為 200px,并且設置向左浮動。將右邊元素的 margin-left 設置為 200px,寬度設置為 auto(默認為 auto,撐滿整個父元素)。
.outer {
height: 100px;
}
.left {
float: left;
width: 200px;
background: tomato;
}
.right {
margin-left: 200px;
width: auto;
background: gold;
}
復制代碼
利用浮動,左側元素設置固定大小,并左浮動,右側元素設置 overflow: hidden; 這樣右邊就觸發了 BFC,BFC 的區域不會與浮動元素發生重疊,所以兩側就不會發生重疊。
.left{
width: 100px;
height: 200px;
background: red;
float: left;
}
.right{
height: 300px;
background: blue;
overflow: hidden;
}
復制代碼
利用 flex 布局,將左邊元素設置為固定寬度 200px,將右邊的元素設置為 flex:1。
.outer {
display: flex;
height: 100px;
}
.left {
width: 200px;
background: tomato;
}
.right {
flex: 1;
background: gold;
}
復制代碼
利用絕對定位,將父級元素設置為相對定位。左邊元素設置為 absolute 定位,并且寬度設置為 200px。將右邊元素的 margin-left 的值設置為 200px。
.outer {
position: relative;
height: 100px;
}
.left {
position: absolute;
width: 200px;
height: 100px;
background: tomato;
}
.right {
margin-left: 200px;
background: gold;
}
復制代碼
利用絕對定位,將父級元素設置為相對定位。左邊元素寬度設置為 200px,右邊元素設置為絕對定位,左邊定位為 200px,其余方向定位為 0。
.outer {
position: relative;
height: 100px;
}
.left {
width: 200px;
background: tomato;
}
.right {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 200px;
background: gold;
}
復制代碼
三欄布局的實現
三欄布局一般指的是頁面中一共有三欄,左右兩欄寬度固定,中間自適應的布局,三欄布局的具體實現:
利用絕對定位,左右兩欄設置為絕對定位,中間設置對應方向大小的 margin 的值。
.outer {
position: relative;
height: 100px;
}
.left {
position: absolute;
width: 100px;
height: 100px;
background: tomato;
}
.right {
position: absolute;
top: 0;
right: 0;
width: 200px;
height: 100px;
background: gold;
}
.center {
margin-left: 100px;
margin-right: 200px;
height: 100px;
background: lightgreen;
}
復制代碼
利用 flex 布局,左右兩欄設置固定大小,中間一欄設置為 flex:1。
.outer {
display: flex;
height: 100px;
}
.left {
width: 100px;
background: tomato;
}
.right {
width: 100px;
background: gold;
}
.center {
flex: 1;
background: lightgreen;
}
復制代碼
利用浮動,左右兩欄設置固定大小,并設置對應方向的浮動。中間一欄設置左右兩個方向的 margin 值,注意這種方式**,中間一欄必須放到最后:**
.outer {
height: 100px;
}
.left {
float: left;
width: 100px;
height: 100px;
background: tomato;
}
.right {
float: right;
width: 200px;
height: 100px;
background: gold;
}
.center {
height: 100px;
margin-left: 100px;
margin-right: 200px;
background: lightgreen;
}
復制代碼
圣杯布局,利用浮動和負邊距來實現。父級元素設置左右的 padding,三列均設置向左浮動,中間一列放在最前面,寬度設置為父級元素的寬度,因此后面兩列都被擠到了下一行,通過設置 margin 負值將其移動到上一行,再利用相對定位,定位到兩邊。
.outer {
height: 100px;
padding-left: 100px;
padding-right: 200px;
}
.left {
position: relative;
left: -100px;
float: left;
margin-left: -100%;
width: 100px;
height: 100px;
background: tomato;
}
.right {
position: relative;
left: 200px;
float: right;
margin-left: -200px;
width: 200px;
height: 100px;
background: gold;
}
.center {
float: left;
width: 100%;
height: 100px;
background: lightgreen;
}
復制代碼
雙飛翼布局,雙飛翼布局相對于圣杯布局來說,左右位置的保留是通過中間列的 margin 值來實現的,而不是通過父元素的 padding 來實現的。本質上來說,也是通過浮動和外邊距負值來實現的。
.outer {
height: 100px;
}
.left {
float: left;
margin-left: -100%;
width: 100px;
height: 100px;
background: tomato;
}
.right {
float: left;
margin-left: -200px;
width: 200px;
height: 100px;
background: gold;
}
.wrApper {
float: left;
width: 100%;
height: 100px;
background: lightgreen;
}
.center {
margin-left: 100px;
margin-right: 200px;
height: 100px;
}
復制代碼
水平垂直居中的實現
利用絕對定位,先將元素的左上角通過 top:50%和 left:50%定位到頁面的中心,然后再通過 translate 來調整元素的中心點到頁面的中心。該方法需要考慮瀏覽器兼容問題。
.parent {
position: relative;
}
.child {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
復制代碼
利用絕對定位,設置四個方向的值都為 0,并將 margin 設置為 auto,由于寬高固定,因此對應方向實現平分,可以實現水平和垂直方向上的居中。該方法適用于盒子有寬高的情況:
.parent {
position: relative;
}
.child {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
復制代碼
利用絕對定位,先將元素的左上角通過 top:50%和 left:50%定位到頁面的中心,然后再通過 margin 負值來調整元素的中心點到頁面的中心。該方法適用于盒子寬高已知的情況
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
margin-top: -50px; /* 自身 height 的一半 */
margin-left: -50px; /* 自身 width 的一半 */
}
復制代碼
使用 flex 布局,通過 align-items:center 和 justify-content:center 設置容器的垂直和水平方向上為居中對齊,然后它的子元素也可以實現垂直和水平的居中。該方法要考慮兼容的問題,該方法在移動端用的較多:
.parent {
display: flex;
justify-content:center;
align-items:center;
}
復制代碼
另外,如果父元素設置了flex布局,只需要給子元素加上margin:auto;就可以實現垂直居中布局
.parent{
display:flex;
}
.child{
margin: auto;
}
復制代碼
這里蠻有意思的 如果不在彈性布局中 margin:auto;只能做到水平居中
這其中的道理可以看這篇文章了解一下(具體就是與auto的定義有關)
實現一個三角形
css 繪制三角形主要用到的是 border 屬性,也就是邊框。
平時在給盒子設置邊框時,往往都設置很窄,就可能誤以為邊框是由矩形組成的。實際上,border 屬性是三角形組成的,下面看一個例子:
div {
width: 0;
height: 0;
border: 100px solid;
border-color: orange blue red green;
}
復制代碼
將元素的長寬都設置為 0,顯示出來的效果是這樣的:
所以可以根據 border 這個特性來繪制三角形:
- 三角 1
div {
width: 0;
height: 0;
border-top: 50px solid red;
border-right: 50px solid transparent;
border-left: 50px solid transparent;
}
復制代碼
- 三角 5
div {
width: 0;
height: 0;
border-top: 100px solid red;
border-right: 100px solid transparent;
}
復制代碼
還有很多,就不一一實現了,總體的原則就是通過上下左右邊框來控制三角形的方向,用邊框的寬度比來控制三角形的角度。
實現一個扇形
用 CSS 實現扇形的思路和三角形基本一致,就是多了一個圓角的樣式,實現一個 90° 的扇形:
div{
border: 100px solid transparent;
width: 0;
height: 0;
border-radius: 100px;
border-top-color: red;
}
復制代碼
實現一個寬高自適應的正方形
- 利用 vw 來實現:
.square {
width: 10%;
height: 10vw;
background: tomato;
}
復制代碼
- 利用元素的 margin/padding 百分比是相對父元素 width 的性質來實現:
.square {
width: 20%;
height: 0;
padding-top: 20%;
background: orange;
}
復制代碼
- 利用子元素的 margin-top 的值來實現:
.square {
width: 30%;
overflow: hidden;
background: yellow;
}
.square::after {
content: '';
display: block;
margin-top: 100%;
}
復制代碼
畫一條 0.5px 的線
采用 transform: scale()的方式,該方法用來定義元素的 2D 縮放轉換:
transform: scale(0.5,0.5);
復制代碼
采用 meta viewport 的方式
<meta name="viewport" content="width=device-width, initial-scale=0.5, minimum-scale=0.5, maximum-scale=0.5"/>
復制代碼
這樣就能縮放到原來的 0.5 倍,如果是 1px 那么就會變成 0.5px。viewport 只針對于移動端,只在移動端上才能看到效果
設置小于 12px 的字體
在谷歌下 css 設置字體大小為 12px 及以下時,顯示都是一樣大小,都是默認 12px。
解決辦法:
- 使用 Webkit 的內核的-webkit-text-size-adjust 的私有 CSS 屬性來解決,只要加了-webkit-text-size-adjust:none;字體大小就不受限制了。但是 chrome 更新到 27 版本之后就不可以用了。所以高版本 chrome 谷歌瀏覽器已經不再支持-webkit-text-size-adjust 樣式,所以要使用時候慎用。
- 使用 css3 的 transform 縮放屬性-webkit-transform:scale(0.5); 注意-webkit-transform:scale(0.75);收縮的是整個元素的大小,這時候,如果是內聯元素,必須要將內聯元素轉換成塊元素,可以使用 display:block/inline-block/...;
- 使用圖片:如果是內容固定不變情況下,使用將小于 12px 文字內容切出做圖片,這樣不影響兼容也不影響美觀。
如何解決 1px 問題?
1px 問題指的是:在一些 Retina屏幕 的機型上,移動端頁面的 1px 會變得很粗,呈現出不止 1px 的效果。原因很簡單——CSS 中的 1px 并不能和移動設備上的 1px 劃等號。它們之間的比例關系有一個專門的屬性來描述:
window.devicePixelRatio = 設備的物理像素 / CSS像素。
復制代碼
打開 Chrome 瀏覽器,啟動移動端調試模式,在控制臺去輸出這個 devicePixelRatio 的值。這里選中 iphone6/7/8 這系列的機型,輸出的結果就是 2:
這就意味著設置的 1px CSS 像素,在這個設備上實際會用 2 個物理像素單元來進行渲染,所以實際看到的一定會比 1px 粗一些。
解決1px問題的三種思路:
思路一:直接寫 0.5px
如果之前 1px 的樣式這樣寫:
border:1px solid #333
復制代碼
可以先在 JS 中拿到 window.devicePixelRatio 的值,然后把這個值通過 JSX 或者模板語法給到 CSS 的 data 里,達到這樣的效果(這里用 JSX 語法做示范):
<div id="container" data-device={{window.devicePixelRatio}}></div>
復制代碼
然后就可以在 CSS 中用屬性選擇器來命中 devicePixelRatio 為某一值的情況,比如說這里嘗試命中 devicePixelRatio 為 2 的情況:
#container[data-device="2"] {
border:0.5px solid #333
}
復制代碼
直接把 1px 改成 1/devicePixelRatio 后的值,這是目前為止最簡單的一種方法。這種方法的缺陷在于兼容性不行,IOS 系統需要 8 及以上的版本,Android/ target=_blank class=infotextkey>安卓系統則直接不兼容。
思路二:偽元素先放大后縮小
這個方法的可行性會更高,兼容性也更好。唯一的缺點是代碼會變多。
思路是先放大、后縮小:在目標元素的后面追加一個 ::after 偽元素,讓這個元素布局為 absolute 之后、整個伸展開鋪在目標元素上,然后把它的寬和高都設置為目標元素的兩倍,border 值設為 1px。接著借助 CSS 動畫特效中的放縮能力,把整個偽元素縮小為原來的 50%。此時,偽元素的寬高剛好可以和原有的目標元素對齊,而 border 也縮小為了 1px 的二分之一,間接地實現了 0.5px 的效果。
代碼如下:
#container[data-device="2"] {
position: relative;
}
#container[data-device="2"]::after{
position:absolute;
top: 0;
left: 0;
width: 200%;
height: 200%;
content:"";
transform: scale(0.5);
transform-origin: left top;
box-sizing: border-box;
border: 1px solid #333;
}
復制代碼
思路三:viewport 縮放來解決
這個思路就是對 meta 標簽里幾個關鍵屬性下手:
<meta name="viewport" content="initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
復制代碼
這里針對像素比為 2 的頁面,把整個頁面縮放為了原來的 1/2 大小。這樣,本來占用 2 個物理像素的 1px 樣式,現在占用的就是標準的一個物理像素。根據像素比的不同,這個縮放比例可以被計算為不同的值,用 js 代碼實現如下:
const scale = 1 / window.devicePixelRatio;
// 這里 metaEl 指的是 meta 標簽對應的 Dom
metaEl.setAttribute('content', `width=device-width,user-scalable=no,initial-scale=${scale},maximum-scale=${scale},minimum-scale=${scale}`);
復制代碼
這樣解決了,但這樣做的副作用也很大,整個頁面被縮放了。這時 1px 已經被處理成物理像素大小,這樣的大小在手機上顯示邊框很合適。但是,一些原本不需要被縮小的內容,比如文字、圖片等,也被無差別縮小掉了。
作者:教主鴿鴿
鏈接:
https://juejin.cn/post/7081144288398016520