快應(yīng)用 style樣式

2020-08-08 17:46 更新

用于描述 template 模板的組件樣式,決定組件應(yīng)該如何顯示

樣式布局采用 CSS Flexbox(彈性盒)樣式,針對(duì)部分原生組件,對(duì) CSS 進(jìn)行了少量的擴(kuò)充以及修改

為了解決屏幕適配問題,所有與大小相關(guān)的樣式(例如 width、font-size)均以基準(zhǔn)寬度(默認(rèn)750px)為基礎(chǔ),根據(jù)實(shí)際屏幕寬度進(jìn)行縮放,例如 width:100px,在 1500px 寬度屏幕上,width實(shí)際上為 200px

文件導(dǎo)入


支持2種導(dǎo)入外部文件的方式

<!-- 導(dǎo)入外部文件, 代替style內(nèi)部樣式 -->
<style src="./style.css"></style>

<!-- 合并外部文件 -->
<style>
 @import './style.css';
 .a{
  }
</style>

模板內(nèi)部樣式


支持使用 style、class 屬性來控制組件的樣式

<!-- 內(nèi)聯(lián)inline -->
<div style="color:red; margin: 10px;" />
<!-- class聲明 -->
<div class="normal append" />

選擇器


支持的選擇器有:

選擇器 樣例 樣例描述
.class .intro 選擇所有擁有 class="intro" 的組件
#id #firstname 選擇擁有 id="firstname" 的組件
tag div 選擇所有 div 組件
, .a, .b 選擇所有class=“.a” 以及class=“.b”的組件
#id .class tag .page .body text 支持id,class,tag的后代選擇器,也可以使用">"表示直接后代
<style>
// 單個(gè)選擇器
text {
}
.class-abc {
}
#idAbc {
}

// 后代選擇
.doc-page #testTag div text {
}
.doc-page #test-class .class1 {
}
.doc-page #testId #testIdId1 {
}
// 直接后代選擇
.doc-page #testTag .flex-column > text {
}

// 同一樣式適應(yīng)多個(gè)選擇器
.font-text, .font-comma {
}
</style>


注意,選擇器聲明的變化可能會(huì)導(dǎo)致元素重新繪制。為了減少選擇器變化引起的DOM更新數(shù)量,當(dāng)前只支持:CSS聲明的多個(gè)選擇器中最后一個(gè)規(guī)則的變更對(duì)DOM的更新

<template>
  <div class="{{docBody}}">
    <text class="{{rowDesc}}" value="描述內(nèi)容"></text>
  </div>
</template>

<style>
  .doc-body .row-desc1 {
    color: #ff0000;
  };
  .doc-body .row-desc2 {
    color: #0000ff;
  };
  .doc-body2 .row-desc1 {
    color: #00ff00;
  };
</style>

<script>
    export default {
      data: {
        rowDesc: "row-desc1",
        docBody: "doc-body"
      }
    }
</script>

以上的代碼示例,當(dāng)我們把rowDesc變量row-desc1變?yōu)?code>row-desc2時(shí)是通知Native更新節(jié)點(diǎn)樣式,但是如果把docBody變量doc-body變?yōu)?code>doc-body2,是不會(huì)通知 DOM 更新的。

因?yàn)?code>doc-body不是最后一個(gè)選擇器,非末尾的選擇器變更有可能影響很多DOM元素,從而影響到渲染性能

選擇器優(yōu)先級(jí)


當(dāng)前樣式的選擇器的優(yōu)先級(jí)計(jì)算保持與瀏覽器一致,是瀏覽器 CSS 渲染的一個(gè)子集(僅支持:inline, id, class, tag, 后代,直接后代)

選擇器優(yōu)先級(jí)規(guī)則如下(假設(shè)多條CSS聲明匹配到同一個(gè)元素div),應(yīng)用在該元素上的CSS聲明總體優(yōu)先級(jí)是:inline > #id > .class > tag,這四大類

匹配到該元素的多個(gè) CSS 聲明,如:#page .class-div.page .class-div,其優(yōu)先級(jí)按照各選擇器的分?jǐn)?shù)高低之和來比較

