金沙棋牌官方平台

当前位置:金沙棋牌 > 金沙棋牌官方平台 > 是你不懂我,重新认识Box

是你不懂我,重新认识Box

来源:http://www.logblo.com 作者:金沙棋牌 时间:2019-11-05 18:52

CSS魔法堂:”那不是bug,是你不懂我!” by inline-block

2016/05/10 · CSS · inline-block

本文作者: 伯乐在线 - ^-^肥仔John 。未经作者许可,禁止转载!
欢迎加入伯乐在线 专栏作者。

CSS魔法堂:重新认识Box Model、IFC、BFC和Collapsing margins

2016/05/10 · CSS · BFC, Box Model, Collapsing margins, IFC

本文作者: 伯乐在线 - ^-^肥仔John 。未经作者许可,禁止转载!
欢迎加入伯乐在线 专栏作者。

前言
盒子模型作为CSS基础中的基础,曾一度以为掌握了IE和W3C标准下的块级盒子模型即可,但近日在学习行级盒子模型时发现原来当初是如此幼稚可笑。本文尝试全面叙述块级、行级盒子模型的特性。作为近日学习的记录。

何为盒子模型?
盒子模型到底何方神圣居然可以作为CSS的基础?闻名不如见面,上图了喂!
图片 1
再来张切面图吧!
图片 2
下面我们以 <div></div> 为栗子。 <div></div> 标签被浏览器解析后会生成div元素并添加到document tree中,但CSS作用的对象并不是document tree,而是根据document tree生成的render tree,而盒子模型就是render tree的节点。
* 注意:
* 1. CSS作用的是盒子(Box), 而不是元素(Element);
* 2. JS无法直接操作盒子。

盒子模型的结构
由于块级盒子在验证效果时干扰信息更少,便于理解盒子模型,因此下面将以块级盒子模型来讲解。
注意: 行级盒子模型与块级盒子模型结构一致,只是行级盒子在此基础上有自身特性而已。
从上面两幅图说明盒子模型其实就是由以下4个盒子组成:

  1. content box:必备,由content area和4条content/inner edge组成;
  2. padding box:可选,由padding和4条padding edge组成。若padding宽度设置为0,则padding edge与content edage重叠;
  3. border box:可选,由border和4条border edge组成。若border宽度设置为0,则border edge与padding edage重叠;
  4. margin box:可选,由margin和4条margin/outer edge组成。若margin宽度设置为0,则margin edge与border edage重叠。
    对于刚接触CSS的同学,经常会将”通过width/height属性设置div元素的宽/高”挂在口边,其实这句话是有误的。
  5. 首先css属性width和height作用于div元素所产生的盒子,而不是元素本身;
  6. 另外盒子模型由4个盒子组成,那width和height到底是作用于哪些盒子呢?
    这里就分为IE盒子模型和标准盒子模型了。
       IE box model    
    IE5.5(怪异模式)采用IE盒子模型,其它将使用W3C标准盒子模型。
    图片 3

JavaScript

width = content-width + padding-width + border-width height = content-height + padding-height + border-height

1
2
width = content-width + padding-width + border-width
height = content-height + padding-height + border-height

  Standard box model  
图片 4

JavaScript

width = content-width height = content-height

1
2
width = content-width
height = content-height

游走于IE box model 和 Standard box model间的通道——box-sizing属性
我们看到存在两种width/height的划分方式,到底哪种才对呢?其实两种都对,具体看如何使用而已。另外IE8开始支持CSS3属性box-sizing,让我们可以自由选择采用哪种盒子:)
box-sizing:content-box/border-box/inherit
content-box——默认值,采用Standard box model
border-box——采用IE box model
inherit——继承父元素属性值
sample:

CSS

