响应式web布局中iframe的自适应

2016/07/13 · CSS ·
CSS,
响应式布局

本文作者: 伯乐在线 –
欲休
。未经作者许可,禁止转载!
欢迎加入伯乐在线 专栏作者。

如何用 CSS 实现多行文本的省略号显示

2017/03/31 · CSS ·
CSS

本文作者: 伯乐在线 –
欲休
。未经作者许可,禁止转载!
欢迎加入伯乐在线 专栏作者。

本文翻译自CSS Ellipsis: How to Manage Multi-Line Ellipsis in Pure
CSS,文中某些部分有些许改动,并添加译者的一些感想,请各位读者谅解。

合理的截断多行文本是件不容易的事情,我们通常采用几种方法解决:

  • overflow: hidden直接隐藏多余的文本
  • text-overflow: ellipsis只适用于单行文本的处理
  • 各种比较脆弱的javascript实现。之所以说这种实现比较脆弱是由于需要文本长度的变化时刻得到回流(relayout)后的布局信息,如宽度

英文原文写作时间是2012.9.18号,比较有意义的一天。不过作者忽略了WebKit提供的一个扩展属性-webkit-line-clamp,它并不是CSS规范中的属性。利用该属性实现多行文本的省略号显示需要配合其他三个属性:display: -webkit-box-webkit-box-orienttext-overflow: ellipsis;。其中,-webkit-line-clamp设置块元素包含的文本行数;display: -webkit-box设置块元素的布局为伸缩布局;-webkit-box-orient设置伸缩项的布局方向;text-overflow: ellipsis;则表示超出盒子的部分使用省略号表示。

不过本文将要介绍的方法是采用CSS规范中的属性,并结合特殊的实现技巧完成的。这意味着在实现CSS2.1规范的浏览器中都是可以兼容的,不将仅仅是纯粹的移动端领域,在传统的PC浏览器(你们懂得我指的是哪些浏览器)中仍是可行的。好吧,让我们一起见识下。

困境

在响应式布局中,我们应该小心对待iframe元素,iframe元素的width和height属性设置了其宽度和高度,但是当包含块的宽度或高度小于iframe的宽度或高度时,会出现iframe元素溢出的现象:

永利开户送38元体验金 1

这样溢出的iframe会破坏页面的布局。我们可以采用一种方法让iframe元素也具有响应性,拭目以待。

CSS实现多行文本溢出的省略号显示

我们把实现的细节划分为7个步骤,在这个实现过程中最简单的就是截断文本,而最难的部分则是让一个元素处在其父包含块溢出时的右下方,并且当父元素未溢出时该元素消失不可见。为了去难避易,我们先从比较简单的地方开始–当父包含框比较小时,将子元素布局到父包含框的右下角。

方案

iframe元素本身并无法伸缩,除非通过js显示的设置其宽度。但是我们可通过一个iframe-container元素来包裹iframe,同时让iframe-container元素的宽度充满包含块的宽度,并且根据iframe的长宽比,设置iframe-container元素的padding-bottom百分比。

其实,这种方式的精髓就在于设置iframe-container元素的padding-bottom属性,设置该属性的目的在于变相的设置元素的高度。因为给padding-bottom设置百分比,是相对于父元素的width而言的,如果对height属性设置百分比,则相对于父元素的height,而父元素的height值我们通常使用默认的auto,因此会出现子元素height也为0.因此,我们只能给padding-bottom设置属性。这样,只需让iframe元素充满iframe-container即可。

CSS