ID 選擇器的權(quán)值為10000 Class 類選擇器的權(quán)值為100 Tag 標(biāo)簽選擇器的權(quán)值為1

那么以下CSS聲明計(jì)算分?jǐn)?shù)為:

  • #page的分?jǐn)?shù)為:10000

  • #page .class-div的分?jǐn)?shù)為:10100

  • #page .class-div text的分?jǐn)?shù)為10101

  • #page #body .container div text的分?jǐn)?shù)為:20102

  • 因此:

  • #page .class-div.page .class-div比較,分?jǐn)?shù)不一致,分?jǐn)?shù)高優(yōu)先級(jí)高;如果分?jǐn)?shù)相同,則按照聲明順序:后者覆蓋前者

媒體查詢 

快應(yīng)用從 1070 版本開始支持媒體查詢能力。通過媒體查詢(media query),開發(fā)者可以根據(jù)各種設(shè)備特征和參數(shù)的值或者是否存在來調(diào)整快應(yīng)用的樣式。

媒體查詢是響應(yīng)式設(shè)計(jì)的一部分。在快應(yīng)用中,和 css 類似,可使用 @media at-rule 根據(jù)媒體查詢的結(jié)果,有條件地應(yīng)用樣式表的一部分;也可使用 @import 有條件地應(yīng)用整個(gè)樣式表。

注意:媒體查詢除了需要快應(yīng)用平臺(tái)版本在1070以上,也需要快應(yīng)用打包工具 hap-toolkit 的版本號(hào)在0.6.15版本以上。(可通過命令hap -v查看)

示例代碼:

.box {
  width: 100px;
  height: 100px;
  background-color: black;
}

@media (orientation: landscape) {
  .box {
    background: white;
  }
}

語(yǔ)法:

每條媒體查詢語(yǔ)句都由一個(gè)可選的媒體類型和任意數(shù)量的媒體特性表達(dá)式構(gòu)成??梢允褂枚喾N邏輯操作符合并多條媒體查詢語(yǔ)句。媒體查詢語(yǔ)句不區(qū)分大小寫。

當(dāng)媒體類型(如果指定)與在其上顯示文檔的設(shè)備匹配并且所有媒體特性表達(dá)式都計(jì)算為true時(shí),媒體查詢將計(jì)算為true。 涉及未知媒體類型的查詢總是 false 的。

有兩種方法可以執(zhí)行媒體查詢:

@media 方式引入媒體查詢:

@media [media type] [and|not|only] [(media feature)] {
    CSS-Code;
}

舉例:

  • @media (max-width: 30) { ... } // level3的寫法。
  • @media (width <= 30) { ... } // level4的寫法,比level3更清晰簡(jiǎn)潔。
  • @media screen and (min-width: 400) and (max-width: 700) { ... } // 多條件寫法。
  • @media (400 <= width <= 700) { ... } // 多條件level4寫法。

@import 方式引入媒體查詢

@import ‘./css_file_name.css’ [media type] [and|not|only] [(media feature) ];

舉例:

  • @import './style.css' screen and (min-width: 400) and (max-width: 700); // 多條件寫法

媒體類型:

媒體類型(Media types)描述設(shè)備的類別。除了在使用 not 或 only 邏輯操作符必須一并填上媒體類型;其他時(shí)候,媒體類型是可選擇是否填入的。

目前快應(yīng)用支持的媒體類型如下:

媒體類型 簡(jiǎn)介
screen 主要用于屏幕。

媒體特性:

媒體特性(Media features)描述了輸出設(shè)備,或是瀏覽環(huán)境的具體特征。媒體特性表達(dá)式是完全可選的,它負(fù)責(zé)測(cè)試這些特性或特征是否存在、值為多少。

每條媒體特性表達(dá)式都必須用括號(hào)括起來。

目前快應(yīng)用支持的媒體特性如下:

類型 描述 查詢時(shí)是否需帶單位 支持單位
height 定義輸出設(shè)備中的頁(yè)面可視區(qū)域高度 dp
min-height 定義輸出設(shè)備中的頁(yè)面可視區(qū)域最小高度 dp
max-height 定義輸出設(shè)備中的頁(yè)面可視區(qū)域最大高度 dp
width 定義輸出設(shè)備中的頁(yè)面可視區(qū)域?qū)挾?/td> dp
min-width 定義輸出設(shè)備中的頁(yè)面可視區(qū)域最小寬度 dp
max-width 定義輸出設(shè)備中的頁(yè)面可視區(qū)域最大寬度 dp
resolution 定義輸出設(shè)備的分辨率 dppx,dpi
min-resolution 定義輸出設(shè)備的最小分辨率 dppx,dpi
max-resolution 定義輸出設(shè)備的最大分辨率 dppx,dpi
orientation 定義屏幕處于橫屏模式還是豎屏模式,支持屬性:portrait(豎屏)、landscape(橫屏)
aspect-ratio 定義輸出設(shè)備中的頁(yè)面可見區(qū)域?qū)捀弑?,比例值需要按?code>x / y的格式,例如 1 / 2
min-aspect-ratio 定義輸出設(shè)備中的頁(yè)面可見區(qū)域最小寬高比,參數(shù)要求同上
max-aspect-ratio 定義輸出設(shè)備中的頁(yè)面可見區(qū)域最大寬高比,參數(shù)要求同上
prefers-color-scheme 檢測(cè)用戶的系統(tǒng)主題,僅在 Android 10+系統(tǒng)生效。支持屬性:light(日間模式)、dark(夜間模式)

注意:

1.dppx 的值對(duì)應(yīng)的是快應(yīng)用的device接口的getInfo方法返回值的screenDensity值,也與瀏覽器里 BOM API 的 Window.devicePixelRatio 值一樣

舉例:一臺(tái)安卓物理分辨率為 1920*1080 的手機(jī),screenDensity = 3,所以此設(shè)備滿足(resolution: 3dppx)的查詢條件

2.dpi 的值= 160 * dppx 的值,dppx 值計(jì)算可參考第 1 條規(guī)則。

舉例:一臺(tái)安卓物理分辨率為 1920*1080 的手機(jī),screenDensity = 3,此設(shè)備的 dpi 值 = 160 * 3 = 480,所以此設(shè)備滿足(resolution: 480dpi)的查詢條件

3.在媒體特性列表中,標(biāo)記了"查詢時(shí)不帶單位"的媒體特性,如 width、height 的查詢,都不帶長(zhǎng)度單位,且長(zhǎng)度單位只能為dp

dp 數(shù)值 = 物理分辨率 / screenDensity

舉例:一臺(tái)安卓物理分辨率為 1920*1080 的手機(jī),screenDensity = 3,屏幕寬度 = 1080 像素 = 360dp,所以此設(shè)備滿足(width:360)的查詢條件

4.媒體特性里,頁(yè)面可視區(qū)域的意思是整個(gè)屏幕去掉通知欄、標(biāo)題欄等其他非快應(yīng)用前端可以控制布局渲染的區(qū)域。其寬高值都可以用快應(yīng)用的device接口的getInfo獲取,以下是示例代碼:

<script>
import device from "@system.device";
export default {
  onReady() {
    device.getInfo({
      success: function(result) {
        let { windowWidth = 0, windowHeight = 0, screenDensity = 0 } = result;
        console.log(`像素密度(同樣也是dppx的值): ${screenDensity}`);
        console.log(`可視區(qū)域?qū)挾龋ㄎ锢矸直媛剩? ${windowWidth}`);
        console.log(`可視區(qū)域高度(物理分辨率): ${windowHeight}`);
        console.log(`可視區(qū)域?qū)挾龋╠p單位): ${windowWidth / screenDensity}`);
        console.log(`可視區(qū)域高度(dp單位): ${windowHeight / screenDensity}`);
        console.log(`設(shè)備dpi值: ${screenDensity * 160}`);
      }
    });
  }
};
</script>

邏輯操作符:

開發(fā)者可以使用邏輯操作符組合多個(gè)媒體特性的查詢條件,編寫復(fù)雜的媒體查詢