Element{ -moz-box-sizing: border-box; // FireFox3.5+ -o-box-sizing: border-box; // Opera9.6(Presto内核) -webkit-box-sizing: border-box; // Safari3.2+ -ms-box-sizing: border-box; // IE8 box-sizing: border-box; // IE9+,Chrome10.0+,Safari5.1+,Opera10.6 }

1
2
3
4
5
6
7
Element{
  -moz-box-sizing: border-box; // FireFox3.5+
  -o-box-sizing: border-box; // Opera9.6(Presto内核)
  -webkit-box-sizing: border-box; // Safari3.2+
  -ms-box-sizing: border-box; // IE8
  box-sizing: border-box; // IE9+,Chrome10.0+,Safari5.1+,Opera10.6
}

行级盒子——怀疑人生de起点:)                  
之前我理解的盒子模型如上所述,当我看到行级盒子的种种现象时,便开始怀疑人生了:(
width/height不起作用。。。

CSS

.defined-wh{ width: 100px; height: 50px; border: solid 1px red; background: yellow; }

1
2
3
4
5
6
7
.defined-wh{
  width: 100px;
  height: 50px;
 
  border: solid 1px red;
  background: yellow;
}

对于block-level box

XHTML

<div class="defined-wh"></div>

1
<div class="defined-wh"></div>

图片 5
对于inline-level box

XHTML

<span class="defined-wh"></span>

1
<span class="defined-wh"></span>

图片 6
行级盒子的宽度怎么会是0呢?高度是有的但不是50px啊,到底什么回事啊?
原因很简单,那就是行级盒子的content box的高/宽根本就不是通过height/width来设置的。
content box/area的高由font-size决定的;
content box/area的宽等于其子行级盒子的外宽度(margin+border+padding+content width)之和。

  行级盒子被挤断了。。。

CSS

.broken{ border: solid 1px red; background: yellow; }

1
2
3
4
.broken{
  border: solid 1px red;
  background: yellow;
}

对于block-level box

XHTML

<div class="broken">一段文字一段文字一段文字一段文字一段文字一段文字</div>

1
<div class="broken">一段文字一段文字一段文字一段文字一段文字一段文字</div>

图片 7
对于inline-level box

XHTML

<span class="broken">一段文字一段文字一段文字一段文字一段文字一段文字</span>

1
<span class="broken">一段文字一段文字一段文字一段文字一段文字一段文字</span>

图片 8
行级盒子被五马分尸了,可怜兮兮的。更可怜的是我理解不了。。。
其实W3C Recommendation有说明的哦!
>The box model for inline elements in bidirectional context
>When the element’s ‘direction’ property is ‘ltr’, the left-most generated box of the first line box in which the element appears has the left margin, left border and left padding, and the right-most generated box of the last line box in which the element appears has the right padding, right border and right margin.
>When the element’s ‘direction’ property is ‘rtl’, the right-most generated box of the first line box in which the element appears has the right padding, right border and right margin, and the left-most generated box of the last line box in which the element appears has the left margin, left border and left padding.
就是说当inline-level box宽度大于父容器宽度时会被拆分成多个inline-level box,
当属性direction为ltr时,margin/border/padding-left将作用于第一个的inline-level box,margin/border/padding-right将作用于最后一个的inline-level box;若属性direction为rtl时,margin/border/padding-right将作用于第一个的inline-level box,margin/border/padding-left将作用于最后一个的inline-level box。
看到了没?行级盒子真的会被分尸的,好残忍哦:|

行级盒子怎么不占空间了?怎么刷存在感啊。。。

CSS

.existed{ margin: 20px; padding: 20px; border: solid 1px red; background: yellow; background-clip: content-box; }

1
2
3
4
5
6
7
.existed{
  margin: 20px;
  padding: 20px;
  border: solid 1px red;
  background: yellow;
  background-clip: content-box;
}

对于block-level box

XHTML

<div>before bababababababa</div> <div class="existed">babababababababababa</div> <div>after bababababababa</div>

1
2
3
<div>before bababababababa</div>
<div class="existed">babababababababababa</div>
<div>after bababababababa</div>

图片 9
对于inline-level box

XHTML

<div>before bababababababa</div> <span class="existed">babababababababababa</span> <div>after bababababababa</div>

1
2
3
<div>before bababababababa</div>
<span class="existed">babababababababababa</span>
<div>after bababababababa</div>

图片 10
看,行级盒子的margin/border/padding-top/bottom怎么均不占空间的?难道行级盒子仅有content box占空间吗?
这里已经涉及到水平和垂直方向排版的范畴了,仅以盒子模型已无法解析理解上述的问题。
(要结合)

在深入解释inline-level box的上述现象前,我们需要补充一下:

  1. 一个元素会对应0~N个box;(当设置display:none;时,则对应0个box)
  2. 根据display属性值,元素会对应不同类型的controlling box(inline/block-level box均是controlling box的子类). 就CSS2而言display:inline|inline-block|inline-table|table-cell|table-column-group的元素对应inline-level box,而display:block|list-item|table|table-caption|table-header-group|table-row|table-row-group|table-footer-group的元素则对应block-level box;
  3. box布局/排版时涉及到定位问题,而CSS中通过positioning scheme来定义,其包含normal flow、floats和absolute positioning三种定位方式.而normal flow包含block formatting、inline formatting和relative positioning,其中BFC为block formatting的上下文,IFC为inline formatting的上下文。

因此大家请注意,前方高能,前方高能!!!

和IFC一起看inline-level box
IFC(Inline Formatting Context),直译为“行内格式化上下文”,这是什么鬼的翻译啊?反正我对于名词一向采用拿来主义,理解名词背后的含义才是硬道理。
我们简单理解为每个盒子都有一个FC特性,不同的FC值代表一组盒子不同的排列方式。有的FC值表示盒子从上到下垂直排列,有的FC值表示盒子从左到右水平排列等等。而IFC则是表示盒子从左到右的水平排列方式,仅此而已(注意:一个盒子仅且仅有一个FC值)。而inline-level box的FC特性值固定为IFC
另外仅处于in-flow的盒子才具有FC特性,也就是positioning scheme必须为Normal flow的盒子才具有FC特性。
除了IFC外,对于inline-level box排版而言还有另一个重要的对象,那就是line box。line box是一个看不见摸不着的边框,但每一行所占的垂直高度其实是指line box的高度,而不是inline-level box的高度。
  line box的特点:

  1. 同一行inline-level box均属于同一个line box;
  2. line box高度的计算方式()
    >The height of each inline-level box in the line box is calculated. For replaced elements, inline-block elements, and inline-table elements, this is the height of their margin box; for inline boxes, this is their ‘line-height’.
    >The inline-level boxes are aligned vertically according to their ‘vertical-align’ property. In case they are aligned ‘top’ or ‘bottom’, they must be aligned so as to minimize the line box height. If such boxes are tall enough, there are multiple solutions and CSS 2.1 does not define the position of the line box’s baseline.
    >The line box height is the distance between the uppermost box top and the lowermost box bottom.

CSS

.parent{ line-height: 1; font-size: 14px; border: solid 1px yellow; } .child{ font-size: 30px; vertical-align: middle; border: solid 1px blue; } .inline-block{ display: inline-block; overflow: hidden; border: solid 1px red; } .other{ border: solid 1px green; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.parent{
  line-height: 1;
  font-size: 14px;
  border: solid 1px yellow;
}
.child{
  font-size: 30px;
  vertical-align: middle;
  border: solid 1px blue;
}
.inline-block{
  display: inline-block;
  overflow: hidden;
  border: solid 1px red;
}
.other{
  border: solid 1px green;
}

XHTML

<span class="parent"> <span class="child"> <span class="inline-block">display:inline-block元素</span> xp子元素的文字 </span> xp父元素的文字 </span> <div class="other">其他元素</div>

1
2
3
4
5
6
7
8
<span class="parent">
  <span class="child">
    <span class="inline-block">display:inline-block元素</span>
    xp子元素的文字
  </span>
  xp父元素的文字
</span>
<div class="other">其他元素</div>

图片 11

  1. 根据规则,span.parent所在行的line box的高度受span.parent、span.child、span.inline-block元素对应的inline-level box”高度”的影响。其中span.parent的”高度”为其line-height实际值,span.child的”高度”为其line-height实际值,而span.inline-block的”高度”为其margin box的高度。由于设置line-height:1,因此span.parent和span.child的content box高度等于line-height实际值;
    2. 根据vertical-align属性垂直对齐,造成各“高度”间并不以上边界或下边界对齐;
  2. span.inline-block红色的上边框(border top)到span.child蓝色的下边框(border bottom)的距离再减去1px即为line box的高度。(line box的下界其实是span.child的content box的下限的,你看”其他元素”的上边框不是和span.child的下边框重叠了吗?如果那是line box的下界,那怎会出现重叠呢)

这里又涉及到另一个属性vertical-align了,由于它十分复杂,还是另开文章来叙述吧!

                      行级盒子小结                          
*就盒子模型而言***

  1. inline-level box与block-level box结构一致;
  2. content box的高度仅能通过属性font-size来设置,content box的宽度则自适应其内容而无法通过属性width设置;
  3. 当inline-level box的宽度大于containing block,且达到内容换行条件时,会将inline-level拆散为多个inline-level box并分布到多行中,然后当属性direction为ltr时,margin/border/padding-left将作用于第一个的inline-level box,margin/border/padding-right将作用于最后一个的inline-level box;若属性direction为rtl时,margin/border/padding-right将作用于第一个的inline-level box,margin/border/padding-left将作用于最后一个的inline-level box。

*垂直排版特性***
inline-level box排版单位不是其本身,而是line box。重点在于line box高度的计算。

  1. 位于该行上的所有in-flow的inline-level box均参与该行line box高度的计算;(注意:是所有inline-level box,而不仅仅是子元素所生成的inline-level box)
  2. replaced elements, inline-block elements, and inline-table elements将以其对应的opaque inline-level box的margin box高度参与line box高度的计算。而其他inline-level box则以line-height的实际值参与line box高度的计算;
  3. 各inline-level box根据vertical-align属性值相对各自的父容器作垂直方向对齐;
  4. 最上方的box的上边界到最下方的下边界则是line box的高度。(表述不够清晰,请参考实例理解)

Collapsing margins                      
大家必定听过或遇过collapsing margins吧,它是in-flow的block-level box排版时的一类现象。说到排版那必须引入另一个FC特性值——BFC(Block Formatting Context)的。
BFC则是表示盒子从上到下的垂直排列方式,仅此而已(注意:一个盒子仅且仅有一个FC值)。而block-level box的FC特性值固定为BFC。
collapsing margins规则
1. 元素自身margin-top/bottom collapsing

XHTML

anonymous block-level box <div class="margins"></div> anonymous block-level box <div class="margins border"></div> anonymous block-level box

1
2
3
4
5
anonymous block-level box
<div class="margins"></div>
anonymous block-level box
<div class="margins border"></div>
anonymous block-level box

CSS

.margins{margin: 50px 0 70px;} .border{border: solid 1px red;}

1
2
.margins{margin: 50px 0 70px;}
.border{border: solid 1px red;}

图片 12
当block-level box高度为0,垂直方向的border和padding为0,并且没有in-flow的子元素。那么它垂直方向的margin将会发生重叠。

2. 父子元素margin-top/top 或 margin-bottom/bottom collapsing

XHTML

anonymous block-level box <div class="parent-margins"> <div class="margins border"></div> anonymous block-level box <div class="margins border"></div> </div> anonymous block-level box <div class="parent-margins border"> <div class="margins border"></div> anonymous block-level box <div class="margins border"></div> </div> anonymous block-level box

1
2
3
4
5
6
7
8
9
10
11
12
13
anonymous block-level box
<div class="parent-margins">
  <div class="margins border"></div>
  anonymous block-level box
  <div class="margins border"></div>
</div>
anonymous block-level box
<div class="parent-margins border">
  <div class="margins border"></div>
  anonymous block-level box
  <div class="margins border"></div>
</div>
anonymous block-level box

CSS

.parent-margins{margin: 25px 0;} .margins{margin: 50px 0 25px;} .border{border: solid 1px red;}

1
2
3
.parent-margins{margin: 25px 0;}
.margins{margin: 50px 0 25px;}
.border{border: solid 1px red;}

图片 13
当父子元素margin-top间或margin-bottom间没有padding、border阻隔时,则会margin会发生重叠。
注意空白字符会造成目标父子元素间的存在anonymous block-level box,导致margin不重叠。

XHTML

anonymous block-level box <div class="parent-margins">  <div class="margins border"></div> anonymous block-level box <div class="margins border"></div> </div> anonymous block-level box

1
2
3
4
5
6
7
anonymous block-level box
<div class="parent-margins">&nbsp;
  <div class="margins border"></div>
  anonymous block-level box
  <div class="margins border"></div>
</div>
anonymous block-level box

图片 14

3. 兄弟元素margin-bottom/top collapsing

XHTML

<div class="margins">former</div> <div class="margins">latter</div>

1
2
<div class="margins">former</div>
<div class="margins">latter</div>

CSS

.margins{margin: 50px 0 25px;}

1
.margins{margin: 50px 0 25px;}

两个相邻的in-flow block-level box的上下margin将发生重叠。

*上述为默认情况下block-level box(即display:block,其它为默认值时)的margin重叠规则***
那非默认情况下呢?相比非默认情况下的margin重叠规则,我们更关心是什么时候不会产生重叠。这时又引入了另一个概念——生成新BFC。也就是block-level box A与block-level box B的FC特性值BFC可能是不同的。
当两个相邻box的FC值不为同一个BFC时,它们的margin绝对不会重叠。
那么剩下的问题就是,到底何时会产生新的BFC?哪些block-level box会采用新的BFC?默认BFC又是谁生成的呢?
其实根元素(html)会生成默认BFC供其子孙block-level box使用。
采用floats或absolute positioning作为positioning scheme时,或display:inline-block/table-cell/table-caption/flex/inline-flex或overflow属性值不为visible时,则会产生新的BFC;而新的BFC将作为子孙block-level box的FC属性值。
注意:
    1. 产生新BFC的盒子不会与子盒子发生margin重叠;
    2. display:inline-block的盒子不与 兄弟 和 父 盒子发生margin重叠,是因为display:inline-block的盒子的FC特性值为IFC,还记得line box吗?没有margin重叠是自然不过的事了;
    3. positioning scheme为floats的盒子不与floated的兄弟盒子发生margin重叠,也不会与前一个in-flow的兄弟盒子发生margin重叠。(注意:与父盒子也不会发生margin重叠)

XHTML

<div class="margins border">sibling</div> <div class="margins border float">floats1</div> <div class="margins border float">floats2</div>

1
2
3
<div class="margins border">sibling</div>
<div class="margins border float">floats1</div>
<div class="margins border float">floats2</div>

CSS

.margins{margin: 50px 0 50px;} .border{border: solid 1px red;} .float{float:left;width:200px;}

1
2
3
.margins{margin: 50px 0 50px;}
.border{border: solid 1px red;}
.float{float:left;width:200px;}

图片 15

归纳FC、BFC和IFC                      

由于上述主要阐述inline/block-level box,因此通过“仅此而已”来简化BFC和IFC的内涵。下面我们稍微全面一点去理解BFC和IFC如何影响inline/block-level box。

FC(Formatting Context),用于初始化时设置盒子自身尺寸和排版规则。注意“初始化”,暗指positioning scheme采用的是normal flow,要知道floats和absolute positioning均不是默认/初始化值。也就是说我们在讨论FC及BFC和IFC时,均针对in-flow box而言的。
  BFC
**对于不产生新BFC的盒子**

  1. block-level boxes垂直排列,盒子的left outer edge与所在的containing block的左边相接触,默认情况下(width为auto时)right outer edge则与所在的containing block的右边相接触。即使存在floated的兄弟盒子。

XHTML

<div id="container" style="border:solid 2px red;"> <div id="left" style="float:left;width:300px;height:30px;background:yellow;opacity:0.2;"></div> <div id="right" style="height:30px;background:#999;"></div> </div>

1
2
3
4
<div id="container" style="border:solid 2px red;">
  <div id="left" style="float:left;width:300px;height:30px;background:yellow;opacity:0.2;"></div>
  <div id="right" style="height:30px;background:#999;"></div>
</div>

图片 16

虽然 div#left 浮点了,但 div#right 的left outer edge还是与 div#container 的left content edge相接触。 div#right 所在的containing block就是 div#container 的content box.

  1. block-level box高度的计算
    The element’s height is the distance from its top content edge to the first applicable of the following:
    the bottom edge of the last line box, if the box establishes a inline formatting context with one or more lines
    the bottom edge of the bottom (possibly collapsed) margin of its last in-flow child, if the child’s bottom margin does not collapse with the element’s bottom margin
    the bottom border edge of the last in-flow child whose top margin doesn’t collapse with the element’s bottom margin
    zero, otherwise
    Only children in the normal flow are taken into account (i.e., floating boxes and absolutely positioned boxes are ignored, and relatively positioned boxes are considered without their offset).

也就out-flow box不影响block-level box高度的计算。也就是解释了为何div中仅含floated元素时,div盒子高度为0的现象了。

**对于产生新BFC的盒子**
对于产生新BFC的盒子而言,除了不发生collapsing margins的情况外,还有两个与浮点相关的现象。

  1. out-flow box纳入block-level box高度的计算
    In addition, if the element has any floating descendants whose bottom margin edge is below the element’s bottom content edge, then the height is increased to include those edges. Only floats that participate in this block formatting context are taken into account, e.g., floats inside absolutely positioned descendants or other floats are not.
    也就positioning scheme为floats的box也会影响block-level box高度的计算。

  2. 誓死不与positioning scheme为floats的兄弟盒子重叠
    The border box of a table, a block-level replaced element, or an element in the normal flow that establishes a new block formatting context (such as an element with ‘overflow’ other than ‘visible’) must not overlap the margin box of any floats in the same block formatting context as the element itself. If necessary, implementations should clear the said element by placing it below any preceding floats, but may place it adjacent to such floats if there is sufficient space. They may even make the border box of said element narrower than defined by section 10.3.3. CSS2 does not define when a UA may put said element next to the float or by how much said element may become narrower.

产生新BFC的block-level box不与floated-box重叠,而是floated-box的margin-box与block-level box的border-box相接触。
水平方向

XHTML

<div style="float:left;width:100px;border: solid 1px red;margin-right:50px;">floated</div> <div style="width:200px;border: solid 1px blue;margin-left:100px;overflow:hidden;">gen new BFC balabala</div>

1
2
<div style="float:left;width:100px;border: solid 1px red;margin-right:50px;">floated</div>
<div style="width:200px;border: solid 1px blue;margin-left:100px;overflow:hidden;">gen new BFC balabala</div>

图片 17
垂直方向

XHTML

<div style="float:left;width:100px;border: solid 1px red;margin-bottom:50px;">floated</div> <div style="width:200px;border: solid 1px blue;margin-top:100px;overflow:hidden;">gen new BFC balabala</div>

1
2
<div style="float:left;width:100px;border: solid 1px red;margin-bottom:50px;">floated</div>
<div style="width:200px;border: solid 1px blue;margin-top:100px;overflow:hidden;">gen new BFC balabala</div>

图片 18

 

 IFC

提起IFC那就不能不说line box,而line box高度的计算方式上面已经叙述了,那line box的宽度呢?
line box默认情况下左边框与containing block的左边框接触,右边框与containing block的右边框接触。若存在floated兄弟盒子,则line box的宽度为containing block的宽度减去floated-box的outer-box的宽度。
图片 19
而inline-level box必须包含在line box中,若inline-level box的white-space:nowrap或pre外的其他值时,就会将inline-level box拆分为多个inline-level box并散落到多个line box中,从而实现文字环绕图片的效果了。
图片 20
否则inline-level box会捅破line box(即line box宽度不变)

    行——换与不    

先看看关于换行的CSS属性吧!

white-space normal: 忽略/合并空白 pre: 保留空白,如同<pre>的行为 nowrap: 忽略/合并空白,文本不会换行,直到遇到<br/> pre-wrap: 保留空白,但是会正常地进行换行 pre-line: 忽略/合并空白,但是会正常地进行换行 inherit: 从父元素继承。 word-wrap normal: 只在允许的断字点换行 break-word: 在长单词或URL地址内部进行换行 word-break normal:依照亚洲和非亚洲语言的文本规则,允许在单词内换行。 keep-all:让亚洲语言文本如同非亚洲语言文本那样不允许在任意单词内换行。 break-all:允许非亚洲语言文本行如同亚洲语言文本那样可以在任意单词内换行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
white-space
    normal: 忽略/合并空白
    pre: 保留空白,如同<pre>的行为
    nowrap: 忽略/合并空白,文本不会换行,直到遇到<br/>
    pre-wrap: 保留空白,但是会正常地进行换行
     pre-line: 忽略/合并空白,但是会正常地进行换行
    inherit: 从父元素继承。
  word-wrap
    normal: 只在允许的断字点换行
    break-word: 在长单词或URL地址内部进行换行
  word-break
    normal:依照亚洲和非亚洲语言的文本规则,允许在单词内换行。
    keep-all:让亚洲语言文本如同非亚洲语言文本那样不允许在任意单词内换行。
    break-all:允许非亚洲语言文本行如同亚洲语言文本那样可以在任意单词内换行。

具体示例可参考:css中强制换行word-break、word-wrap、white-space区别实例说明

在处理换行问题上,我们要处理的对象分为亚洲语言文本和非亚洲语言文本。对于亚洲语言文本是以字作为操作单元,而非亚洲语言文本是以单词作为操作单元。而换行是针对特定语言文本的操作单元来处理,所以默认情况下会看到一串没空格的“中文”自动换行,而一串没空格的“英文”却没有换行的现象。
对于我们(亚洲人)而言,一般采用 word-break:break-all;word-wrap:break-word; 来实现中英文自动换行效果,但英文单词本身是不能这样简单粗暴地换行的。
英语单词移行有一定规则,归纳如下:
1.移行处要用连字符号“-”,只占一个印刷符号的位置并放在该行的最后.
2.移行时一般按照音节进行,故只可在两音节之间分开,不能把一个完整的音节分写在上下两行.例如:Octo-ber(正),Octob-er(误).
3.复合词要在构成该词的两部分之间移行.如:some-thing,bed-room等.
4.如果复合词原来就有连字符号,则就在原连字符号处分行.如:good-looking等.
5.两个不同的辅音字母在一起时,移行时前后各一个.如:cap-tain,ex-pose等.
6.当两个音节间只有一个辅音字母时,如果该辅音字母前的元音字母按重读开音节的规则发音,该辅音字母移至下一行.如:fa-ther等.但如果元音按重读闭音节的规则发音,则该辅音字母保留在上一行末尾.例如:man-age等.
7.当遇到双写辅音字母时,一般把它们分成前后各一个.例如:mat-ter等.
8.当重读音节在后面时,元音字母前的辅音字母通常移到下一行.如:po-lite等.
9.单音节词不可移行.如:length,long,dance等.
10.前缀或后缀要保持完整,不可分开写.如:unfit,disappear等.
11.阿拉伯数字不分开移行书写.
12.不论音节多少,专有名词不宜分写.例如:Nancy,Russia等.
13.缩写词、略写词或某些词的缩写形式不可移行书写.例如:U.N.(联合国),P.R.C.(中华人民共和国),isn’t.
14.不能构成一个音节的词尾不分写.例如:stopped等.
15.字母组合或辅音连缀不可移行.例如:machine,meat等.

CSS简化了上述的规则,若需要换行处恰好是一个复合词,就在原连字符号处分行;其它情况则整个单词移到下一行。因此使用 word-wrap:break-word; 就OK了。

另外我们还可以通过 word-break:keep-all;white-space:nowrap; 来实现打死都不换行的效果
总结                              
洋洋洒洒总算把Box Model、BFC和IFC描述了个大概。对于BFC折腾点就是在collapsing margins那,另外还有产生新BFC这个行为上(这个跟浮动等有交集,以后再理清吧);而IFC重点在于理解line box,其实line box也像block-level box那样是垂直排列的,而inline-level box则是以line box作为容器实现水平排列罢了。到这里会发现理解IFC比BFC蛋疼多了,不过有了这篇作基础,后面理解text-align、line-height和vertical-align就轻松不少了。

本文纯个人理解,若有纰漏,望各位指正,谢谢!

感谢                              

)

)

