From f463ec013c4fe981e4a8c59d6de6fcbcc57ac360 Mon Sep 17 00:00:00 2001 From: Yoli <799480165@qq.com> Date: Wed, 10 Jan 2024 14:42:22 +0800 Subject: [PATCH] chore: add zh-CN document (#20) --- README.md | 2 +- docs/index.md | 25 ++ docs/index.zh-CN.md | 739 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 765 insertions(+), 1 deletion(-) create mode 100644 docs/index.zh-CN.md diff --git a/README.md b/README.md index 1a2dd1f..2b50816 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ A lib for generating Style Sheets with C#. -For documentation see our [docs](./docs/index.md). +[English](./docs/index.md) | [简体中文](./docs/index.zh-CN.md) ![Latest Version](https://img.shields.io/github/actions/workflow/status/ant-design-blazor/CssInCsharp/package.yml?style=flat-square) [![CssInCSharp](https://img.shields.io/nuget/v/CssInCSharp.svg?color=red&style=flat-square)](https://www.nuget.org/packages/CssInCsharp) diff --git a/docs/index.md b/docs/index.md index c0c8146..39d1c1e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,3 +1,27 @@ +# Table of Contents +- [Table of Contents](#table-of-contents) +- [Getting Started](#getting-started) + - [Install Package](#install-package) + - [Add Using](#add-using) + - [Create CSS Object](#create-css-object) +- [Usage](#usage) + - [Structured Stylesheet](#structured-stylesheet) + - [Parent Selectors](#parent-selectors) + - [Merge](#merge) + - [Reuse global styles](#reuse-global-styles) + - [Using merge operator](#using-merge-operator) + - [Overwrite existing styles](#overwrite-existing-styles) + - [Variables](#variables) + - [Retain CSS](#retain-css) + - [Functions](#functions) + - [Animation](#animation) + - [Colors](#colors) + - [Style Rendering](#style-rendering) + - [CSS Isolation](#css-isolation) + - [Custom Component Style](#custom-component-style) + +# Getting Started + ## Install Package ```sh dotnet add package CssInCSharp @@ -100,6 +124,7 @@ var css = new CSSObject } ``` +# Usage ## Structured Stylesheet The stylesheet is structured, this is similar to less or sass. diff --git a/docs/index.zh-CN.md b/docs/index.zh-CN.md new file mode 100644 index 0000000..5074bce --- /dev/null +++ b/docs/index.zh-CN.md @@ -0,0 +1,739 @@ +# 目录表 +- [目录表](#目录表) +- [开始](#开始) + - [安装包](#安装包) + - [添加引用](#添加引用) + - [创建CSSObject](#创建cssobject) +- [用法简介](#用法简介) + - [结构化样式表](#结构化样式表) + - [父选择](#父选择) + - [样式合并](#样式合并) + - [复用全局样式](#复用全局样式) + - [使用操作符合并样式](#使用操作符合并样式) + - [覆写已有样式](#覆写已有样式) + - [变量](#变量) + - [保留样式](#保留样式) + - [方法](#方法) + - [动画](#动画) + - [颜色](#颜色) + - [样式渲染](#样式渲染) + - [StyleOutlet组件](#styleoutlet组件) + - [StyleContent组件](#stylecontent组件) + - [Style组件](#style组件) + - [样式隔离](#样式隔离) + - [自定义组件样式](#自定义组件样式) + +# 开始 + +## 安装包 +```sh +dotnet add package CssInCSharp +``` + +## 添加引用 + +在blazor项目中,添加以下代码到_Imports.razor文件中。 + +```CSharp +@using CssInCSharp +``` + +## 创建CSSObject +```CSharp +// 创建一个CSSObject对象 +var css = new CSSObject +{ + [".demo"] = new CSSObject + { + Width = 300, + Height = 300, + Border = "1px solid #DDD", + ["& .title"] = new CSSObject + { + LineHeight = 20, + Color = "red" + }, + ["& .button"] = new CSSObject + { + Width = "100%", + Height = "20px", + TextAlign = "center", + ["&:hover"] = new CSSObject + { + Color = "blue" + } + } + } +}; + +// 使用ToString方法来序列化样式表 +var style = css.ToString(); +// 或者使用SerializeCss方法序列化样式表。 +var style = css.SerializeCss("hashId"); +``` + +CSSObject类型支持字符串类型的索引器,你可以利用该索引器向样式对象中添加样式名称,样式属性,选择器和变量等。 + +```csharp +var css = new CSSObject +{ + // 索引器支持样式名称 + [".btn-default"] = new CSSObject + { + // 索引器支持选择器 + ["&:hober"] = ..., + ["> span"] = ..., + ["button"] = ..., + + // 索引器支持变量 + ["--btn-display"] = "block", + + // 索引器支持样式属性,但是推荐使用强类型属性字段 + ["color"] = "red", + }, +} +``` +CSSObject为每个样式属性定义了属性类型,该类型支持多种值。 + +```csharp +var css = new CSSObject +{ + [".btn-default"] = new CSSObject + { + // Width属性既支持数字类型,同时也支持字符串类型。 + Width = 200, + Width = "200px", + Width = "100%", + Width = "var(--btn-width)", + }, +} +``` + +数字类型的属性在序列化时会自动添加`px`后缀。CSSObject内部有一个数据集用来判断该属性是否支持px。 + +使用数字类型的属性,可以对属性进行数值运算,而不用进行类型转换。 + +```csharp +var token = 10; +var css = new CSSObject +{ + [".btn-default"] = new CSSObject + { + // 例如:可以在属性赋值时进行四则运算等。 + Width = 200 + token, + Width = 200 - token, + Width = 200 * token, + Width = 200 / token, + }, +} +``` + +# 用法简介 +## 结构化样式表 + +和less或sass类似,CSSObject也是结构化的样式表。可以使用对象嵌套的方式来表示样式的层级关系。 + + +HTML +```html +
+
+
+
+
+``` +Standard CSS +```css +.div1 { ... } +.div1 .div2 { ... } +.div1 .div2 .div3 { ... } +``` +CssInCSharp +```csharp +var css = new CSSObject +{ + [".div1"] = new CSSObject + { + [".div2"] = new CSSObject + { + [".div3"] = new CSSObject + { + } + } + } +} +``` + +## 父选择 + +和less一样,CSSObject也是使用 `&` 来表示对父级选择器的引用。 + +```csharp +var css = new CSSObject +{ + ["a"] = new CSSObject + { + Color = "blue", + ["&:hover"] = new CSSObject + { + Color = "green" + } + } +}; +``` + +output: + +```css +a { + color: blue; +} + +a:hover { + color: green; +} +``` + +`&` 操作符用途有很多,基本上只要是默认规则以外的其他方式组合嵌套的选择器都可以使用。例如:你可以使用 `&` 来生成重复的样式名称。 + + +```csharp +var css = new CSSObject +{ + [".button"] = new CSSObject + { + ["&-ok"] = new CSSObject + { + BackgroundImage = "url(\"ok.png\")" + }, + ["&-cancel"] = new CSSObject + { + BackgroundImage = "url(\"cancel.png\")" + }, + ["&-custom"] = new CSSObject + { + BackgroundImage = "url(\"custom.png\")" + } + } +}; +``` + +output: + +```css +.button-ok { + background-image: url("ok.png"); +} +.button-cancel { + background-image: url("cancel.png"); +} +.button-custom { + background-image: url("custom.png"); +} +``` + +## 样式合并 + +在某些使用场景里,你可以使用Merge方式来继承或合并多个样式对象。 + +### 复用全局样式 +```CSharp +// 这是一个全局共用样式对象 +var globalCss = new CSSObject +{ + Background = "#EFEFEF", + FontSize = "14px", + Border = "1px solid #DDD", + MarginBottom = "20px" +}; + +// 使用Merge方法可以将该全局样式合并到当前样式中,合并时会覆盖已经存在的同名属性。 +var css = new CSSObject +{ + [".div1"] = new CSSObject + { + Width = "100px", + Height = "100px", + Color = "red" + }.Merge(globalCss), + [".div2"] = new CSSObject + { + Width = "120px", + Height = "120px", + Color = "blue" + }.Merge(globalCss), + [".div3"] = new CSSObject + { + Width = "120px", + Height = "120px", + Color = "blue", + ["& .title"] = new CSSObject + { + Color = "cadetblue", + FontSize = "20px" + } + }.Merge(globalCss) +}; +``` + +### 使用操作符合并样式 +CSSObject对象中提供了一个合并操作符`["..."]`,使用该操作符何以在构造期间进行指定位置的样式合并。 + +```CSharp +var globalCss = new CSSObject +{ + Background = "#EFEFEF", + FontSize = "14px", + Border = "1px solid #DDD", + MarginBottom = "20px" +}; + +var colorCss = new CSSObject +{ + Color = "green" +} + +var css = new CSSObject +{ + [".div1"] = new CSSObject + { + // 使用 ["..."] 来合并全局样式, 写法类似TS中的 ...globalCss + ["..."] = globalCss, + Width = "100px", + Height = "100px", + Color = "red", + ["..."] = colorCss, // 合并操作符何以多次使用。 + } +}; +``` + +**注意** : Merge方法,只能用在对象构造之后。`["..."]`操作符可以用在对象构造期间。 + + +### 覆写已有样式 +Merge方法可以覆盖对象中已有的样式。例如:覆盖上述样式对象中div3的title的颜色值。 + +```CSharp +css.Merge(new CSSObject +{ + [".div3"] = new CSSObject + { + ["& .title"] = new CSSObject + { + Color = "yellow" + } + } +}); +``` + +## 变量 + +CssInCsharp设计的目的就是为了能够利用C#语言的一切特性来生成样式。所以你可以在创建样式过程中使用C#定义的任何变量,包括但不限于全局变量,成员变量或局部变量。 + + +```CSharp +private string _style = ""; +private string _color = "red"; // 成员变量 +[Parameter] +public int Size { get; set; } = 200; // 组件属性 + +protected override void OnInitialized() +{ + var fontSize = "16px"; // 局部变量 + var css = new CSSObject + { + [".div1"] = new CSSObject + { + Border = "1px solid #DDD", + Width = $"{Size}px", + Height = $"{Size}px", + Color = _color, + FontSize = fontSize, + ["& .title"] = new CSSObject + { + Color = _color, + FontSize = fontSize + } + } + }; + + _style = css.ToString(); +} +``` +**变量值只在序列化时生效,一旦序列化完成后,样式就不再受变量值影响。除非重新序列化样式。** + +### 保留样式 + +```CSharp +private CSSObject _css = new (); +private string _color = "red"; +[Parameter] +public int Size { get; set; } = 200; // 组件属性 + +protected override void OnInitialized() +{ + var fontSize = "16px"; // 局部变量 + _css = new CSSObject + { + [".div2"] = new CSSObject + { + Border = "1px solid #DDD", + Width = $"{Size}px", + Height = $"{Size}px", + MarginTop = "10px", + ["& .title"] = new CSSObject + { + Color = _color, + FontSize = fontSize + } + } + }; +} +``` + +如果你需要在样式对象构造完成后并更新它,那么你需要将它定义成成员变量或全局变量。但这么做并不推荐。 + + +以下是演示如何修改上述定义的CSSObject对象。 + +```CSharp +private void ClickToChangeCssObject() +{ + // 1.使用Merge方法来修改其内容 + _css.Merge(new CSSObject + { + [".div2"] = new () + { + ["& .title"] = new CSSObject + { + Color = "green" + } + } + }); + + // 2.直接设置对象属性的值 + _css[".div2"]["& .title"].Color = "green"; + + // 重新序列化样式 + _style = _css.ToString(); +} +``` +**注意: 尽可能不要在样式已经初始化结束再修改样式内容。** + +## 方法 + +由于CssInCsharp是完全基于C#语言的,因此也可以在创建样式时调用C#定义的方法。 + +```CSharp +private int _size = 500; +private string _style = ""; + +protected override async Task OnInitializedAsync() +{ + var css = new CSSObject + { + [".div"] = new CSSObject + { + Width = $"{_size}px", + Border = "1px solid #DDD", + ["& .header"] = new CSSObject + { + Height = "50px", + Width = "100%", + }, + ["& .footer"] = new CSSObject + { + Height = "50px", + Width = "100%", + }, + ["& .body"] = new CSSObject + { + // 直接调用普通的方法 + Height = $"{CalcBodyHeight(50, 50)}px", + Width = "100%", + BorderTop = "1px solid #DDD", + BorderBottom = "1px solid #DDD", + [".container"] = new CSSObject + { + // 也可以调用async方法 + Height = await GetContainerSizeAsync(), + BackgroundColor = "#EFEFEF", + } + } + } + }; + _style = css.ToString(); +} + +private int CalcBodyHeight(int header, int footer) +{ + return _size - header - footer; +} + +private async Task GetContainerSizeAsync() +{ + return await Task.FromResult("200px"); +} +``` + +## 动画 + +CSSObject类型的AnimationName属性支持`Keyframe`类型的值。使用该类型可以创建动画效果。 + +这是一个渐变效果的动画,在3s内将div宽度从0px变到100px,透明度从1变为0.2 + +```csharp +
+ Transform +
+
+ + + +@code { + private string _transform = ""; + + protected override void OnInitialized() + { + _transform = new CSSObject + { + [".transform"] = new CSSObject + { + Width = 120, + Height = 120, + ["& .title"] = new CSSObject + { + Height = 20, + LineHeight = 20, + FontSize = 14 + }, + ["& .animation"] = new CSSObject + { + Width = 100, + Height = 100, + BackgroundColor = "rgba(0, 0, 255, 0.5)", + AnimationDuration = "3s", + AnimationName = new Keyframe("animation-transform") + { + ["from"] = new() + { + Transform = "translateX(0px)", + Opacity = 1 + }, + ["to"] = new() + { + Transform = "translateX(100px)", + Opacity = 0.2 + } + } + } + } + }.ToString(); + } +} +``` + +## 颜色 +CssInCSharp提供了用于颜色处理和转换的TinyColor类型。该类型可以用来对不同颜色值进行转换处理。例如RGB和16进制互转等。同时也支持css颜色转rgb或16进制。 + +* 字符串rgb转16进制 +```csharp +new TinyColor("rgb 255 0 0").ToHexString(); // 输出: #ff0000 +``` +* 16进制字符串转rgb +```csharp +new TinyColor("#fff").ToRgbString(); // 输出: rgb(255, 255, 255) +``` +* css颜色值转16进制 +```csharp +new TinyColor("red").ToHexString(); // 输出: #ff0000 +``` +* RGB对象转16进制 +```csharp +new TinyColor(new RGB(255, 0, 0)).ToHexString(); // 输出: #ff0000 +``` +* 单独设置Alpha通道值 +```csharp +new TinyColor("rgba(255, 0, 0, 1)").SetAlpha(0.9); +``` + +## 样式渲染 + +CssInCSharp提供一组用于样式渲染输出的组件。包括 `` , `` 和 ` + + + +@code{ + +} +``` + +StyleContent里可以放原生的style标签也可以放CssInCsharp提供的Style组件。 + +**NOTE:** 由于每个页面只能有一个StyleContent组件,因此StyleContent只能放在页面里,不能用在组件中。(因为组件可能会被实例化多次,例如Button组件,在同一个页面上也可能存在多个实例) + +### Style组件 +` + + +@code +{ + private string _tokenHash = "css-zcfrx9"; + + private CSSInterpolation GenStyle() + { + return new CSSObject + { + [".div1"] = new CSSObject + { + Width = "200px", + Height = "200px", + Border = "1px solid #DDD", + } + }; + } +} +``` + +**NOTE:** +`Path` 属性为样式提供了唯一性保证,相同的Path只会创建一个style标签。因此在为组件设计样式时,一定要设置Path属性,这样无论该组件被实例化多少次,它的样式表有且只有一份。 + +在使用` + + +@code{ + private string _tokenHash = "css-zcfrx9"; + + private CSSInterpolation GenStyle() + { + return new CSSObject + { + [".div1"] = new CSSObject + { + Width = "200px", + Height = "200px", + Border = "1px solid #DDD", + } + }; + } +} +``` +输出的样式: +```css + +``` + +## 自定义组件样式 +在页面上,你可以使用``组件来添加页面样式。但是StyleContent并不能用在自定义的组件里。例如创建一个``组件,该如何为这个自定义组件添加样式。CssInCsharp提供一个全局的Helper类`StyleHelper`。你可以使用`UseStyleRegister`方法来向head标签里注入样式。 + +DemoComponent.razor演示代码: +```csharp +
+@_styleContent + +@code +{ + private RenderFragment _styleContent; + private string _tokenHash = "css-zcfrx9"; + + protected override void OnInitialized() + { + _styleContent = StyleHelper.UseStyleRegister(new StyleInfo + { + HashId = _tokenHash, + Path = new[] { "component", "demo" }, + StyleFn = GenStyle + }); + } + + private CSSInterpolation GenStyle() + { + return new CSSObject + { + [".demo"] = new CSSObject + { + Width = "200px", + Height = "200px", + Border = "1px solid #DDD", + } + }; + } +} +``` +`UseStyleRegister`方法调用后会返回RenderFragment对象。你需要将该对象放到组件里。 \ No newline at end of file