visual formatting model details简译 <二> 之 box的宽度

本文详细解析CSS中各类元素盒子模型的宽度计算方法,包括inline、block、replaced及绝对定位元素等,并介绍了shrink-to-fit算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. width属性

width属性定义了box的content区域的宽度。

width的属性值可以是具体数值,可以是百分数,也可是”auto”。如果结点是non-replacedinline类型,或者是table row类型,或者是rowgroup类型,那么即使设置了结点的width属性,该属性也不会影响作为结点box的宽度。对于除了上述三种类型之外的结点来说,width属性都会影响结点box的宽度。

如果width属性值为”auto”,那么在布局时会根据某些规则计算width属性值。如果width属性值为百分数,那么在布局时会将containing box的宽作为基数。假设containing box的宽为widthCB,结点的属性值是widthVal%,那么结点宽为widthCB* widthVal / 100。如果width属性值就是具体数值,那么不需要对width属性值做改变,该值就被作为content区域的宽度。

width属性的值必须是非负值。

2. 宽度以及margin的计算方法

一个结点的width属性、margin-left属性、margin-right属性、left属性、right属性会影响结点box的位置以及二维大小。另外,这些属性也相互影响着。

为了区分网页设计者设置的属性值与浏览器布局时使用的值,将浏览器布局时使用的值命名为“used value”, 将网页设计者设置的属性值命名为value。一般情况下,used value与value是相同或等价的。如果value是数值10 px,那么used value就是10 px。如果value是15%,那么used value就是base * 15%。但是在特殊情况、特殊场景下,used value与value不等价也不相同。

在介绍各个结点的宽度计算方法之前,先给出一个重要的约束。

'left'+ 'margin-left' + 'border-left-width' + 'padding-left' + 'width' +'padding-right' + 'border-right-width' + 'margin-right' + 'right' = width of containing box -----------(式1)

2.1 inline, non-replaced 结点

width的value不影响width的used value,width的used value完全取决于containing box的宽度。如果margin-left, margin-right的value为”auto”,那么margin-left,margin-right的usedvalue为0。

2.2 inline, replaced 结点

如果margin-left, margin-right的value为“auto”,那么margin-left,margin-right的used value为0。

如果height, width的value都为”auto”,结点具有内在的宽度,那么内在的宽度就是width的used value。

如果width的value为”auto”, height可以得到有效值,结点具有内在的宽高比radio,那么width的used value为”height * radio”。这里需要说明一下,height可能是由height属性定义的,也有可能是结点的内在高度。

如果width,height的value都为”auto”,结点也没有内在宽、内在高,那么width的used value是不确定的。在containing box的宽度不依赖与此结点宽度的情况下,css2.1标准建议利用(式1)计算结点width属性的used value。在Containing box的宽度依赖于此结点宽度的情况下,css2.1标准建议将结点box的宽设置为300px。如果宽度300px太宽了,不能在设备上显示,那么将结点box设置为“宽高比为2:1,能够在设备上显示的、最大的矩形”。

2.3 block-level, non-replaced in-flow结点

left,margin-left,border-left-width, padding-left, width, padding-right, border-right-width, margin-right, right的used value必须满足(式1)的约束。
假设width的value不是“auto”,上述属性的value之和大于containing box的宽度。如果margin-left的value为”auto”,那么margin-left的used value将是0。如果margin-right的value为”auto”,那么margin-right的used value将是0。
上一段的假设仍然成立,且margin-left的value、margin-right的value都是”auto”。但是将margin-left与margin-right设为0值后,发现value之和小于containing box的宽度怎么办?答案是:将多出的空间平均分配给margin-left, margin-right。
如果上述属性的value都不是”auto”, value之和大于containing box的宽,那么某些属性的used value将与value不等价也不相同。如果containing box的direction属性为”ltr”,那么margin-right会被作为0以满足(式1)的约束。如果containing box的direction属性为”rtl”,那么margin-left会被作为0以满足(式1)的约束。

2.4 block-level, replaced in-flow结点

计算宽度的方法与使用inline, replaced结点相同,同时必须满足(式1)的约束。

2.5 floating, non-replaced结点

如果margin-left, margin-right的value是”auto”,那么margin-left, margin-right的used value是0。
如果width的value是”auto”,那么按照“shrink-to-fit”算法计算width的used value。”shrink-to-fit”算法的简单描述如下。
1)除非碰到了<br />结点或其他必须换行的结点之外,尽量将所有inline box置于一行。记录此时box的宽度为preferred-width。
2) 除非碰到了<nowrap>结点之外,尽量将inline 结点放在不同的行。记录此时box的宽度为preferred-minimum-width。
3)算出box的可用宽度,即containing box的宽度减去margin-left, border-left-width, padding-left, padding-right, border-right-width, margin-right, scroll-bar width得到的值。计算这个宽度为available-width。
4)min(max(available-width, preferred-minimum-width), preferred-width)就是width的used value。
【注】表格也是采用”shrink-to-fit”算法布局的。