(IFC)

[KB010: 常规流( Normal flow ) ]()
[CSS 101: Block Formatting Contexts]()

打赏支持我写出更多好文章,谢谢!

打赏作者

SO热门问答:可以为半个字符应用CSS样式吗?

2014/06/13 · CSS · CSS

本文由 伯乐在线 - Carman 翻译。未经许可,禁止转载!
英文出处:stackoverflow。欢迎加入翻译组。

调试 CSS 的方法

2016/09/06 · CSS · 调试

原文出处: Ben Frain   译文出处:众成翻译 - yanni4night   

我经历过许多 CSS 代码的调试工作,有别人写的也有自己写的,有移动端平台的也有标准桌面浏览器的,从陈旧的 IE 到最新的基于 Webkit 的每日构建。经验告诉我,很多人并没有一个标准的 CSS 调试流程。

我发现在大多数情况下,拥有专业的解决问题的方法,能够节省花在 bug 上的时间。

下面是我总结的经验。

我不保证这是最适合的调试 CSS 的方法,但是确实对我很有效。如何 CSS 不是你的主要编程语言,调试它可能就像暗黑艺术一样;遵循下面的指南能够帮助你更有效地定位和解决 bug。

概括地说,我把调试流程分为 3 个阶段:

  • 评估并快速修复
  • 还原和重现
  • 定位根源并修复

我们挨个解释每个阶段并实践一个例子。

前言

每当来个需要既要水平排版又要设置固定高宽时,我就会想起display:inline-block,还有为了支持IE5.5/6/7的hack*display:inline;*zoom:1;。然后发现盒子间无端端多了个不可选的空白符,于是想尽办法修复这个bug。

直到一天拜读了@一丝姐、@HAX等高人的秘笈后才顿悟,原来我错了。那不是bug,是我不懂而已。

打赏支持我写出更多好文章,谢谢!

任选一种支付方式

图片 21 图片 22

1 赞 3 收藏 评论

Mathew MacLean 提问

我正在寻找:

一种方法为半个字符应用样式(在这种情况下,一半的字母是透明的)。

我目前已经搜索并尝试的(不走运)

  • 渲染一半字符/字母的方法
  • 用CSS或JavaScript渲染字符的一部分
  • 对一个字符的50%应用CSS

以下是我尝试实现的一个例子:

图片 23

这个是否有一个CSS或者JavaScript的解决方法存在,还是我必须采用图片的方法?我不愿意采用图片的方法,因为文本将最终是动态生成的。

 

评估并快速修复

如果 CSS 是你的主要工作语言,或者你对 CSS 有一定的理解和实践经验的话,解决 CSS 问题就有很多简单的方法,否则的话,方法就少一些。

