CSS blazor 中的隔离不适用于预定义的表单元素
CSS isolation in blazor doesn't work with predefined Form elements
我有一个页面 foo.razor,代表一个表单:
<EditForm Model=SomeModel>
<InputText @bind-Value=SomeModel.Property1 />
<InputText @bind-Value=SomeModel.Property2 />
<p>a paragraph</p>
</EditForm>
在它旁边我有一个孤立的CSS,foo.razor。css,例如:
input{
display: block;
}
p{
color: lime;
}
段落的样式应用正确,但输入元素的样式应用不正确。我不明白为什么。
另外,我知道 blazor 会在编译后为元素生成随机 ID。在浏览器中,我可以看到该段落具有这样的 ID,但输入和表单元素同样没有。
我尝试为组件添加一个 class 名称并使用深度选择器,如下所示:
::deep .classname {
.......
}
但这也不行。
CSS 隔离的棘手之处在于它仅适用于普通 HTML 节点,不适用于组件。在幕后,定义隔离 CSS 的当前组件中的元素获得自定义(一种随机)属性,并且 CSS 规则级联通过该属性以限定范围到您的当前组件。框架不知道其他组件内部是什么,所以它不能向它们添加该属性——它们的渲染是它们自己的。因此,这些范围 CSS 规则不能针对组件。
如何解决这个问题 - 将您的组件包装在当前组件的 HTML 元素中,并将您的规则写入该容器内的目标元素,方法是将该元素替换为 ::deep
。
这是一个例子:
input,
::deep input{
display: block;
border: 2px solid red;
}
p,
::deep p {
color: lime;
border: 2px solid red;
}
下面是修改表格的方法
<EditForm Model=SomeModel>
<div> @* This div right here is the "magic" *@
<InputText @bind-Value=SomeModel.Property1 />
<InputText @bind-Value=SomeModel.Property2 />
<p>a paragraph</p>
</div>
</EditForm>
@code{
TestModel SomeModel { get; set; } = new TestModel();
public class TestModel
{
public string Property1 { get; set; }
public string Property2 { get; set; }
}
}
@rdmptn 的回答是正确的,但我还是要加两分钱。我花了很长时间才理解并开始 ::deep
工作,我将分享我的旅程。
假设我们想要覆盖子组件中 <p>
标签的颜色:
MyComponent.razor.css
::deep p { color: red !important; }
MyComponent.razor:
<span>My component!</span>
<OtherComponent/>
OtherComponent.razor:
<p>Other component!</p>
现在,为 MyComponent.razor 生成的 HTML 看起来像:
<span random1="">My component!</span>
<p random2="">Other component!</p>
每个 .razor 组件都有一个随机的、唯一的 component-id 分配给它的所有 plain HTML 标签,即 <div>
, <p>
、<span>
、<img>
等。请注意 MyComponent 中的 <span>
元素如何使用 random1 进行标记。同样,<p>
元素被标记为 random2,因为该元素是在 OtherComponent.
中定义的
但是从 MyComponent.razor.css 生成的 CSS 看起来像:
[random1] p { color: red !important; }
也就是说,::deep
CSS 选择器变成类似于“所有元素类型 <p>
元素下带有标签 random1
”。从上面生成的 HTML 可以明显看出,这与 OtherComponent 中的 <p>
不匹配。这就是将内容包装在 <div>
中的原因:
MyComponent.razor(更新)
<span>My Component!</span>
<div>
<OtherComponent/>
</div>
而新生成的HTML:
<span random1="">My Component!</span>
<div random1="">
<p random2="">Other component!</p>
</div>
现在 ::deep
CSS 选择器将匹配 OtherComponent 中的 <p>
标签.
我有一个页面 foo.razor,代表一个表单:
<EditForm Model=SomeModel>
<InputText @bind-Value=SomeModel.Property1 />
<InputText @bind-Value=SomeModel.Property2 />
<p>a paragraph</p>
</EditForm>
在它旁边我有一个孤立的CSS,foo.razor。css,例如:
input{
display: block;
}
p{
color: lime;
}
段落的样式应用正确,但输入元素的样式应用不正确。我不明白为什么。
另外,我知道 blazor 会在编译后为元素生成随机 ID。在浏览器中,我可以看到该段落具有这样的 ID,但输入和表单元素同样没有。
我尝试为组件添加一个 class 名称并使用深度选择器,如下所示:
::deep .classname {
.......
}
但这也不行。
CSS 隔离的棘手之处在于它仅适用于普通 HTML 节点,不适用于组件。在幕后,定义隔离 CSS 的当前组件中的元素获得自定义(一种随机)属性,并且 CSS 规则级联通过该属性以限定范围到您的当前组件。框架不知道其他组件内部是什么,所以它不能向它们添加该属性——它们的渲染是它们自己的。因此,这些范围 CSS 规则不能针对组件。
如何解决这个问题 - 将您的组件包装在当前组件的 HTML 元素中,并将您的规则写入该容器内的目标元素,方法是将该元素替换为 ::deep
。
这是一个例子:
input,
::deep input{
display: block;
border: 2px solid red;
}
p,
::deep p {
color: lime;
border: 2px solid red;
}
下面是修改表格的方法
<EditForm Model=SomeModel>
<div> @* This div right here is the "magic" *@
<InputText @bind-Value=SomeModel.Property1 />
<InputText @bind-Value=SomeModel.Property2 />
<p>a paragraph</p>
</div>
</EditForm>
@code{
TestModel SomeModel { get; set; } = new TestModel();
public class TestModel
{
public string Property1 { get; set; }
public string Property2 { get; set; }
}
}
@rdmptn 的回答是正确的,但我还是要加两分钱。我花了很长时间才理解并开始 ::deep
工作,我将分享我的旅程。
假设我们想要覆盖子组件中 <p>
标签的颜色:
MyComponent.razor.css
::deep p { color: red !important; }
MyComponent.razor:
<span>My component!</span>
<OtherComponent/>
OtherComponent.razor:
<p>Other component!</p>
现在,为 MyComponent.razor 生成的 HTML 看起来像:
<span random1="">My component!</span>
<p random2="">Other component!</p>
每个 .razor 组件都有一个随机的、唯一的 component-id 分配给它的所有 plain HTML 标签,即 <div>
, <p>
、<span>
、<img>
等。请注意 MyComponent 中的 <span>
元素如何使用 random1 进行标记。同样,<p>
元素被标记为 random2,因为该元素是在 OtherComponent.
但是从 MyComponent.razor.css 生成的 CSS 看起来像:
[random1] p { color: red !important; }
也就是说,::deep
CSS 选择器变成类似于“所有元素类型 <p>
元素下带有标签 random1
”。从上面生成的 HTML 可以明显看出,这与 OtherComponent 中的 <p>
不匹配。这就是将内容包装在 <div>
中的原因:
MyComponent.razor(更新)
<span>My Component!</span>
<div>
<OtherComponent/>
</div>
而新生成的HTML:
<span random1="">My Component!</span>
<div random1="">
<p random2="">Other component!</p>
</div>
现在 ::deep
CSS 选择器将匹配 OtherComponent 中的 <p>
标签.