2.6 floating, replaced结点

如果margin-left, margin-right的value是”auto”,那么margin-left, margin-right的used value是0。
计算宽度的方法与使用inline, replaced结点相同。

2.7 absolutely, non-replaced结点

在介绍absolute box宽度的计算方法之前必须明确几个关键词。

1)static position。

假设结点不具有absolute属性,那么box的位置很可能不同于box的实际位置。将在假设条件下,box所在的位置称为static position。假设html脚本如下。
<html>
<head><title>test</title>
<style>
#abObj{ 
left:100px; top:100px; width:300px; height:150px; background-color:yellow; 
position: absolute;
}
#noObj{
left:100px; top:100px; width:300px; height:150px; background-color:green;
}
</style></head>
<body><div id=”abObj”></div><div id=”noObj”></div></body>
</html>

效果图如下。

从代码可以看到,黄色box只比绿色box多了一个absolute属性。因此,绿色矩形框所在区域就是absolute box的static position。注意,static position只是一个概念,不是说absolute box对应着一个static box。
2)static-position 的containing box。
假设结点不具有absolute属性时,结点box的contaning box就是static-position的containing box。还以图1为例,图1中static-position的containing box是body,而absolute box的containing box却是initial containing box。
absolute box的各个属性值也必须满足(式1)的约束。

根据left, right, width的value是否为”auto”,可以将计算used value的方法分为8种。下面分别介绍。
  1. left, width, right的value都是”auto”。 如果margin-left, margin-right的value是”auto”,那么margin-left, margin-right的used value直接设置为0。如果static-position的containing box的direction属性值是”ltr”,那么left被设置为0,然后应用方法5)计算used value。如果static-position的containing box的direction属性值是”rt1”,那么right被设置为0,然后应用方法3)计算used value。
  2. left, width, right的value都不是”auto”。如果margin-left, margin-right的value是”auto”且left、width、right的value之和小于containing box的宽度,那么将额外的空间均分给margin-left,margin-right。如果margin-left, margin-right的value是”auto”且left、width、right的vlaue之和大于等于containing box的宽度,那么将margin-left, margin-right都设为0。
  3. left、width 的value是”auto”,right的value不是”auto”。使用shrink-to-fit算法计算width的used value,然后利用(式1)计算left的used value。
  4. left、right的value是”auto”,width的value不是”auto”。如果static-postion的containing box的direnction属性值是”ltr”,那么left设置为0,然后利用(式1)计算right的used value。如果static-position的containing box的direction属性值是”rtl”,那么right设置为0,然后利用(式1)计算left的used value。
  5. right、width的value是”auto”,left的value不是”auto”。按照shrink-to-fit算法计算width的used value,然后利用(式1)计算right的used value。
  6. left的value是”auto”,width、right的value不是”auto”。按照(式1)计算left的used value。
  7. width的value是”auto”,left、right的value不是”auto”。按照(式1)计算width的used value。
  8. right的value是”auto”,width、left的value不是”auto”。按照(式1)计算right的used value。

2.8 absolutely, replaced结点

  1. left, width, right的value都是”auto”。 如果margin-left, margin-right的value是”auto”,那么margin-left, margin-right的used value直接设置为0。如果static-position的containing box的direction属性值是”ltr”,那么left被设置为0,然后应用方法5)计算used value。如果static-position的containing box的direction属性值是”rt1”,那么right被设置为0,然后应用方法3)计算used value。
  2. left, width, right的value都不是”auto”。如果margin-left, margin-right的value是”auto”且left、width、right的value之和小于containing box的宽度,那么将额外的空间均分给margin-left,margin-right。如果margin-left, margin-right的value是”auto”且left、width、right的vlaue之和大于等于containing box的宽度,那么将margin-left, margin-right都设为0。
  3. width used value的计算方法与2.2节 inline replaced结点相同。
  4. left、right的value都是”auto”。如果static position containing box的direction属性值是”ltr”,那么设置left为0。如果static position containing box的direction属性值是”rtl”,那么设置right为0。
  5. left、right之一是”auto”。如果margin-left, margin-right的value 是”auto”,那么将其设置为0。
  6. 截止到这一步,如果还未计算出margin-left, margin-rigth的used value,那么让margin-left,margin-right评分额外的宽度。如果没有额外的宽度,那么设置used value为零。
  7. 截止到这一步,如果还未计算出left或right的used value,那么利用(式1)计算left或right的used value。
  8. 截止到这一步,如果发现不满足(式1),那么或者忽略left的值,或者忽略right的值。如果static position containing box的direction属性值是”rtl”,那么忽略left值。如果static position containing box的direction属性值是”ltr”,那么忽略right值。

2.9 inline-block, non-replaced结点