.wrap { width: 400px; margin: auto; border: 5px solid greenyellow; }
.iframe-container { height: 0; padding-bottom: 97.6%; position:
relative; } .iframe-container iframe { position: absolute; left: 0; top:
0; width: 100%; height: 100%; } @media screen and (max-width: 400px) {
.wrap { width: 300px; } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.wrap {
    width: 400px;
    margin: auto;
    border: 5px solid greenyellow;
}
.iframe-container {
    height: 0;
    padding-bottom: 97.6%;
    position: relative;
}
.iframe-container iframe {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
}
@media screen and (max-width: 400px) {
    .wrap {
        width: 300px;
    }
}

XHTML

<div class=”wrap”> <div class=”iframe-container”> <iframe
height=”498″ width=”510″
src=”” frameborder=”0″
allowfullscreen=””></iframe> </div> </div>

1
2
3
4
5
<div class="wrap">
    <div class="iframe-container">
        <iframe height="498" width="510" src="http://player.youku.com/embed/XOTE0MjkyODgw" frameborder="0" allowfullscreen=""></iframe>
    </div>
</div>

结果显示的状态:

当视口宽度大于400px时:

永利开户送38元体验金 2

当视口宽度小于400px时:

永利开户送38元体验金 3

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

打赏作者

1st 引子

永利开户送38元体验金 4
永利开户送38元体验金 5
其实这个实现完全利用了元素浮动的基本规则。在这里不详细讲解CSS2.1规范中的几种情形,不明白的读者自行查阅。这段代码实现很简单,就是三个子元素和包含块的高度及浮动设置:

JavaScript

<div class=”wrap”> <div
class=”prop”>1.prop<br>float:left</div> <div
class=”main”>2.main<br>float:right<br>Fairly short
text</div> <div
class=”end”>3.end<br>float:right</div> </div> .wrap
{ width: 400px; height: 200px; margin: 20px 20px 50px; border: 5px solid
#AAA; line-height: 25px; } .prop { float: left; width: 100px; height:
200px; background: #FAF; } .main { float: right; width: 300px;
background: #AFF; } .end { float: right; width: 100px; background:
#FFA; }

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
<div class="wrap">
  <div class="prop">1.prop<br>float:left</div>
  <div class="main">2.main<br>float:right<br>Fairly short text</div>
  <div class="end">3.end<br>float:right</div>
</div>
 
.wrap {
  width: 400px; height: 200px;
    margin: 20px 20px 50px;
    border: 5px solid #AAA;
    line-height: 25px;
}
 
.prop {
    float: left;
    width: 100px; height: 200px;
    background: #FAF; }
.main {
    float: right;
    width: 300px;
    background: #AFF; }
.end {
    float: right;
    width: 100px;
    background: #FFA; }

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

永利开户送38元体验金 6

1 赞 9 收藏
评论

2nd 模拟场景

我们通过创建一个子元素来替代将要显示的省略号,当文本溢出的情形下该元素显示在正确的位置上。在接下来的实现中,我们创建了一个realend元素,并利用上一节end元素浮动后的位置来实现realend元素的定位。

JavaScript

<div class=”wrap”> <div class=”prop”> 1.prop<br>
float:right</div> <div class=”main”> 2.main<br>
float:left<br> Fairly short text</div> <div
class=”end”> <div class=”realend”> 4.realend<br>
position:absolute</div> 3.end<br>float:right </div>
</div> .end { float: right; position: relative; width: 100px;
background: #FFA; } .realend { position: absolute; width: 100%; top:
-50px; left: 300px; background: #FAA; font-size: 13px; }

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
<div class="wrap">
  <div class="prop">
   1.prop<br>
   float:right</div>
  <div class="main">
   2.main<br>
   float:left<br>
   Fairly short text</div>
  <div class="end">
   <div class="realend">
     4.realend<br>
     position:absolute</div>
  3.end<br>float:right
  </div>
</div>
 
.end {
    float: right; position: relative;
    width: 100px;
    background: #FFA; }
.realend {
    position: absolute;
    width: 100%;
    top: -50px;
    left: 300px;
    background: #FAA; font-size: 13px; }

这一步中,我们主要关心的是realend元素的定位,基于浮动后的end元素设置偏移量,当end元素浮动到第一节第二章图的位置时(即在prop元素的下方),此时realend元素正好处在end元素的上方50px,右侧300px-100px=200px处,而该位置正是父包含框wrap元素的右下角,此时正是我们期待的结果:
永利开户送38元体验金 7

若父元素并没有溢出,那么realend元素会出现在其右侧
永利开户送38元体验金 8
这种情况解决很简单,请看下文之第七节,此处仅作实例说明。

关于作者:欲休

永利开户送38元体验金 9

前端自由人
个人主页 ·
我的文章 ·
1 ·
 

永利开户送38元体验金 10

3rd 优化定位模型

在第二节中,我们针对end元素设置了相对定位,对realend元素设置绝对定位。但是我们可以采用更为简单的代码来实现,即只使用相对定位。熟悉定位模型的同学应该知道,相对定位的元素仍然占据文本流,同时仍可针对元素设置偏移。这样,就可以去掉end元素,仅针对realend元素设置相对定位。

JavaScript

<div class=”wrap”> <div
class=”prop”>1.prop<br>float:right</div> <div
class=”main”>2.main<br>float:left<br>Fairly short
text</div> <div class=”realend”>
3.realend<br>position:relative</div> </div> .realend {
float: right; position: relative; width: 100px; top: -50px; left: 300px;
background: #FAA; font-size: 14px; }

1
2
3
4
5
6
7
8
9
10
11
12
13
<div class="wrap">
  <div class="prop">1.prop<br>float:right</div>
  <div class="main">2.main<br>float:left<br>Fairly short text</div>
  <div class="realend">
  3.realend<br>position:relative</div>
</div>
 
.realend {
    float: right;
        position: relative;
    width: 100px;
    top: -50px; left: 300px;
    background: #FAA; font-size: 14px; }

其他的属性并不改变,效果一样。

4th 削窄prop元素

目前,最左侧的prop元素的作用在于让realend元素在文本溢出时处在其正下方,在前几节的示例代码中为了直观的演示,设置prop元素的宽度为100px,那么现在为了更好的模拟实际的效果,我们缩小逐渐缩小prop元素的宽度。

JavaScript

<div class=”wrap”> <div
class=”prop”>1.prop<br>float:right</div> <div
class=”main”>2.main<br>float:left<br>Fairly short
text</div> <div class=”realend”>
3.realend<br>position:relative</div> </div> .prop {
float: left; width: 5px; height: 200px; background: #F0F; } .main {
float: right; width: 300px; margin-left: -5px; background: #AFF; }
.realend { float: right; position: relative; top: -50px; left: 300px;
width: 100px; margin-left: -100px; padding-right: 5px; background:
#永利开户送38元体验金,FAA; font-size: 14px; }

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
<div class="wrap">
  <div class="prop">1.prop<br>float:right</div>
  <div class="main">2.main<br>float:left<br>Fairly short text</div>
  <div class="realend">
  3.realend<br>position:relative</div>
</div>
 
 
.prop {
  float: left;
  width: 5px;
  height: 200px;
  background: #F0F; }
.main {
    float: right;
    width: 300px;
    margin-left: -5px;
    background: #AFF; }
.realend {
    float: right;
        position: relative;
    top: -50px;
        left: 300px;
    width: 100px;
        margin-left: -100px;
    padding-right: 5px;
    background: #FAA; font-size: 14px; }

针对prop元素,缩小宽度为5px,其余属性不变;

针对main元素,设置margin-left:5px,让main元素左移5px,这样main元素在宽度上就完全占满了父元素;

对于realend元素,top、left和width的值不变。而设置margin-left: -100pxpadding-right: 5px则是为了让realend元素的盒模型的最终宽度计算为5px。

BoxWidth = ChildMarginLeft + ChildBorderLeftWidth + ChildPaddingLeft +
ChildWidth + ChildPaddingLeft + ChildBorderRightWidth +
ChildMarginRightWidth;

1
BoxWidth = ChildMarginLeft + ChildBorderLeftWidth + ChildPaddingLeft + ChildWidth + ChildPaddingLeft + ChildBorderRightWidth + ChildMarginRightWidth;

具体可参考我之前的文章负margin的原理以及应用一文。

由于CSS规范规定padding的值不可以为负数,因此只有设置margind-left为负值,且等于其宽度。这样做的最终目的就是保证realend元素处在prop元素的下方,保证在文本溢出的情况下定位准确性:
永利开户送38元体验金 11

5th 继续优化:流式布局+伪元素

目前,realend元素的相关属性仍采用px度量,为了更好的扩展性,可以改用%替代。

同时,prop元素和realend元素可以采用伪元素来实现,减少额外标签的使用。

JavaScript

<div class=”ellipsis”>
<div>2.main<br>float:left<br>Fairly short text
</div> </div> /*相当于之前的prop元素*/ .ellipsis:before {
content: “”; float: left; width: 5px; height: 200px; background: #F0F;
} /*相当于之前的main元素*/ .ellipsis > *:first-child { float:
right; width: 100%; margin-left: -5px; background: #AFF; }
/*相当于之前的realend元素*/ .ellipsis:after { content: “realend”;
float: right; position: relative; top: -25px; left: 100%; width: 100px;
margin-left: -100px; padding-right: 5px; background: #FAA; font-size:
14px; }

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
<div class="ellipsis">
  <div>2.main<br>float:left<br>Fairly short text
  </div>
</div>
 
/*相当于之前的prop元素*/
.ellipsis:before {
    content: "";
    float: left;
    width: 5px; height: 200px;
    background: #F0F; }
/*相当于之前的main元素*/
.ellipsis > *:first-child {
    float: right;
    width: 100%;
    margin-left: -5px;
    background: #AFF; }
/*相当于之前的realend元素*/
.ellipsis:after {
    content: "realend";
    float: right; position: relative;
    top: -25px; left: 100%;
    width: 100px; margin-left: -100px;
    padding-right: 5px;
    background: #FAA; font-size: 14px; }

效果图和上节一样。

6th 隐藏

之前的实现中在文本未溢出的情况下,realend元素会出现在父元素的右侧,正如永利开户送38元体验金 8。解决此问题很简单,急需要设置:

.ellipsis{ overflow:hidden; }

1
2
3
.ellipsis{
  overflow:hidden;
}

即可解决问题。

7th 大功告成

现在我们离完结就差一步了,即去掉各元素的背景色,并且用“…”替换文本。最后为了优化体验,采用渐变来隐藏“…”覆盖的文本,并设置了一些兼容性的属性。

到了此处,相信现在关心的只是CSS的代码了:

CSS

.ellipsis { overflow: hidden; height: 200px; line-height: 25px; margin:
20px; border: 5px solid #AAA; } .ellipsis:before { content:””; float:
left; width: 5px; height: 200px; } .ellipsis > *:first-child {
float: right; width: 100%; margin-left: -5px; } .ellipsis:after {
content: “\02026”; box-sizing: content-box; -webkit-box-sizing:
content-box; -moz-box-sizing: content-box; float: right; position:
relative; top: -25px; left: 100%; width: 3em; margin-left: -3em;
padding-right: 5px; text-align: right; background-size: 100% 100%; /*
512×1 image, gradient for IE9. Transparent at 0% -> white at 50%
-> white at 100%.*/ background-image:
url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAABCAMAAACfZeZEAAAABGdBTUEAALGPC/xhBQAAAwBQTFRF////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wDWRdwAAAP90Uk5TgsRjMZXhS30YrvDUP3Emow1YibnM9+ggOZxrBtpRRo94gxItwLOoX/vsHdA2yGgL8+TdKUK8VFufmHSGgAQWJNc9tk+rb5KMCA8aM0iwpWV6dwP9+fXuFerm3yMs0jDOysY8wr5FTldeoWKabgEJ8RATG+IeIdsn2NUqLjQ3OgBDumC3SbRMsVKsValZplydZpZpbJOQco2KdYeEe36BDAL8/vgHBfr2CvTyDu8R7esU6RcZ5ecc4+Af3iLcJSjZ1ivT0S/PMs3LNck4x8U7wz7Bv0G9RLtHuEq1TbJQr1OtVqqnWqRdoqBhnmSbZ5mXapRtcJGOc4t2eYiFfH9AS7qYlgAAARlJREFUKM9jqK9fEGS7VNrDI2+F/nyB1Z4Fa5UKN4TbbeLY7FW0Tatkp3jp7mj7vXzl+4yrDsYoVx+JYz7mXXNSp/a0RN25JMcLPP8umzRcTZW77tNyk63tdprzXdmO+2ZdD9MFe56Y9z3LUG96mcX02n/CW71JH6Qmf8px/cw77ZvVzB+BCj8D5vxhn/vXZh6D4uzf1rN+Cc347j79q/zUL25TPrJMfG/5LvuNZP8rixeZz/mf+vU+Vut+5NL5gPOeb/sd1dZbTs03hBuvmV5JuaRyMfk849nEM7qnEk6IHI8/qn049hB35QGHiv0yZXuMdkXtYC3ebrglcqvYxoj1muvC1nDlrzJYGbpcdHHIMo2FwYv+j3QAAOBSfkZYITwUAAAAAElFTkSuQmCC);
background: -webkit-gradient(linear, left top, right top, from(rgba(255,
255, 255, 0)), to(white), color-stop(50%, white)); background:
-moz-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%,
white); background: -o-linear-gradient(to right, rgba(255, 255, 255, 0),
white 50%, white); background: -ms-linear-gradient(to right, rgba(255,
255, 255, 0), white 50%, white); background: linear-gradient(to right,
rgba(255, 255, 255, 0), white 50%, 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
32
33
34
35
36
37
38
39
40
41
42
43
.ellipsis {
  overflow: hidden;
  height: 200px;
    line-height: 25px;
    margin: 20px;
    border: 5px solid #AAA; }
 
.ellipsis:before {
    content:"";
    float: left;
    width: 5px; height: 200px; }
 
.ellipsis > *:first-child {
    float: right;
    width: 100%;
    margin-left: -5px; }        
 
.ellipsis:after {
    content: "\02026";  
 
    box-sizing: content-box;
    -webkit-box-sizing: content-box;
    -moz-box-sizing: content-box;
 
    float: right; position: relative;
    top: -25px; left: 100%;
    width: 3em; margin-left: -3em;
    padding-right: 5px;
    
    text-align: right;
 
  
        background-size: 100% 100%;
  /* 512×1 image, gradient for IE9. Transparent at 0% -> white at 50% -> white at 100%.*/
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgAAAAABCAMAAACfZeZEAAAABGdBTUEAALGPC/xhBQAAAwBQTFRF////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wDWRdwAAAP90Uk5TgsRjMZXhS30YrvDUP3Emow1YibnM9+ggOZxrBtpRRo94gxItwLOoX/vsHdA2yGgL8+TdKUK8VFufmHSGgAQWJNc9tk+rb5KMCA8aM0iwpWV6dwP9+fXuFerm3yMs0jDOysY8wr5FTldeoWKabgEJ8RATG+IeIdsn2NUqLjQ3OgBDumC3SbRMsVKsValZplydZpZpbJOQco2KdYeEe36BDAL8/vgHBfr2CvTyDu8R7esU6RcZ5ecc4+Af3iLcJSjZ1ivT0S/PMs3LNck4x8U7wz7Bv0G9RLtHuEq1TbJQr1OtVqqnWqRdoqBhnmSbZ5mXapRtcJGOc4t2eYiFfH9AS7qYlgAAARlJREFUKM9jqK9fEGS7VNrDI2+F/nyB1Z4Fa5UKN4TbbeLY7FW0Tatkp3jp7mj7vXzl+4yrDsYoVx+JYz7mXXNSp/a0RN25JMcLPP8umzRcTZW77tNyk63tdprzXdmO+2ZdD9MFe56Y9z3LUG96mcX02n/CW71JH6Qmf8px/cw77ZvVzB+BCj8D5vxhn/vXZh6D4uzf1rN+Cc347j79q/zUL25TPrJMfG/5LvuNZP8rixeZz/mf+vU+Vut+5NL5gPOeb/sd1dZbTs03hBuvmV5JuaRyMfk849nEM7qnEk6IHI8/qn049hB35QGHiv0yZXuMdkXtYC3ebrglcqvYxoj1muvC1nDlrzJYGbpcdHHIMo2FwYv+j3QAAOBSfkZYITwUAAAAAElFTkSuQmCC);
  
    background: -webkit-gradient(linear, left top, right top,
        from(rgba(255, 255, 255, 0)), to(white), color-stop(50%, white));
    background: -moz-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);          
    background: -o-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
    background: -ms-linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
    background: linear-gradient(to right, rgba(255, 255, 255, 0), white 50%, white);
}

永利开户送38元体验金 13

总结之兼容性

从上文的实现细节来看,我们利用的技巧完全是CSS规范中的浮动+定位+盒模型宽度计算,唯一存在兼容性问题的在于无关痛痒的渐变实现,因此可以在大多数浏览器下进行尝试。

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

打赏作者

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

永利开户送38元体验金 14

1 赞 3 收藏
评论

关于作者:欲休

永利开户送38元体验金 15

前端自由人
个人主页 ·
我的文章 ·
1 ·
 

永利开户送38元体验金 10

相关文章