有经验的 CSS 开发者可能都知道的一些 CSS 陷阱:

  • 图片周边存在有趣的空白?设置 display: block(图片默认是内联的,因此会有空白)。
  • 元素排列不正确?你可能有浮动的元素。
  • 绝对定位元素不显示、位置错误或者被遮挡?你可能没有设置父元素的 position 属性或者用 transform 及 opacity 创建一个 z-index 上下文。
  • 伪元素不显示?你可能忘记了设置 ‘content’的值。

这样的 “bug” 有一大堆。实际上根本没有 bug,更多的是开发者缺少对浏览器行为的理解。更准确地说,是 CSS 代码让浏览器怎么做。

对这些 CSS 特性熟悉的开发者能够快速定位到问题并且修复。他们对 bug 的认识与那些对 CSS 不了解的人会产生分歧。这样在解决 CSS bug 中对‘工作流’需求的重要性的认识就会因人而异。

对于‘快速修复’中没有覆盖的陌生问题,在开发者工具中靠猜来解决问题的方式已经没什么价值。即使运气好问题被解决了,也很难判断出问题到底是怎样被解决的。

如果出现的问题不能被轻易解决,先确定问题区域的范围,抓取 HTML 标签(也就是拷贝 DOM),进入下一个调试阶段:还原和重现。

专业提示:大多数浏览器的开发者工具会让你选择包裹元素并拷贝 HTML 区块。在 Chrome 的开发者工具中,要连同包裹元素一起拷贝,需要点击 ‘Copy > Copy OuterHTML’。

先行者——IE5.5中的inline-block

当我们为支持IE5.5/6/7而添加这段hack时*display:inline;*zoom:1,总以为从IE8开始才支持display:inline-block属性值。其实从IE5.5开始已经支持了,只是IE5.5/6/7支持的是IE的自定义标准,而从IE8开始则是支持CSS2.1标准而已。

The inline-block value is supported starting with Internet Explorer 5.5. You can use this value to give an object a layout without specifying the object’s height or width.

XHTML

<style type="text/css"> .bk1{ background: #06F; } .bk2{ background: #F60; } .item{ width: 100px; height: 100px; display:inline-block; } </style> <div class="bk1 item"></div> <div class="bk2 item"></div> <span class="bk1 item"></span> <span class="bk2 item"></span>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<style type="text/css">
.bk1{
  background: #06F;
}
.bk2{
  background: #F60;
}
.item{
  width: 100px;
  height: 100px;
  display:inline-block;
}
</style>
<div class="bk1 item"></div>
<div class="bk2 item"></div>
<span class="bk1 item"></span>
<span class="bk2 item"></span>

图片 24

经过CSS2.1洗礼的我们对上述内容不禁会发出两个疑问:

  1. 为啥block-level element设置了display:inline-block后还是垂直方向排列呢?
  2. 为啥inline-level element设置了display:inline-block后之间没有诡异的间隙呢?

还记得杨过是如何变成神雕大侠的吗?不就是被断右臂后发现左手才是真爱吗:)
好了,其实我的意思是抛弃过去对display:inline-block的认知,重新来理解IE5.5/6/7下的它才是硬道理啦。

对于问题1,首先上面的引用很直白地告诉我们——display:inline-block能触发hasLayout,然后就没了。所以block-level element依然是block-level element,不会一夜成了inline-level element的。结论:display:inline-block仅会触发hasLayout,而元素本该怎么排版还是怎么排版。关于hasLayout的内容可参考《CSS魔法堂:hasLayout原来是这样!》

对于问题2,我们先看看是否真的没有间隙吧!

XHTML