如果width的value是”auto”,那么按照shrink-to-fit算法计算width的used value。
如果margin-left, margin-right的value是”auto”,那么将它们的used value设置为0。

2.10 inline-block, replaced结点

与inline replaced结点的计算方法完全相同。

<think>好的,我现在要解决用户的问题:如何解析和使用Apache POI中的dxfs、dxf、font、fill元素,并将其应用于XSSFFontFormatting。首先,我需要明确用户提到的这些术语在Apache POI中的具体含义和上下文。 用户提到了XML中的dxfs和dxf,这应该与Excel的样式定义有关。根据之前的引用内容,dxf是Differential Formatting的缩写,用于指定部分格式而不是全部格式。用户还提到了font和fill元素,这些通常在Excel的样式中用于定义字体和填充样式。XSSFFontFormatting可能与条件格式中的字体设置相关。 首先,我需要确认Apache POI中如何处理这些元素。例如,dxfs可能对应StylesTable中的某个部分,而dxf是其中的一个条目。用户可能需要知道如何从现有的样式中提取这些元素,或者创建新的dxf条目应用到单元格样式中。 接下来,用户想将这些元素应用到XSSFFontFormatting中,这可能涉及条件格式的设置。例如,在条件格式规则中,可以通过XSSFFontFormatting来设置字体颜色、样式等,而这些设置可能来源于dxf定义的格式。 我需要检查Apache POI的文档或源代码,了解如何访问和操作dxfs和dxf。例如,StylesTable类可能有获取或添加dxf的方法。同时,XSSFFontFormatting可能需要从现有的dxf中获取字体和填充信息,或者将自定义的设置写入dxf。 可能的步骤包括: 1. 获取工作簿的StylesTable,其中包含dxfs集合。 2. 创建或修改一个dxf条目,设置其font和fill属性。 3. 将dxf应用到条件格式规则中的XSSFFontFormatting。 需要注意的是,根据用户提供的引用[1],直接复制样式可能导致边界问题,可能需要通过StylesTable中的方法来正确创建样式副本。引用[2]提到dxf使用差异格式记录,这可能意味着在应用时需要引用现有的dxf而不是创建全新的样式。 此外,用户可能需要代码示例来具体说明如何操作这些元素。例如,如何从StylesTable中获取dxf,如何创建新的dxf并设置字体和填充,然后将这些应用到XSSFFontFormatting对象中。 需要验证这些步骤是否正确,是否有常见的陷阱,例如样式未被正确应用,或者dxf索引未正确关联。可能需要参考Apache POI的官方文档或社区资源,确保方法的正确性。 最后,生成相关问题时要围绕dxfs、dxf、字体和填充的应用,可能涉及条件格式、样式复制、性能优化等方向。</think>### XML格式元素解析与应用指南 在Apache POI处理XSSF格式时,dxfs/dxf和font/fill元素的关系可通过以下结构理解: $$ \text{StylesTable} \rightarrow \text{dxfs集合} \rightarrow \text{dxf条目} \rightarrow [\text{font}+\text{fill}+\text{border}] $$ #### 一、核心元素解析 1. **dxfs元素** - 存储所有差异格式定义(Differential Formatting)的容器 - 通过`StylesTable.getDxfs()`获取列表[^2] - 索引对应条件格式规则中的dxfId引用 2. **dxf元素** - 表示轻量级格式模板 - 包含可选格式组件: ```xml <dxf> <font><color rgb="FFFF0000"/></font> <fill><patternFill patternType="solid"/></fill> </dxf> ``` 3. **XSSFFontFormatting** - 专门处理字体格式的API接口 - 通过`ConditionalFormattingRule.createFontFormatting()`创建 #### 、应用步骤示例 ```java // 1. 获取样式表 StylesTable styles = workbook.getStylesSource(); // 2. 创建新dxf条目 CTDxf dxf = CTDxf.Factory.newInstance(); CTFont dxfFont = dxf.addNewFont(); dxfFont.addNewColor().setRgb("FF00FF00"); // 设置字体颜色 // 3. 注册dxf到样式表 styles.addDxf(dxf); // 4. 创建条件格式规则 XSSFConditionalFormattingRule rule = sheet.createConditionalFormattingRule("$A1>100"); XSSFFontFormatting fmt = rule.createFontFormatting(); // 5. 绑定dxf到字体格式 fmt.setDxf(styles.getDxfAt(styles.getDxfsSize()-1)); // 获取最后添加的dxf ``` #### 三、关键注意事项 1. **样式继承机制** - 未显式定义的属性会继承单元格基础样式 - 使用`CTFont.setNil(true)`可重置继承属性 2. **性能优化** - 重用现有dxf索引可减少文件体积 - 批量操作建议使用`StylesTable.cloneStyle()`[^1] 3. **颜色编码转换** - RGB值需转换为AARRGGBB格式字符串 - 示例:白色表示为`"FFFFFFFF"`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值