注: この記事の内容は、HarmonyOS Developer 公式 Web サイトのドキュメントから共有および転載されています。
1. CSS 構文リファレンス
CSS は、HML ページの構造を記述するスタイル言語です。すべてのコンポーネントにはシステムのデフォルト スタイルがあり、ページ CSS スタイル ファイル内のコンポーネントとページに対してさまざまなスタイルをカスタマイズできます。JS 互換の Web ライクな開発パラダイムでサポートされるコンポーネント スタイルについては、「共通スタイル」を参照してください。
測定単位
● 論理ピクセル px (ドキュメントでは <length> として表現):
○ デフォルトの画面の論理幅は 720 ピクセルです (構成については、構成ファイルのウィンドウセクションを参照してください)。実際に表示されるとき、ページ レイアウトは 100 ピクセルなどの実際の画面の幅に合わせて拡大縮小されます。実際の幅は 1440 物理ピクセル、実際のレンダリングは 200 物理ピクセルです (720 ピクセルから 1440 物理ピクセル、すべての寸法は 2 の係数でスケールされます)。
○ 追加の設定 autoDesignWidth が true の場合 (設定については設定ファイルの window セクションを参照)、論理ピクセル px は画面密度に従ってスケーリングされます。たとえば、画面密度 3 のデバイスでは、実際には 100px になります。 300 物理ピクセルとしてレンダリングされます。この方法は、アプリを複数のデバイスに適応させる必要がある場合に推奨されます。
● パーセンテージ (ドキュメントでは <percentage> として表されます): このコンポーネントが占める親コンポーネントのサイズのパーセンテージを示します。たとえば、コンポーネントの幅が 50% に設定されている場合、その幅は 50 であることを意味します。親コンポーネントの %。
スタイルのインポート
モジュール管理とコードの再利用のために、CSS スタイル ファイルは CSS ファイルをインポートするための @import ステートメントをサポートしています。
宣言スタイル
各ページ ディレクトリには、レイアウト hml ファイルと同じ名前の css ファイルがあり、hml ページ内のコンポーネントのスタイルを記述し、コンポーネントの表示方法を決定するために使用されます。
1. 内部スタイル。コンポーネントのスタイルを制御するためのスタイル属性とクラス属性の使用をサポートします。例えば:
<!-- index.hml -->
<div class="container">
<text style="color: red">Hello World</text>
</div>
/* index.css */
.container {
justify-content: center;
}
2. ファイルをインポートし、外部スタイル ファイルをマージします。たとえば、スタイル ファイル style.css を common ディレクトリに定義し、それをindex.css ファイルの最初の行にインポートします。
/* style.css */
.title {
font-size: 50px;
}
/* index.css */
@import '../../common/style.css';
.container {
justify-content: center;
}
セレクタ
CSS セレクターは、スタイルを設定する必要がある要素を選択するために使用されます。サポートされているセレクターは、次の表に示すとおりです。
例:
<!-- 页面布局xxx.hml -->
<div id="containerId" class="container">
<text id="titleId" class="title">标题</text>
<div class="content">
<text id="contentId">内容</text>
</div>
</div>
/* 页面样式xxx.css */
/* 对所有div组件设置样式 */
div {
flex-direction: column;
}
/* 对class="title"的组件设置样式 */
.title {
font-size: 30px;
}
/* 对id="contentId"的组件设置样式 */
#contentId {
font-size: 20px;
}
/* 对所有class="title"以及class="content"的组件都设置padding为5px */
.title, .content {
padding: 5px;
}
/* 对class="container"的组件下的所有text设置样式 */
.container text {
color: #007dff;
}
/* 对class="container"的组件下的直接后代text设置样式 */
.container > text {
color: #fa2a2d;
}
上記のスタイルの効果は次のとおりです。
ここで、「.container text」は「タイトル」と「コンテンツ」を青に設定し、「.container > text」の直接子孫セレクターは「タイトル」を赤に設定します。2 つの優先順位は同じですが、直系の子孫セレクターの宣言順序が後になり、前のスタイルが上書きされます (優先順位の計算については、セレクターの優先順位を参照してください)。
セレクターの優先順位
セレクターの優先順位計算ルールは、w3c ルール (インライン スタイル、ID、クラス、タグ、子孫、直系子孫のみサポート) と一致しています。ここで、インライン スタイルは、要素の style 属性で宣言されたスタイルです。
複数のセレクター宣言が同じ要素に一致する場合、さまざまなセレクターの優先順位は高から低の順で、インライン スタイル > ID > クラス > タグになります。
疑似クラス
CSS 疑似クラスは、選択される要素の特別な状態を指定するセレクター内のキーワードです。たとえば、:disabled 状態は、要素の disabled 属性が true になったときに要素のスタイルを設定するために使用できます。
単一の疑似クラスに加えて、疑似クラスの組み合わせもサポートされます。たとえば、要素の focus 属性とchecked属性の両方が true の場合、 :focus:checked 状態を使用してスタイルを設定できます。次の表に、サポートされている個々の疑似クラスを優先順位の降順に示します。
疑似クラスの例は次のとおりです。ボタンの :active 疑似クラスを設定すると、ユーザーが押したときのスタイルを制御できます。
<!-- index.hml -->
<div class="container">
<input type="button" class="button" value="Button"></input>
</div>
/* index.css */
.button:active {
background-color: #888888;/*按钮被激活时,背景颜色变为#888888 */
}
説明する
擬似クラス効果は、ポップアップ、ダイアログ、メニュー、オプション、ピッカーなどのポップアップ ウィンドウ コンポーネントとそのサブ要素ではサポートされていません。
スタイルのプリコンパイル
プリコンパイルは、独自の構文を使用して CSS を生成するプログラムを提供します。変数、演算、その他の関数を提供できるため、開発者はコンポーネント スタイルをより簡単に定義できます。現在、less、sass、および scss のプリコンパイルをサポートしています。スタイルのプリコンパイルを使用する場合は、元の CSS ファイルのサフィックスをless、sass、または scss に変更する必要があります。たとえば、index.css をindex.less、index.sass、またはindex.scss に変更します。
● 現在のファイルはスタイルを使用してプリコンパイルされます。たとえば、元のindex.css をindex.less に変更します。
/* index.less */
/* 定义变量 */
@colorBackground: #000000;
.container {
background-color: @colorBackground; /* 使用当前less文件中定义的变量 */
}
● プリコンパイルされたファイルを参照します。たとえば、style.scss ファイルが共通に存在し、元のindex.css をindex.scss に変更し、style.scss を導入します。
/* style.scss */
/* 定义变量 */
$colorBackground: #000000;
Index.scss で引用:
/* index.scss */
/* 引入外部scss文件 */
@import '../../common/style.scss';
.container {
background-color: $colorBackground; /* 使用style.scss中定义的变量 */
}
説明する
参照されるプリコンパイル済みファイルは、管理用に共通ディレクトリに配置することをお勧めします。
CSS スタイルの継承 6+
CSS スタイルの継承により、子ノードが親ノードのスタイルを継承できるようになります。継承されたスタイルは、複数セレクターのスタイル一致のシナリオでは優先順位が最も低くなります。現在、次のスタイルの継承がサポートされています:
● フォントファミリー
● フォントの太さ
● フォントサイズ
● フォントスタイル
● テキスト整列
● 行の高さ
● 文字間隔
●色
● 視認性
2.CSSアニメーション
1. 属性スタイルのアニメーション
キーフレーム内の親コンポーネントの幅と高さを動的に設定して、コンポーネントを拡大または縮小します。子コンポーネントは、スケール属性を設定して親コンポーネントと子コンポーネントを同時にスケールし、次に不透明度を設定して親コンポーネントと子コンポーネントを表示または非表示にします。
<!-- xxx.hml -->
<div class="container">
<div class="fade">
<text>fading away</text>
</div>
<div class="bigger">
<text>getting bigger</text>
</div>
</div>
/* xxx.css */
.container {
background-color:#F1F3F5;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 100%;
height: 100%;
}
.fade {
width: 30%;
height: 200px;
left: 35%;
top: 25%;
position: absolute;
animation: 2s change infinite friction;
}
.bigger {
width: 20%;
height: 100px;
background-color: blue;
animation: 2s change1 infinite linear-out-slow-in;
}
text {
width: 100%;
height: 100%;
text-align: center;
color: white;
font-size: 35px;
animation: 2s change2 infinite linear-out-slow-in;
}
/* 颜色变化 */
@keyframes change{
from {
background-color: #f76160;
opacity: 1;
}
to {
background-color: #09ba07;
opacity: 0;
}
}
/* 父组件大小变化 */
@keyframes change1 {
0% {
width: 20%;
height: 100px;
}
100% {
width: 80%;
height: 200px;
}
}
/* 子组件文字缩放 */
@keyframes change2 {
0% {
transform: scale(0);
}
100% {
transform: scale(1.5);
}
}
説明する
● アニメーション値は順序を区別せず、Duration(アニメーション実行時間)/Delay(アニメーション遅延実行時間)が出現順に解析されます。
● アニメーション期間スタイルを設定する必要があります。設定しない場合、期間が 0 の場合、アニメーション効果はありません。anime-fill-mode 属性が forwards に設定されている場合、コンポーネントは最後のフレームのスタイルを直接表示します。
2. 変形スタイルのアニメーション
コンポーネントを回転、拡大縮小、移動、傾斜させるには、transform プロパティを設定します。
静的アニメーションを設定する
正方形を作成し、90°回転してひし形にし、下の長方形を使用してひし形の下半分を覆い、屋根を形成します。長方形のtranslate属性値を(150px,-150px)に設定して、座標位置を決定します。ドアを形成し、position 属性を使用して水平線と垂直線を作成します。親コンポーネント (正方形) に従って指定された座標位置に移動し、スケール プロパティを設定して、親コンポーネントと子コンポーネントが一緒に成長して窓を形成します。サイズを設定し、最後に skewX プロパティを使用してコンポーネントを傾け、座標を設定する translation(200px,-710px) して煙突を取得します。
<!-- xxx.hml -->
<div class="container">
<div class="top"></div>
<div class="content"></div>
<div class="door"></div>
<!-- 窗户 -->
<div class="window">
<div class="horizontal"></div>
<div class="vertical"></div>
</div>
<div class="chimney"></div>
</div>
/* xxx.css */
.container {
width:100%;
height:100%;
background-color:#F1F3F5;
align-items: center;
flex-direction: column;
}
.top{
z-index: -1;
position: absolute;
width: 428px;
height: 428px;
background-color: #860303;
transform: rotate(45deg);
margin-top: 284px;
margin-left: 148px;
}
.content{
margin-top: 500px;
width: 600px;
height: 400px;
background-color: white;
border: 1px solid black;
}
.door{
width: 100px;
height: 135px;
background-color: #1033d9;
transform: translate(150px,-137px);
}
.window{
z-index: 1;
position: relative;
width: 100px;
height: 100px;
background-color: white;
border: 1px solid black;
transform: translate(-150px,-400px) scale(1.5);
}
/* 窗户的横轴 */
.horizontal{
position: absolute;
top: 50%;
width: 100px;
height: 5px;
background-color: black;
}
/* 窗户的纵轴 */
.vertical{
position: absolute;
left: 50%;
width: 5px;
height: 100px;
background-color: black;
}
.chimney{
z-index: -2;
width: 40px;
height: 100px;
border-radius: 15px;
background-color: #9a7404;
transform: translate(200px,-710px) skewX(-5deg);
}
パンアニメーションを設定する
ボールが落ちるアニメーションです。ボールの落下を実現するには、ボールの Y 軸座標を変更します。次の期間では、ボールのリバウンドを実現するために、Y 軸座標を減らします。リバウンドするまで、各リバウンドの高さを徐々に減少させます。高さは 0 です。ボールが落ちるアニメーションがシミュレートされています。
<!-- xxx.hml -->
<div class="container">
<div class="circle"></div>
<div class="flower"></div>
</div>
/* xxx.css */
.container {
width:100%;
height:100%;
background-color:#F1F3F5;
display: flex;
justify-content: center;
}
.circle{
width: 100px;
height: 100px;
border-radius: 50px;
background-color: red;
/* forwards停在动画的最后一帧 */
animation: down 3s fast-out-linear-in forwards;
}
.flower{
position: fixed;
width: 80%;
margin-left: 10%;
height: 5px;
background-color: black;
top: 1000px;
}
@keyframes down {
0%{
transform: translate(0px,0px);
}
/* 下落 */
15%{
transform: translate(10px,900px);
}
/* 开始回弹 */
25%{
transform: translate(20px,500px);
}
/* 下落 */
35%{
transform: translate(30px,900px);
}
/* 回弹 */
45%{
transform: translate(40px,700px);
}
55%{
transform: translate(50px,900px);
}
65%{
transform: translate(60px,800px);
}
80%{
transform: translate(70px,900px);
}
90%{
transform: translate(80px,850px);
}
/* 停止 */
100%{
transform: translate(90px,900px);
}
}
回転アニメーションを設定する
異なる原点位置 (transform-origin) を設定すると、要素の周りの回転中心が変更されます。rotate3d 属性の最初の 3 つのパラメーターはそれぞれ X 軸、Y 軸、Z 軸の回転ベクトルで、4 番目の値は回転角度です。回転角度は負の値にすることができ、負の値は次のことを意味します。回転方向は反時計回りです。
<!-- xxx.hml -->
<div class="container">
<div class="rotate">
<div class="rect rect1"></div>
<div class="rect rect2"></div>
<div class="rect rect3"></div>
</div>
<!-- 3d属性 -->
<div class="rotate3d">
<div class="content">
<div class="rect4"></div>
<div class="rect5"> </div>
</div>
<div class="mouse"></div>
</div>
</div>
/* xxx.css */
.container {
flex-direction: column;
background-color:#F1F3F5;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.rect {
width: 100px;
height: 100px;
animation: rotate 3s infinite;
margin-left: 30px;
}
.rect1 {
background-color: #f76160;
}
.rect2 {
background-color: #60f76f;
/* 改变原点位置*/
transform-origin: 10% 10px;
}
.rect3 {
background-color: #6081f7;
/* 改变原点位置*/
transform-origin: right bottom;
}
@keyframes rotate {
from {
transform: rotate(0deg)
}
to {
transform: rotate(360deg);
}
}
/* 3d示例样式 */
.rotate3d {
margin-top: 150px;
flex-direction: column;
background-color:#F1F3F5;
display: flex;
align-items: center;
width: 80%;
height: 600px;
border-radius: 300px;
border: 1px solid #ec0808;
}
.content {
padding-top: 150px;
display: flex;
align-items: center;
justify-content: center;
}
/* react4 react5 翻转形成眼睛 */
.rect4 {
width: 100px;
height: 100px;
animation: rotate3d1 1000ms infinite;
background-color: darkmagenta;
}
.rect5 {
width: 100px;
height: 100px;
animation: rotate3d1 1000ms infinite;
margin-left: 100px;
background-color: darkmagenta;
}
.mouse {
margin-top: 150px;
width: 200px;
height: 100px;
border-radius: 50px;
border: 1px solid #e70303;
animation: rotate3d2 1000ms infinite;
}
/* 眼睛的动效 */
@keyframes rotate3d1 {
0% {
transform:rotate3d(0,0,0,0deg)
}
50% {
transform:rotate3d(20,20,20,360deg);
}
100% {
transform:rotate3d(0,0,0,0deg);
}
}
/* 嘴的动效 */
@keyframes rotate3d2 {
0% {
transform:rotate3d(0,0,0,0deg)
}
33% {
transform:rotate3d(0,0,10,30deg);
}
66% {
transform:rotate3d(0,0,10,-30deg);
}
100% {
transform:rotate3d(0,0,0,0deg);
}
}
説明する
transform-origin はオブジェクトの原点位置を変換します。値が 1 つだけ設定されている場合、もう 1 つの値は 50% です。値が 2 つ設定されている場合、最初の値は X 軸の位置を表し、2 番目の値は X 軸の位置を表しますY軸の位置。
ズームアニメーションを設定する
波紋アニメーションを実現するにはスケール スタイル属性を設定し、最初に位置決めを使用して要素の位置を決定します。次に、座標を決定した後に複数のコンポーネントを作成して重なり合う効果を実現します。次に、不透明度属性を設定してコンポーネントの不透明度を変更します。コンポーネントの非表示と表示を実現し、コンポーネントを並べて拡大できるようにスケール値を設定します。 片側を非表示にし、最後に 2 つのコンポーネントに異なるアニメーション実行時間を設定して、拡散効果を実現します。
sacle3dにX軸、Y軸、Z軸のズームパラメータを設定してアニメーションを実現します。
<!-- xxx.hml -->
<div class="container">
<div class="circle">
<text>ripple</text>
</div>
<div class="ripple"></div>
<div class="ripple ripple2"></div>
<!-- 3d -->
<div class="content">
<text>spring</text>
</div>
</div>
/* xxx.css */
.container {
flex-direction: column;
background-color:#F1F3F5;
width: 100%;
position: relative;
}
.circle{
margin-top: 400px;
margin-left: 40%;
width: 100px;
height: 100px;
border-radius: 50px;
background-color: mediumpurple;
z-index: 1; position: absolute;
}
.ripple{
margin-top: 400px;
margin-left: 40%;
position: absolute; z-index: 0;
width: 100px;
height: 100px;
border-radius: 50px;
background-color: blueviolet;
animation: ripple 5s infinite;
}
/* 设置不同的动画时间 */
.ripple2{
animation-duration: 2.5s;
}
@keyframes ripple{
0%{
transform: scale(1);
opacity: 0.5;
}
50%{
transform: scale(3);
opacity: 0;
}
100%{
transform: scale(1);
opacity: 0.5;
}
}
text{
color: white;
text-align: center;
height: 100%;
width: 100%;
}
.content {
margin-top: 700px;
margin-left: 33%;
width: 200px;
height: 100px;
animation:rubberBand 1s infinite;
background-color: darkmagenta;
position: absolute;
}
@keyframes rubberBand {
0% {
transform: scale3d(1, 1, 1);
}
30% {
transform: scale3d(1.25, 0.75, 1.1);
}
40% {
transform: scale3d(0.75, 1.25, 1.2);
}
50% {
transform: scale3d(1.15, 0.85, 1.3);
}
65% {
transform: scale3d(.95, 1.05, 1.2);
}
75% {
transform: scale3d(1.05, .95, 1.1);
}
100%{
transform: scale3d(1, 1, 1);
}
}
説明する
変換属性値を設定すると、親要素とともに子要素も変更されますが、親要素の他の属性値(高さ、幅など)のみを変更した場合、子要素は変更されません。
マトリックスのプロパティを設定する
行列は 6 つの入力パラメータを持つ行列で、6 つの値は、scaleX、skewY、skewX、scaleY、translateX、translateY を表します。次の例では、コンポーネントを移動して傾けるために、行列プロパティを行列(1,0,0,1,0,200)に設定します。
<!-- xxx.hml -->
<div class="container">
<div class="rect"> </div>
</div>
/* xxx.css */
.container{
background-color:#F1F3F5;
display: flex;
justify-content: center;
width: 100%;
height: 100%;
}
.rect{
width: 100px;
height: 100px;
background-color: red;
animation: down 3s infinite forwards;
}
@keyframes down{
0%{
transform: matrix(1,0,0,1,0,0);
}
10%{
transform: matrix(1,0,0,1,0,200);
}
60%{
transform: matrix(2,1.5,1.5,2,0,700);
}
100%{
transform: matrix(1,0,0,1,0,0);
}
}
変換属性を統合する
変換には複数の値を設定することができ、複数の値を同時に設定することもできます。次のケースは、scale、translate、rotate 属性を同時に設定した場合のアニメーション効果を示しています。
<!-- xxx.hml -->
<div class="container">
<div class="rect1"></div>
<div class="rect2"></div>
<div class="rect3"></div>
<div class="rect4"></div>
<div class="rect5"></div>
</div>
/* xxx.css */
.container{
width: 100%;
height: 100%;
flex-direction:column;
background-color:#F1F3F5;
padding:50px;
}
.rect1{
width: 100px;
height: 100px;
background-color: red;
animation: change1 3s infinite forwards;
}
.rect2{
margin-top: 50px;
width: 100px;
height: 100px;
background-color: darkblue;
animation: change2 3s infinite forwards;
}
.rect3{
margin-top: 50px;
width: 100px;
height: 100px;
background-color: darkblue;
animation: change3 3s infinite;
}
.rect4{
align-self: center;
margin-left: 50px;
margin-top: 200px;
width: 100px;
height: 100px;
background-color: darkmagenta;
animation: change4 3s infinite;
}
.rect5{
margin-top: 300px;
width: 100px;
height: 100px;
background-color: cadetblue;
animation: change5 3s infinite;
}
/* change1 change2 对比 */
@keyframes change1{
0%{
transform: translate(0,0); transform: rotate(0deg)
}
100%{
transform: translate(0,500px);
transform: rotate(360deg)
}
}
/* change2 change3 对比属性顺序不同的动画效果 */
@keyframes change2{
0%{
transform:translate(0,0) rotate(0deg) ;
}
100%{
transform: translate(300px,0) rotate(360deg);
}
}
@keyframes change3{
0%{
transform:rotate(0deg) translate(0,0);
}
100%{
transform:rotate(360deg) translate(300px,0);
}
}
/* 属性值不对应的情况 */
@keyframes change4{
0%{
transform: scale(0.5);
}
100%{
transform:scale(2) rotate(45deg);
}
}
/* 多属性的写法 */
@keyframes change5{
0%{
transform:scale(0) translate(0,0) rotate(0);
}
100%{
transform: scale(1.5) rotate(360deg) translate(200px,0);
}
}
説明する
● 複数のトランスフォームが設定されている場合、後続のトランスフォーム値は前のトランスフォーム値を上書きします。複数のアニメーション スタイルを同時に使用したい場合は、複合記述を使用できます。例:transform:scale(1)rotate(0)translate(0,0)。
● トランスフォームを複合書き込みに使用する場合、トランスフォーム スタイル内の複数のスタイル値の順序が異なると、異なるアニメーション効果が表示されます。
●transform属性で設定したスタイル値は1対1に対応している必要があり、表と裏が一致していないとアニメーションが有効になりません。複数のスタイル値が設定されている場合、対応する値のアニメーション効果のみが表示されます。