類型 描述
and and 運(yùn)算符用于將多個(gè)媒體特性組合到一個(gè)單獨(dú)的媒體查詢中,要求每個(gè)鏈接的特性返回 true,則此時(shí)查詢?yōu)檎妗?/td>
not not 運(yùn)算符用于否定媒體查詢,如果查詢不返回 false,則返回 true。如果出現(xiàn)在逗號(hào)分隔的列表中,它只會(huì)否定應(yīng)用它的特定查詢。如果使用 not 運(yùn)算符,則必須指定顯式媒體類型。
例如:not screen and (min-width: 400) and (max-width: 700)
注:not 關(guān)鍵字不能用于否定單個(gè)功能表達(dá)式,它會(huì)作用于整個(gè)媒體查詢。
only only 運(yùn)算符僅用于整個(gè)查詢匹配應(yīng)用樣式, 快應(yīng)用處理以 only 開頭的關(guān)鍵詞時(shí)將會(huì)忽略 only。
如果使用 only 運(yùn)算符,必須指定媒體類型。例如:only screen and (min-width: 400) and (max-width: 700)
,
(逗號(hào))
逗號(hào)分隔效果等同于 or 邏輯操作符。當(dāng)使用逗號(hào)分隔的媒體查詢時(shí),如果任何一個(gè)媒體查詢返回真,樣式就是有效的。
例如:(orientation: landscape), (height >= 690)
or or 運(yùn)算符用于將多個(gè)媒體特性比較語(yǔ)句組合到一個(gè)媒體查詢語(yǔ)句中,只要有其中一條媒體特性比較語(yǔ)句返回 true,查詢成立。
例如:(min-width: 400) or (max-width: 700)
<= 小于等于。例如: (400 <= width)
>= 大于等于。例如: (500 >= height)
< 小于。例如: (400 < width)
> 大于。例如: (500 > height)

樣式預(yù)編譯

目前快應(yīng)用支持lesssass的預(yù)編譯,具體教程也可以參考 這里

<!--導(dǎo)入外部文件, 代替style內(nèi)部樣式-->
<style lang="less" src="./lessFile.less"></style>

<!--合并外部文件-->
<style lang="less">
  @import './lessFile.less';
  .page-less {
    #testTag {
      .less-font-text, .less-font-comma {
        font-size: 60px;
      }
    }
  }
</style>

偽類

任何組件中,如果某個(gè)屬性是 boolean 類型且默認(rèn)值為 false 時(shí),均可通過該屬性名字來聲明偽類,當(dāng)屬性變?yōu)?true 時(shí)偽類生效,例如所有組件的 disabled 屬性、input 組件的 checked 屬性等

另外部分組件會(huì)有其他形式的偽類支持,比如 input 組件可以通過主動(dòng)調(diào)用 focus 方法,或者用戶操作獲得焦點(diǎn),使得 focus 偽類生效,詳情請(qǐng)參考各組件內(nèi)部說明

1010+版本上提供了 active 偽類的支持,當(dāng)用戶按下組件時(shí)該偽類生效。其中默認(rèn)可點(diǎn)擊的組件(input, a, picker, switch 等)聲明即有效,非默認(rèn)可點(diǎn)擊組件(image, text, div, stack 等)聲明該偽類后須同時(shí)監(jiān)聽 click 事件才有效果

偽類寫法舉例:

<template>
  <div class="doc-page">
    <input type="button" class="btn" disabled="{{btndisabled}}" value="Click" onclick="btnClick" />
  </div>
</template>

<style>
  .doc-page {
    flex: 1;
    align-items: center;
    justify-content: center;
  }
  .btn {
    width: 360px;
    height: 120px;
    background-color: red;
  }
  .btn:disabled{
    background-color: green;
  }
</style>

<script>
  export default {
    data: {
      btndisabled: false
    },
    btnClick () {
      this.btndisabled = true
    }
  }
  </script>

當(dāng)組件的 disabled 屬性變?yōu)?true 時(shí),disabled 偽類的樣式生效,疊加到原有樣式上,例子中 background-color 會(huì)從紅色變成綠色


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)