<style type="text/css"> .bk1{ background: #06F; } .bk2{ background: #F60; } .item{ width: 100px; height: 100px; display:inline-block; } </style> <span class="bk1 item"></span> <span class="bk2 item"></span> <br/><br/> <span class="bk1 item">bk1</span> <span class="bk2 item"></span>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<style type="text/css">
.bk1{
  background: #06F;
}
.bk2{
  background: #F60;
}
.item{
  width: 100px;
  height: 100px;
  display:inline-block;
}
</style>
<span class="bk1 item"></span>
<span class="bk2 item"></span>
<br/><br/>
<span class="bk1 item">bk1</span>
<span class="bk2 item"></span>

图片 25

见鬼了,在前一个盒子内添加些文本就出现间隙了?其实这真的和display:inline-block无关的,大家就放过他吧!来上呈堂证供!

XHTML

<style type="text/css"> .bk1{ background: #06F; } .bk2{ background: #F60; } <span class="bk1">no line break</span> <span class="bk2"> has line break </span>

1
2
3
4
5
6
7
8
9
10
11
12
13
<style type="text/css">
.bk1{
  background: #06F;
}
.bk2{
  background: #F60;
}
<span class="bk1">no line break</span>
  
  
<span class="bk2">
has line break
</span>

图片 26

可以看到蓝色块k和红色块h间存在一个空格,而红色块k后也存在一个空格。可是代码中我们看到蓝红色块间有4个&#x20HTML实体,为啥只有一个空格呢?而红色块中仅仅换了行而已,怎么就有个空格呢?

先抛结论:上面两端代码均是white space、white space collasping再作祟。

关于作者:^-^肥仔John

图片 27

偏前端的临栈工程师 个人主页 · 我的文章 · 5 ·    

图片 28

来自 Arbel 的最佳回答:(1280+ 赞)

还原和重现

本阶段的 CSS bug 修复在类似 Codepen 的帮助下异常简单。我们目的主要是复现出此问题 – 也就是引起 bug 的代码。这能让我们快速定位 bug,直捣黄龙。

为清晰起见,只把相关的 HTML 和 CSS 提取出来复现问题。你既可以手打 HTML 对应的 CSS,也可以复制真实的代码。如果可能的话,不用把所有 CSS 代码一股脑拷贝过去重现问题,保证最精简的要素即可。保持逐步增加 CSS 的习惯,问题就会自己找到你。

在快要接近真相时,往往只需要一个特殊的 CSS 属性的改变就能让 bug 暴露出来。

相对应的做法是,把所有 CSS 都扔进入复现问题,然后每次移除一点,直到问题出现。在实践中,我发现这略笨,不用也因人而异,你可能有不同的见解。

逐步地增加或删除 CSS 代码已经是重现问题和定位故障的固定套路了。

White space不仅是空格符那么简单

初看之下以为就是空格键,其实white space是一组空白字符和换行符组成。查看unicode字符集我们会发现有一大堆空白字符(如NO-BREAK SPACE等),但HTML只把ASCII space( )ASCII tab( )ASCII form feed(&#x000C)Zero-width space(​)纳入white space囊中,另外还将line break(换行符)carriage return( )line feed( )和它俩的组合纳入white space中。

已做成一个插件,放 Github 上了!

那么 HTML 标签呢?

假设使用最少 CSS 代码复现问题时,效果有如原始代码一样。这也是有用的,我们现在看 HTML 标签。

第一件事要做的,也是不能跳过的,就是检查标签的有效性。即使报告出我们不关心的问题(比如 meta),至少能保证它不会以某种方式破坏美感。我们希望能发现未闭合的标签、没有引号的属性,以及其它任何可能影响浏览器解析的问题。建议你使用 W3C validator。

一旦标签检查通过,将有助于消除浏览器引入意外样式的可能性。这样做:

首先,把所有元素改成 div(块级元素)和 span(行内元素),保证它们只被 CSS 的类选择器选中。也许有必要把额外的选择器移除,如把 a.link 改为 .link

通过使用固定的标签我们消除了浏览器针对特定元素引入默认样式的可能性。表单元素是个特例(马上会在例子中见到)。

如果把所有元素改成 div 和 span,问题消失了,那么浏览器引入默认样式的嫌疑就被确定了。现在在 computed styles 面板中寻找浏览器增加了什么样式,想办法覆盖它。总之就是要看计算后的样式。

inter-word space——White space的用途之一

西文是以空格来分隔单词的,而汉字间则无需空格分隔,但为了统一西文、东亚和CJK的排版,于是抽象出一个名为inter-word space的概念用于分隔词义单元,white space则作为inter-word space的值域,而定义域就是语言信息。如西文以ASCII SPACE作为inter-word space,而泰文则以Zero-width space作为inter-word space,汉语则没有inter-word space,所以word-spacing属性不影响汉字间的距离,本来无一物何处惹尘埃呢。字形、单词间的水平距离

演示 | 下载 Zip | Half-Style.com (重定向到GitHub)


  • 单个字符的纯css
  • JavaScript用来自动覆盖文本或多字符
  • 保护文本的可读性,盲人或视障人士使用的屏幕阅读器可识别

定位根源并修复

如果简化 HTML 标签也没有找到问题,并且是可稳定复现的,那么就该换个浏览器试一试。是否同样的问题出现在 Chrome,IE,Safari 和 Firefox 上?如果不是,哪个的表现是正确的?如果只有一个浏览器是错的,那么就值得去搜索一下对应的 bug 跟踪系统了:

  • Chrome bugs
  • Firefox bugs
  • Safari bugs
  • Microsoft bugs

是某浏览器的问题吗?或者是某浏览器的特定版本的问题?问题是否在修复中?有没有不影响其它浏览器的解决方案?实在不行你可以为特定的浏览器编写修复代码吗?

过去我曾详细描述过如何向浏览器提 bug,在 2011 年 Lea Verou 也写过一份描述提 bug 流程的文章。

另一种情况是可能需要‘无害的’hack。例如,我最近遇到的一个场景是在一个块级元素后面的元素必须是绝对定位的才能显示出来。 left: 100% 只有在 IE 浏览器(移动端是Windows Phone 8,8.1 和 10)中不生效。IE 中在两个元素之间总有一个空隙。看起来像是一个亚像素渲染问题,因此 left: 99.99% 就能解决问题而不会影响其它浏览器。这是个 hack 手段,但我们知道原理(有的浏览器会舍入,其它则不会),标注在 CSS 的注释中,没有任何危害。

微软的 Greg Whitworth 告诉我了关于亚像素舍入的更多细节。WebKit 和 Blink 内核舍入 1/64,Gecko 内核舍入 1/60,Edge 舍入 1/100(感谢 Webkit 开发者 ‘smfr’)。

White space collapsing的玩法

兼容性问题又来了,因为各浏览器的实现均不尽相同。

XHTML

<style type="text/css"> span{background:#F60;} </style> <div><span> before</span></div> <div><span> before</span></div> <div><span>after </span></div> <div><span>after </span></div> <div><span>after </span></div> <div><span>one two</span></div> <div><span>one two</span></div> <div><span> </span></div>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<style type="text/css">
  span{background:#F60;}
</style>
<div><span>
 
before</span></div>
<div><span>
 
before</span></div>
<div><span>after
 
</span></div>
<div><span>after
 
</span></div>
<div><span>after
</span></div>
<div><span>one
two</span></div>
<div><span>one
two</span></div>
<div><span> &#x000C;
</span></div>

** chrome43 **

  1. 对于起始标签与第一个non-white-space字符间的white-space字符串,以carriage return( )作为white-space合并单元的起始符,最后保留各合并单元的合并结果。
  2. 结束标签与最后一个non-white-space字符间的white-space字符串,以carriage return( )作为white-space合并单元的结束符,最后保留各合并单元的合并结果。
  3. 词义单元间的white-space字符串,以carriage return( )作为white-space合并单元的分界符,最后保留各合并单元的合并结果。
  4. 标签内仅包含white-space字符串,那么这些white-space字符串将被忽略。

图片 29
** FF5.0 **

  1. 对于起始标签与第一个non-white-space字符间和结束标签与最后一个non-white-space字符间的white-space字符串将被忽略。
  2. 词义单元间的white-space字符串,以carriage return( )作为white-space合并单元的分界符,最后保留各合并单元的合并结果。
  3. 标签内仅包含white-space字符串,那么这些white-space字符串将被忽略。

图片 30
** IE8+ **

  1. 对于起始标签与第一个non-white-space字符间和结束标签与最后一个non-white-space字符间的white-space字符串将被忽略。
  2. 词义单元间的white-space字符串,合并为1个(ASCII space)字符。
  3. 标签内仅包含white-space字符串,那么这些white-space字符串将被忽略。

图片 31

** IE5.5/6/7 **

  1. 对于起始标签与第一个non-white-space字符间的white-space字符串将被忽略。
  2. 结束标签与最后一个non-white-space字符间的white-space字符串,合并为1个(ASCII space)字符。
  3. 词义单元间的white-space字符串,合并为1个(ASCII space)字符。
  4. 标签内仅包含white-space字符串,那么这些white-space字符串将被忽略。

图片 32
合并单元:合并单元包含0到N个white-space字符串,最终合并为0到1个white-space字符
SGML描述B.3.1 Line breaks

specifies that a line break immediately following a start tag must be ignored, as must a line break immediately before an end tag. This applies to all HTML elements without exception.

XHTML

<A>My favorite Website</A> <A> My favorite Website </A>

1
2
3
4
<A>My favorite Website</A>
<A>
My favorite Website
</A>

望文生义翻译法:标签与正文间的line breaks要被忽略掉!也就是上下两种HTML格式的渲染效果应该一致。实际上除了IE5.5/6/7外其他浏览器均遵守之一规定的。也许你会说上面的实验不是已经证明chrome43不遵守这个法则吗?其实

XHTML

<A> My favorite Website </A>

1
2
3
<A>
My favorite Website
</A>

HTML格式等价于<A>#x000A;My favorite Website#x000A;</A>而不是<A>#x000D;#x000A;My favorite Website#x000D;#x000A;</A>。现在大家都清楚了吧:)

绕到这里我想大家都有点晕了,到底这个跟问题2有啥关系呢?先不要着急嘛,我们先记住两点:

  1. IE5.5/6/7中”结束标签与最后一个non-white-space字符间的white-space字符串,合并为1个(ASCII space)字符”;
  2. IE5.5/6/7中仅字符(串)可以作为词义单元,而IE8+中inline-level element也作为词义单元。
XHTML

&lt;span class="bk1 item"&gt;&lt;/span&gt; &lt;span class="bk2
item"&gt;&lt;/span&gt; &lt;br/&gt;&lt;br/&gt; &lt;span class="bk1
item"&gt;bk1&lt;/span&gt; &lt;span class="bk2 item"&gt;&lt;/span&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6d17e73c7306787940-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d17e73c7306787940-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6d17e73c7306787940-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d17e73c7306787940-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6d17e73c7306787940-5">
5
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6d17e73c7306787940-1" class="crayon-line">
&lt;span class=&quot;bk1 item&quot;&gt;&lt;/span&gt;
</div>
<div id="crayon-5b8f6d17e73c7306787940-2" class="crayon-line crayon-striped-line">
&lt;span class=&quot;bk2 item&quot;&gt;&lt;/span&gt;
</div>
<div id="crayon-5b8f6d17e73c7306787940-3" class="crayon-line">
&lt;br/&gt;&lt;br/&gt;
</div>
<div id="crayon-5b8f6d17e73c7306787940-4" class="crayon-line crayon-striped-line">
&lt;span class=&quot;bk1 item&quot;&gt;bk1&lt;/span&gt;
</div>
<div id="crayon-5b8f6d17e73c7306787940-5" class="crayon-line">
&lt;span class=&quot;bk2 item&quot;&gt;&lt;/span&gt;
</div>
</div></td>
</tr>
</tbody>
</table>


IE5.5/6/7下等价于  


XHTML

&lt;span&gt; &lt;/span&gt; &lt;br/&gt;&lt;br/&gt; &lt;span&gt;bk1
&lt;/span&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6d17e73ca280682483-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d17e73ca280682483-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6d17e73ca280682483-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d17e73ca280682483-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6d17e73ca280682483-5">
5
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6d17e73ca280682483-1" class="crayon-line">
&lt;span&gt;
</div>
<div id="crayon-5b8f6d17e73ca280682483-2" class="crayon-line crayon-striped-line">
&lt;/span&gt;
</div>
<div id="crayon-5b8f6d17e73ca280682483-3" class="crayon-line">
&lt;br/&gt;&lt;br/&gt;
</div>
<div id="crayon-5b8f6d17e73ca280682483-4" class="crayon-line crayon-striped-line">
&lt;span&gt;bk1
</div>
<div id="crayon-5b8f6d17e73ca280682483-5" class="crayon-line">
&lt;/span&gt;
</div>
</div></td>
</tr>
</tbody>
</table>


对比一下上面的规则,空隙自然就有了。  
IE8+下等价于  


XHTML

&lt;span&gt;&nbsp; &nbsp;&lt;/span&gt; &lt;br/&gt;&lt;br/&gt;
&lt;span&gt;&nbsp; &nbsp;&lt;/span&gt;

<table>
<colgroup>
<col style="width: 50%" />
<col style="width: 50%" />
</colgroup>
<tbody>
<tr class="odd">
<td><div class="crayon-nums-content" style="font-size: 13px !important; line-height: 15px !important;">
<div class="crayon-num" data-line="crayon-5b8f6d17e73cd347104087-1">
1
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d17e73cd347104087-2">
2
</div>
<div class="crayon-num" data-line="crayon-5b8f6d17e73cd347104087-3">
3
</div>
<div class="crayon-num crayon-striped-num" data-line="crayon-5b8f6d17e73cd347104087-4">
4
</div>
<div class="crayon-num" data-line="crayon-5b8f6d17e73cd347104087-5">
5
</div>
</div></td>
<td><div class="crayon-pre" style="font-size: 13px !important; line-height: 15px !important; -moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4;">
<div id="crayon-5b8f6d17e73cd347104087-1" class="crayon-line">
&lt;span&gt;&amp;nbsp;
</div>
<div id="crayon-5b8f6d17e73cd347104087-2" class="crayon-line crayon-striped-line">
&amp;nbsp;&lt;/span&gt;
</div>
<div id="crayon-5b8f6d17e73cd347104087-3" class="crayon-line">
&lt;br/&gt;&lt;br/&gt;
</div>
<div id="crayon-5b8f6d17e73cd347104087-4" class="crayon-line crayon-striped-line">
&lt;span&gt;&amp;nbsp;
</div>
<div id="crayon-5b8f6d17e73cd347104087-5" class="crayon-line">
&amp;nbsp;&lt;/span&gt;
</div>
</div></td>
</tr>
</tbody>
</table>


inline-level
element整体作为词义单元,从外部看根本不用管里面具体字符串是什么。

第一部分: 基本解决方案

图片 33

演示: 


这种方法用于任何动态文本或单个字符,并且都是自动适用的。所有你需要做的就是在目标文本上添加一个class,剩下的就解决了。

同时,保留了原文的可访问性,可以被盲人或视障人士使用的屏幕阅读器识别。

单个字符的实现

纯CSS。所有你需要做的就是把.halfStyle class用在每个你想要渲染一半样式字符的元素上。

对于每个包含字符的span元素,你可以添加一个data属性,比如data-content=”X”,并且在伪元素上使用content:attr(data-content);这样,.halfStyle:before class将会是动态的,你不需要为每个实例进行硬编码

任意文本的实现

只需添加textToHalfStyle class到包含文本的元素上。


CSS:

JavaScript

.halfStyle { position:relative; display:inline-block; font-size:80px; /* or any font size will work */ color: black; /* or transparent, any color */ overflow:hidden; white-space: pre; /* to preserve the spaces from collapsing */ } .halfStyle:before { display:block; z-index:1; position:absolute; top:0; left:0; width: 50%; content: attr(data-content); /* dynamic content for the pseudo element */ overflow:hidden; color: #f00; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.halfStyle {
    position:relative;
    display:inline-block;
    font-size:80px; /* or any font size will work */
    color: black; /* or transparent, any color */
    overflow:hidden;
    white-space: pre; /* to preserve the spaces from collapsing */
}
.halfStyle:before {
    display:block;
    z-index:1;
    position:absolute;
    top:0;
    left:0;
    width: 50%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow:hidden;
    color: #f00;
}

HTML

JavaScript

<p>Single Characters:</p> <span class="halfStyle" data-content="X">X</span> <span class="halfStyle" data-content="Y">Y</span> <span class="halfStyle" data-content="Z">Z</span> <span class="halfStyle" data-content="A">A</span> <hr/> <p>Automated:</p> <span class="textToHalfStyle">Half-style, please.</span>

1
2
3
4
5
6
7
8
9
10
<p>Single Characters:</p>
<span class="halfStyle" data-content="X">X</span>
<span class="halfStyle" data-content="Y">Y</span>
<span class="halfStyle" data-content="Z">Z</span>
<span class="halfStyle" data-content="A">A</span>
 
<hr/>
<p>Automated:</p>
 
<span class="textToHalfStyle">Half-style, please.</span>

它会自动生效,只要添加 textToHalfStyle class到包含文本的元素上。

jQuery 自动模式:

JavaScript

jQuery(function($) { var text, chars, $el, i, output; // Iterate over all class occurences $('.textToHalfStyle').each(function(idx, el) { $el = $(el); text = $el.text(); chars = text.split(''); // Set the screen-reader text $el.html('<span style="position: absolute !important;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);">' + text + '</span>'); // Reset output for appending output = ''; // Iterate over all chars in the text for (i = 0; i < chars.length; i++) { // Create a styled element for each character and append to container output += '<span aria-hidden="true" data-content="' + chars[i] + '">' + chars[i] + '</span>'; } // Write to DOM only once $el.append(output); }); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
jQuery(function($) {
    var text, chars, $el, i, output;
 
    // Iterate over all class occurences
    $('.textToHalfStyle').each(function(idx, el) {
        $el = $(el);
        text = $el.text();
        chars = text.split('');
 
        // Set the screen-reader text
        $el.html('&lt;span style="position: absolute !important;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);"&gt;' + text + '&lt;/span&gt;');
 
        // Reset output for appending
        output = '';
 
        // Iterate over all chars in the text
        for (i = 0; i &lt; chars.length; i++) {
            // Create a styled element for each character and append to container
            output += '&lt;span aria-hidden="true" data-content="' + chars[i] + '"&gt;' + chars[i] + '&lt;/span&gt;';
        }
 
        // Write to DOM only once
        $el.append(output);
    });
});

演示: 


计算后样式

开发者工具中比较容易被忽视的是 computed styles 面板。如果你对 computed styles 不熟悉的话,顾名思义,就是真正应用到元素上的样式。这很重要,因为你写的样式不一定会生效。同样,你写的样式也不是所有生效的样式。下面的例子将解释我的意思:

XHTML

<fieldset class="outer"> <div class="inner"> <label for="" class="item"><span>hello</span></label> <label for="" class="item"><span>hello</span></label> <label for="" class="item"><span>hello</span></label> <label for="" class="item"><span>hello</span></label> <label for="" class="item"><span>hello</span></label> <label for="" class="item"><span>hello</span></label> <label for="" class="item"><span>hello</span></label> <label for="" class="item"><span>hello</span></label> <label for="" class="item"><span>hello</span></label> <label for="" class="item"><span>hello</span></label> </div> </fieldset>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<fieldset class="outer">
    <div class="inner">
        <label for="" class="item"><span>hello</span></label>
        <label for="" class="item"><span>hello</span></label>
        <label for="" class="item"><span>hello</span></label>
        <label for="" class="item"><span>hello</span></label>
        <label for="" class="item"><span>hello</span></label>
        <label for="" class="item"><span>hello</span></label>
        <label for="" class="item"><span>hello</span></label>
        <label for="" class="item"><span>hello</span></label>
        <label for="" class="item"><span>hello</span></label>
        <label for="" class="item"><span>hello</span></label>
    </div>
</fieldset>

对应的 CSS 是:

CSS

.outer { max-width: 400px; } .inner { width: 100%; overflow-x: auto; overflow-y: hidden; -ms-overflow-style: -ms-autohiding-scrollbar; -webkit-overflow-scrolling: touch; white-space: nowrap; } .item { display: inline-block; width: 100px; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.outer {
    max-width: 400px;
}
 
.inner {
    width: 100%;
    overflow-x: auto;
    overflow-y: hidden;
    -ms-overflow-style: -ms-autohiding-scrollbar;
    -webkit-overflow-scrolling: touch;
    white-space: nowrap;
}
 
.item {
    display: inline-block;
    width: 100px;
}

outer 的宽度会是多少?如果你认为是 max-width 的 400px,我会原谅你的。但是不是我们看到的宽度,看 Ben Frain 编写的 codepen。

什么情况?为什么不是 max-width 的值?给你个思路,打开 Computed Styles 面板。

找到问题的根源了吗?

我来给你解释下。默认地,fieldset 元素的宽度会等于其内容的宽度。在 Chrome 的Computed Styles 面板中,min-width 的值是一个新的 min-content

min-width 设置一个新值来“修复”它。这个例子中,min-width: 0 就会让 max-width 按照我们期望的那样进行工作。

这正是开发者工具的 Computed Styles 面板中看到的值。记住你写的代码不一定是浏览器计算后的。

后来者居上——CSS2.1描述中的inline-block

相对IE自定义的inline-block,CSS2.1引入的inline-block就好理解多了,它做了两件事:

  1. 将元素变性为inline-level element;
  2. 让元素产生新的BFC。

第二部分:先进的解决方案-独立的左边和右边

图片 34

使用这种方法你可以分别单独的渲染左边和右边部分。

一切都是相同的,只是更高级的CSS在发挥作用。

演示: 

JavaScript

.halfStyle { position:relative; display:inline-block; font-size:80px; /* or any font size will work */ color: transparent; /* hide the base character */ overflow:hidden; white-space: pre; /* to preserve the spaces from collapsing */ } .halfStyle:before { /* creates the left part */ display:block; z-index:1; position:absolute; top:0; width: 50%; content: attr(data-content); /* dynamic content for the pseudo element */ overflow:hidden; pointer-events: none; /* so the base char is selectable by mouse */ color: #f00; /* for demo purposes */ text-shadow: 2px -2px 0px #af0; /* for demo purposes */ } .halfStyle:after { /* creates the right part */ display:block; direction: rtl; /* very important, will make the width to start from right */ position:absolute; z-index:2; top:0; left:50%; width: 50%; content: attr(data-content); /* dynamic content for the pseudo element */ overflow:hidden; pointer-events: none; /* so the base char is selectable by mouse */ color: #000; /* for demo purposes */ text-shadow: 2px 2px 0px #0af; /* for demo purposes */ }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
.halfStyle {
    position:relative;
    display:inline-block;
    font-size:80px; /* or any font size will work */
    color: transparent; /* hide the base character */
    overflow:hidden;
    white-space: pre; /* to preserve the spaces from collapsing */
}
.halfStyle:before { /* creates the left part */
    display:block;
    z-index:1;
    position:absolute;
    top:0;
    width: 50%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow:hidden;
    pointer-events: none; /* so the base char is selectable by mouse */
    color: #f00; /* for demo purposes */
    text-shadow: 2px -2px 0px #af0; /* for demo purposes */
}
.halfStyle:after { /* creates the right part */
    display:block;
    direction: rtl; /* very important, will make the width to start from right */
    position:absolute;
    z-index:2;
    top:0;
    left:50%;
    width: 50%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow:hidden;
    pointer-events: none; /* so the base char is selectable by mouse */
    color: #000; /* for demo purposes */
    text-shadow: 2px 2px 0px #0af; /* for demo purposes */
}


讨论

页面出现异常的原因可能很多并且不尽相同。不同浏览器对规范的实现存在差异是普遍存在的现象。相比于编写一个疯狂的浏览器 bug 目录,解决问题的最有效流程还是始终保持条理性。总结来看有效的措施包括:

  • 评估 bug,执行快速修复
  • 使用最少的代码重现问题
  • 利用工具和 bug 追踪描述原因
  • 使用更灵活的代码修复问题,或者使用注释过的hack手段,亦或拷贝副本修复

    1 赞 3 收藏 评论

图片 35

消灭尾行者

现在我们终于明白通过display:inline-block进行元素的水平排版时,为啥会有个讨人厌的跟屁虫了,那剩下的工作当然是去而快之啦。首先这个跟屁虫实质上就是white-space字符串,而我们一般会输入的就是ASCII space( )ASCII tab( )和让HTML Markup更可读的line breakscarriage return( )line feed( )
那么消灭尾行者的方式就只有两个方向:1. 从根本上消除white-space字符串;2. 视觉效果上消除white-space字符串的影响。

第三部分:混合-匹配和改进

现在我们知道什么是可能的,让我们来添加一些花样。


牺牲HTML Markup可读性

牺牲前

XHTML

<span>one</span> <span>two</span> <span>three</span>

1
2
3
<span>one</span>
<span>two</span>
<span>three</span>

牺牲后1:一行搞定(一大坨代码,会斗鸡眼的。。。)

XHTML

<span>one</span><span>two</span><span>three</span>

1
<span>one</span><span>two</span><span>three</span>

牺牲后2:注释衔接(通过JS获取子元素数会有问题)

XHTML

<span>one</span><!-- --><span>two</span><!-- --><span>three</span>

1
2
3
<span>one</span><!--
--><span>two</span><!--
--><span>three</span>

牺牲后3

XHTML

<span>one</span ><span>two</span ><span>three</span>

1
2
3
<span>one</span
><span>two</span
><span>three</span>

然后@一丝姐说为展现效果牺牲结构是耍流氓,@HAX说这是”削足适履”。虽说这方法从根本上清除了white-space字符串,但那种丑不是一般人能接受的。

-水平一半

图片 36

Demo

JavaScript

.halfStyle { position:relative; display:inline-block; font-size:80px; /* or any font size will work */ color: transparent; /* hide the base character */ overflow:hidden; white-space: pre; /* to preserve the spaces from collapsing */ } .halfStyle:before { /* creates the top part */ display:block; z-index:2; position:absolute; top:0; height: 50%; content: attr(data-content); /* dynamic content for the pseudo element */ overflow:hidden; pointer-events: none; /* so the base char is selectable by mouse */ color: #f00; /* for demo purposes */ text-shadow: 2px -2px 0px #af0; /* for demo purposes */ } .halfStyle:after { /* creates the bottom part */ display:block; position:absolute; z-index:1; top:0; height: 100%; content: attr(data-content); /* dynamic content for the pseudo element */ overflow:hidden; pointer-events: none; /* so the base char is selectable by mouse */ color: #000; /* for demo purposes */ text-shadow: 2px 2px 0px #0af; /* for demo purposes */ }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
.halfStyle {
    position:relative;
    display:inline-block;
    font-size:80px; /* or any font size will work */
    color: transparent; /* hide the base character */
    overflow:hidden;
    white-space: pre; /* to preserve the spaces from collapsing */
}
.halfStyle:before { /* creates the top part */
    display:block;
    z-index:2;
    position:absolute;
    top:0;
    height: 50%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow:hidden;
    pointer-events: none; /* so the base char is selectable by mouse */
    color: #f00; /* for demo purposes */
    text-shadow: 2px -2px 0px #af0; /* for demo purposes */
}
.halfStyle:after { /* creates the bottom part */
    display:block;
    position:absolute;
    z-index:1;
    top:0;
    height: 100%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow:hidden;
    pointer-events: none; /* so the base char is selectable by mouse */
    color: #000; /* for demo purposes */
    text-shadow: 2px 2px 0px #0af; /* for demo purposes */
}


font-size:0大法

这种方式存在兼容性的问题,而且子元素需要重新设置font-size以保证后续采用em设置属性值正确有效这个就是一个巨蛋疼的事了。

-垂直1/3

图片 37

Demo

JavaScript

.halfStyle { /* base char and also the right 1/3 */ position:relative; display:inline-block; font-size:80px; /* or any font size will work */ color: transparent; /* hide the base character */ overflow:hidden; white-space: pre; /* to preserve the spaces from collapsing */ color: #f0f; /* for demo purposes */ text-shadow: 2px 2px 0px #0af; /* for demo purposes */ } .halfStyle:before { /* creates the left 1/3 */ display:block; z-index:2; position:absolute; top:0; width: 33.33%; content: attr(data-content); /* dynamic content for the pseudo element */ overflow:hidden; pointer-events: none; /* so the base char is selectable by mouse */ color: #f00; /* for demo purposes */ text-shadow: 2px -2px 0px #af0; /* for demo purposes */ } .halfStyle:after { /* creates the middle 1/3 */ display:block; z-index:1; position:absolute; top:0; width: 66.66%; content: attr(data-content); /* dynamic content for the pseudo element */ overflow:hidden; pointer-events: none; /* so the base char is selectable by mouse */ color: #000; /* for demo purposes */ text-shadow: 2px 2px 0px #af0; /* for demo purposes */ }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
.halfStyle { /* base char and also the right 1/3 */
    position:relative;
    display:inline-block;
    font-size:80px; /* or any font size will work */
    color: transparent; /* hide the base character */
    overflow:hidden;
    white-space: pre; /* to preserve the spaces from collapsing */
    color: #f0f; /* for demo purposes */
    text-shadow: 2px 2px 0px #0af; /* for demo purposes */
}
.halfStyle:before { /* creates the left 1/3 */
    display:block;
    z-index:2;
    position:absolute;
    top:0;
    width: 33.33%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow:hidden;
    pointer-events: none; /* so the base char is selectable by mouse */
    color: #f00; /* for demo purposes */
    text-shadow: 2px -2px 0px #af0; /* for demo purposes */
}
.halfStyle:after { /* creates the middle 1/3 */
    display:block;
    z-index:1;
    position:absolute;
    top:0;
    width: 66.66%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow:hidden;
    pointer-events: none; /* so the base char is selectable by mouse */
    color: #000; /* for demo purposes */
    text-shadow: 2px 2px 0px #af0; /* for demo purposes */
}


负margin-right法

原理是通过负margin-right将white-space字符收入盒子后方,而margin-right的属性值需要根据font-size来决定,必须恰恰等于字形宽度的负数,否则会出现元素重叠的问题。(IE5.5/6/7不兼容这玩法)

-水平 1/3

图片 38

Demo

JavaScript

.halfStyle { /* base char and also the bottom 1/3 */ position:relative; display:inline-block; font-size:80px; /* or any font size will work */ color: transparent; overflow:hidden; white-space: pre; /* to preserve the spaces from collapsing */ color: #f0f; text-shadow: 2px 2px 0px #0af; /* for demo purposes */ } .halfStyle:before { /* creates the top 1/3 */ display:block; z-index:2; position:absolute; top:0; height: 33.33%; content: attr(data-content); /* dynamic content for the pseudo element */ overflow:hidden; pointer-events: none; /* so the base char is selectable by mouse */ color: #f00; /* for demo purposes */ text-shadow: 2px -2px 0px #fa0; /* for demo purposes */ } .halfStyle:after { /* creates the middle 1/3 */ display:block; position:absolute; z-index:1; top:0; height: 66.66%; content: attr(data-content); /* dynamic content for the pseudo element */ overflow:hidden; pointer-events: none; /* so the base char is selectable by mouse */ color: #000; /* for demo purposes */ text-shadow: 2px 2px 0px #af0; /* for demo purposes */ }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
.halfStyle { /* base char and also the bottom 1/3 */
    position:relative;
    display:inline-block;
    font-size:80px; /* or any font size will work */
    color: transparent;
    overflow:hidden;
    white-space: pre; /* to preserve the spaces from collapsing */
    color: #f0f;
    text-shadow: 2px 2px 0px #0af; /* for demo purposes */
}
.halfStyle:before { /* creates the top 1/3 */
    display:block;
    z-index:2;
    position:absolute;
    top:0;
    height: 33.33%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow:hidden;
    pointer-events: none; /* so the base char is selectable by mouse */
    color: #f00; /* for demo purposes */
    text-shadow: 2px -2px 0px #fa0; /* for demo purposes */
}
.halfStyle:after { /* creates the middle 1/3 */
    display:block;
    position:absolute;
    z-index:1;
    top:0;
    height: 66.66%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow:hidden;
    pointer-events: none; /* so the base char is selectable by mouse */
    color: #000; /* for demo purposes */
    text-shadow: 2px 2px 0px #af0; /* for demo purposes */
}


引入HTML预编译

引入如Jade等HTML模板引擎,开发和维护时采用可读性可维护性更高的语言,而浏览器运行时则采用效率更佳但可读性差甚至非人类友好的编码,然后通过如sourcemap来做映射。

但若仅仅为解决本文的问题而引入HTML模板引擎,是不是小题大造了呢?

-HalfStyle改进 @KevinGranger

图片 39

DEMO

JavaScript

body{ background-color: black; } .textToHalfStyle{ display:block; margin: 200px 0 0 0; text-align:center; } .halfStyle { font-family: 'Libre Baskerville', serif; position:relative; display:inline-block; width:1; font-size:70px; color: black; overflow:hidden; white-space: pre; text-shadow: 1px 2px 0 white; } .halfStyle:before { display:block; z-index:1; position:absolute; top:0; width: 50%; content: attr(data-content); /* dynamic content for the pseudo element */ overflow:hidden; color: white; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
body{
    background-color: black;
}
 
.textToHalfStyle{
    display:block;
    margin: 200px 0 0 0;
    text-align:center;
}
 
.halfStyle {
    font-family: 'Libre Baskerville', serif;
    position:relative;
    display:inline-block;
    width:1;
    font-size:70px;
    color: black;
    overflow:hidden;
    white-space: pre;
    text-shadow: 1px 2px 0 white;
}
.halfStyle:before {
    display:block;
    z-index:1;
    position:absolute;
    top:0;
    width: 50%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow:hidden;
    color: white;
}


用float啦!

既然上述方式皆不爽,而你又熟知float的使用和注意事项,那直接换成float就好了。float的内容可参考《CSS魔法堂:说说Float那个被埋没的志向》

 -PeelingStyle 改进的 HalfStyle @SamTremaine

图片 40

总结

原来display:inline-block受委屈的这么多年,现在总算沉冤得雪了!都怪CSS2没有专门的布局模块,逼得我们东拼西凑地拼页面。所幸的是CSS3专设了Flexbox/Grid/Multi-columns Layout Modules,我们可以寄望更美好的将来了!

Demo and on samtremaine.co.uk

演示 和 samtremaine.co.uk

JavaScript

.halfStyle { position: relative; display: inline-block; font-size: 68px; color: rgba(0, 0, 0, 0.8); overflow: hidden; white-space: pre; transform: rotate(4deg); text-shadow: 2px 1px 3px rgba(0, 0, 0, 0.3); } .halfStyle:before { /* creates the left part */ display: block; z-index: 1; position: absolute; top: -0.5px; left: -3px; width: 100%; content: attr(data-content); overflow: hidden; pointer-events: none; color: #FFF; transform: rotate(-4deg); text-shadow: 0px 0px 1px #000; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.halfStyle {
    position: relative;
    display: inline-block;
    font-size: 68px;
    color: rgba(0, 0, 0, 0.8);
    overflow: hidden;
    white-space: pre;
    transform: rotate(4deg);
    text-shadow: 2px 1px 3px rgba(0, 0, 0, 0.3);
}
.halfStyle:before { /* creates the left part */
    display: block;
    z-index: 1;
    position: absolute;
    top: -0.5px;
    left: -3px;
    width: 100%;
    content: attr(data-content);
    overflow: hidden;
    pointer-events: none;
    color: #FFF;
    transform: rotate(-4deg);
    text-shadow: 0px 0px 1px #000;
}


感谢

inline-block 前世今生
inline-block 未来
应不应该使用inline-block代替float
inline-block元素间间隙产生及去除详解
有哪些好方法能处理 display: inline-block 元素之间出现的空格?
Fighting the Space Between Inline Block Elements
拜拜了,浮动布局-基于display:inline-block的列表布局
9.1 White space
9.3.2 Controlling line breaks

打赏支持我写出更多好文章,谢谢!

打赏作者

第四部分:准备生产

定制不同的Half-Style样式集可以用在同一个页面的所需元素上。你可以定义多个样式集并告诉插件要用哪一个。

插件在目标.textToHalfStyle元素上使用data属性data-halfstyle=”[-CustomClassName-]”,所有都会自动改变。

所以,只要含有文本的元素添加了textToHalfStyle class和data属性 data-halfstyle="[-CustomClassName-]",插件将完成剩下的工作。

图片 41

相同页面中多个Half-Styles的 演示

JavaScript

jQuery(function($) { var halfstyle_text, halfstyle_chars, $halfstyle_el, halfstyle_i, halfstyle_output, halfstyle_style; // Iterate over all class occurrences $('.textToHalfStyle').each(function(idx, halfstyle_el) { $halfstyle_el = $(halfstyle_el); halfstyle_style = $halfstyle_el.data('halfstyle'); halfstyle_text = $halfstyle_el.text(); halfstyle_chars = halfstyle_text.split(''); // Set the screen-reader text $halfstyle_el.html('<span style="position: absolute !important;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);">' + halfstyle_text + '</span>'); // Reset output for appending halfstyle_output = ''; // Iterate over all chars in the text for (halfstyle_i = 0; halfstyle_i < halfstyle_chars.length; halfstyle_i++) { // Create a styled element for each character and append to container halfstyle_output += '<span aria-hidden="true" data-content="' + halfstyle_chars[halfstyle_i] + '">' + halfstyle_chars[halfstyle_i] + '</span>'; } // Write to DOM only once $halfstyle_el.append(halfstyle_output); }); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
jQuery(function($) {
    var halfstyle_text, halfstyle_chars, $halfstyle_el, halfstyle_i, halfstyle_output, halfstyle_style;
 
    // Iterate over all class occurrences
    $('.textToHalfStyle').each(function(idx, halfstyle_el) {
        $halfstyle_el = $(halfstyle_el);
        halfstyle_style = $halfstyle_el.data('halfstyle');
        halfstyle_text = $halfstyle_el.text();
        halfstyle_chars = halfstyle_text.split('');
 
        // Set the screen-reader text
        $halfstyle_el.html('&lt;span style="position: absolute !important;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);"&gt;' + halfstyle_text + '&lt;/span&gt;');
 
        // Reset output for appending
        halfstyle_output = '';
 
        // Iterate over all chars in the text
        for (halfstyle_i = 0; halfstyle_i &lt; halfstyle_chars.length; halfstyle_i++) {
            // Create a styled element for each character and append to container
            halfstyle_output += '&lt;span aria-hidden="true" data-content="' + halfstyle_chars[halfstyle_i] + '"&gt;' + halfstyle_chars[halfstyle_i] + '&lt;/span&gt;';
        }
 
        // Write to DOM only once
        $halfstyle_el.append(halfstyle_output);
    });
});

此外,CSS样式集class的定义匹配上述的 [-CustomClassName-] 部分,并且链到.halfStyle,因此我们将有.halfStyle.[-CustomClassName-]

JavaScript

/* start half-style hs-base */ .halfStyle.hs-base { position:relative; display:inline-block; font-size:80px; /* or any font size will work */ overflow:hidden; white-space: pre; /* to preserve the spaces from collapsing */ color: #000; /* for demo purposes */ } .halfStyle.hs-base:before { display:block; z-index:1; position:absolute; top:0; width: 50%; content: attr(data-content); /* dynamic content for the pseudo element */ pointer-events: none; /* so the base char is selectable by mouse */ overflow:hidden; color: #f00; /* for demo purposes */ } /* end half-style hs-base */ /* start half-style hs-horizontal-third */ .halfStyle.hs-horizontal-third { /* base char and also the bottom 1/3 */ position:relative; display:inline-block; font-size:80px; /* or any font size will work */ color: transparent; overflow:hidden; white-space: pre; /* to preserve the spaces from collapsing */ color: #f0f; text-shadow: 2px 2px 0px #0af; /* for demo purposes */ } .halfStyle.hs-horizontal-third:before { /* creates the top 1/3 */ display:block; z-index:2; position:absolute; top:0; height: 33.33%; content: attr(data-content); /* dynamic content for the pseudo element */ overflow:hidden; pointer-events: none; /* so the base char is selectable by mouse */ color: #f00; /* for demo purposes */ text-shadow: 2px -2px 0px #fa0; /* for demo purposes */ } .halfStyle.hs-horizontal-third:after { /* creates the middle 1/3 */ display:block; position:absolute; z-index:1; top:0; height: 66.66%; content: attr(data-content); /* dynamic content for the pseudo element */ overflow:hidden; pointer-events: none; /* so the base char is selectable by mouse */ color: #000; /* for demo purposes */ text-shadow: 2px 2px 0px #af0; /* for demo purposes */ } /* end half-style hs-horizontal-third */ /* start half-style hs-PeelingStyle, by user SamTremaine on Stackoverflow.com */ .halfStyle.hs-PeelingStyle { position: relative; display: inline-block; font-size: 68px; color: rgba(0, 0, 0, 0.8); overflow: hidden; white-space: pre; transform: rotate(4deg); text-shadow: 2px 1px 3px rgba(0, 0, 0, 0.3); } .halfStyle.hs-PeelingStyle:before { /* creates the left part */ display: block; z-index: 1; position: absolute; top: -0.5px; left: -3px; width: 100%; content: attr(data-content); overflow: hidden; pointer-events: none; color: #FFF; transform: rotate(-4deg); text-shadow: 0px 0px 1px #000; } /* end half-style hs-PeelingStyle */ /* start half-style hs-KevinGranger, by user KevinGranger on StackOverflow.com*/ .textToHalfStyle.hs-KevinGranger { display:block; margin: 200px 0 0 0; text-align:center; } .halfStyle.hs-KevinGranger { font-family: 'Libre Baskerville', serif; position:relative; display:inline-block; width:1; font-size:70px; color: black; overflow:hidden; white-space: pre; text-shadow: 1px 2px 0 white; } .halfStyle.hs-KevinGranger:before { display:block; z-index:1; position:absolute; top:0; width: 50%; content: attr(data-content); /* dynamic content for the pseudo element */ overflow:hidden; color: white; } /* end half-style hs-KevinGranger

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/* start half-style hs-base */
.halfStyle.hs-base {
    position:relative;
    display:inline-block;
    font-size:80px; /* or any font size will work */
    overflow:hidden;
    white-space: pre; /* to preserve the spaces from collapsing */
    color: #000; /* for demo purposes */
}
.halfStyle.hs-base:before {
    display:block;
    z-index:1;
    position:absolute;
    top:0;
    width: 50%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    pointer-events: none; /* so the base char is selectable by mouse */
    overflow:hidden;
    color: #f00; /* for demo purposes */
}
/* end half-style hs-base */
 
/* start half-style hs-horizontal-third */
.halfStyle.hs-horizontal-third { /* base char and also the bottom 1/3 */
    position:relative;
    display:inline-block;
    font-size:80px; /* or any font size will work */
    color: transparent;
    overflow:hidden;
    white-space: pre; /* to preserve the spaces from collapsing */
    color: #f0f;
    text-shadow: 2px 2px 0px #0af; /* for demo purposes */
}
.halfStyle.hs-horizontal-third:before { /* creates the top 1/3 */
    display:block;
    z-index:2;
    position:absolute;
    top:0;
    height: 33.33%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow:hidden;
    pointer-events: none; /* so the base char is selectable by mouse */
    color: #f00; /* for demo purposes */
    text-shadow: 2px -2px 0px #fa0; /* for demo purposes */
}
.halfStyle.hs-horizontal-third:after { /* creates the middle 1/3 */
    display:block;
    position:absolute;
    z-index:1;
    top:0;
    height: 66.66%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow:hidden;
    pointer-events: none; /* so the base char is selectable by mouse */
    color: #000; /* for demo purposes */
    text-shadow: 2px 2px 0px #af0; /* for demo purposes */
}
/* end half-style hs-horizontal-third */
 
/* start half-style hs-PeelingStyle, by user SamTremaine on Stackoverflow.com */
.halfStyle.hs-PeelingStyle {
    position: relative;
    display: inline-block;
    font-size: 68px;
    color: rgba(0, 0, 0, 0.8);
    overflow: hidden;
    white-space: pre;
    transform: rotate(4deg);
    text-shadow: 2px 1px 3px rgba(0, 0, 0, 0.3);
}
.halfStyle.hs-PeelingStyle:before { /* creates the left part */
    display: block;
    z-index: 1;
    position: absolute;
    top: -0.5px;
    left: -3px;
    width: 100%;
    content: attr(data-content);
    overflow: hidden;
    pointer-events: none;
    color: #FFF;
    transform: rotate(-4deg);
    text-shadow: 0px 0px 1px #000;
}
/* end half-style hs-PeelingStyle */
 
/* start half-style hs-KevinGranger, by user KevinGranger on StackOverflow.com*/
.textToHalfStyle.hs-KevinGranger {
    display:block;
    margin: 200px 0 0 0;
    text-align:center;
}
 
.halfStyle.hs-KevinGranger {
    font-family: 'Libre Baskerville', serif;
    position:relative;
    display:inline-block;
    width:1;
    font-size:70px;
    color: black;
    overflow:hidden;
    white-space: pre;
    text-shadow: 1px 2px 0 white;
}
.halfStyle.hs-KevinGranger:before {
    display:block;
    z-index:1;
    position:absolute;
    top:0;
    width: 50%;
    content: attr(data-content); /* dynamic content for the pseudo element */
    overflow:hidden;
    color: white;
}
/* end half-style hs-KevinGranger

HTML:

JavaScript

<p> <span class="textToHalfStyle" data-halfstyle="hs-base">Half-style, please.</span> </p> <p> <span class="textToHalfStyle" data-halfstyle="hs-horizontal-third">Half-style, please.</span> </p> <p> <span class="textToHalfStyle" data-halfstyle="hs-PeelingStyle">Half-style, please.</span> </p> <p style="background-color:#000;"> <span class="textToHalfStyle" data-halfstyle="hs-KevinGranger">Half-style, please.</span> </p>

1
2
3
4
5
6
7
8
9
10
11
12
<p>
    <span class="textToHalfStyle" data-halfstyle="hs-base">Half-style, please.</span>
</p>
<p>
    <span class="textToHalfStyle" data-halfstyle="hs-horizontal-third">Half-style, please.</span>
</p>
<p>
    <span class="textToHalfStyle" data-halfstyle="hs-PeelingStyle">Half-style, please.</span>
</p>
<p style="background-color:#000;">
    <span class="textToHalfStyle" data-halfstyle="hs-KevinGranger">Half-style, please.</span>
</p>

相同页面中多个Half-Styles的 演示

赞 收藏 评论

打赏支持我写出更多好文章,谢谢!

任选一种支付方式

图片 42 图片 43

1 赞 4 收藏 评论

关于作者:Carman

图片 44

(新浪微博:@常见长剑) 个人主页 · 我的文章

图片 45

关于作者:^-^肥仔John

图片 46

偏前端的临栈工程师 个人主页 · 我的文章 · 5 ·    

图片 47

本文由金沙棋牌发布于金沙棋牌官方平台,转载请注明出处:是你不懂我,重新认识Box

关键词: