不知道大家有沒有注意到玫镐,微信里面倒戏,我們聊天的時(shí)候,發(fā)文字和發(fā)圖片的時(shí)候恐似,氣泡對(duì)話框樣式是有所不同的杜跷。有啥不同呢?且看下圖矫夷。
可以看到银萍,發(fā)圖片的時(shí)候惠勒,氣泡對(duì)話框箭頭的背景也是圖片的一部分帚稠。出于好奇和需求穆律,我試著嘗試實(shí)現(xiàn)這一樣式。實(shí)現(xiàn)是在移動(dòng)端下進(jìn)行的蔓彩。
用到的css屬性
background: inherit
: 表示繼承父級(jí)的背景屬性治笨,其中包括背景圖片驳概。
background-origin
: 規(guī)定 background-position 屬性相對(duì)于什么位置來定位。
background-clip
: 設(shè)置元素的背景(背景圖片或顏色)是否延伸到邊框下面旷赖。
方法一
原理是顺又,定義一個(gè)塊級(jí)元素,把圖片設(shè)置為塊級(jí)元素的背景圖片等孵,圖片位置左移20px稚照,然后使用偽元素,把三角形實(shí)現(xiàn)出來俯萌,同時(shí)繼承父級(jí)的背景圖片果录,border的寬度是20px,和上面的左移尺寸一樣咐熙,這樣圖片拼接才順暢弱恒。代碼如下:
<div class="dialog"></div>
<style>
.dialog {
position: relative;
width: 200px;
height: 200px;
border-radius: 10px;
margin-left: 40px;
background: url("card.png") -20px 0 no-repeat;
background-size: 220px auto;
}
.dialog:after {
content: '';
position: absolute;
top: 30px;
left: -40px;
border: solid #ccc;
border-width: 20px;
border-right-color: transparent;
background: inherit;
background-size: auto;
background-clip: border-box;
background-origin: border-box;
background-position: 20px -30px;
}
</style>
實(shí)現(xiàn)的效果圖是這樣的:
看起來還不錯(cuò),達(dá)到了預(yù)期效果棋恼。但是返弹,仔細(xì)看下代碼,里面的寬度和高度都是固定的爪飘,也就是說义起,不同的圖片,在這里顯示尺寸都是一樣的师崎,這個(gè)展示不太友好默终。
方法二
為了做到自適應(yīng),我選擇使用img來自動(dòng)控制大小犁罩。對(duì)img指定寬度穷蛹,然后高度自適應(yīng)。原理跟方法一有點(diǎn)類似昼汗。這里大家可以先思考下,如何做鬼雀。
實(shí)現(xiàn)的代碼如下:
<div class="dialog">
<div class="pic-wrap">
<img src="test.png" alt="">
</div>
</div>
<style>
.dialog {
position: relative;
width: 200px;
border-radius: 10px;
margin-left: 40px;
background-size: 2px 2px;
background: url(test.png) -9999px 0 no-repeat;
img{
width: 100%;
position: relative;
left: -20px;
bottom: 0;
top: 0;
border-radius: 10px;
display: block;
}
.pic-wrap{
overflow: hidden;
border-radius: 10px;
}
}
.dialog:after {
content: '';
position: absolute;
top: 30px;
left: -38px;
border: solid #ccc;
border-width: 10px 20px;
background: inherit;
border-right-color: transparent;
background-clip: border-box;
background-origin: border-box;
background-position: 20px -30px;
}
</style>
簡(jiǎn)單說下原理顷窒,三角形的做法還是跟方法一一樣,不同的是對(duì)話框內(nèi)圖片的處理源哩。這次采用了img標(biāo)簽鞋吉,并且在img外包了一層,以控制img的展示励烦。首先谓着,img先設(shè)置position:absolute
,然后坛掠,設(shè)置left: -20px
赊锚。然后外層設(shè)置寬度治筒,高度由圖片控制,設(shè)置overflow:hidden
舷蒲,裁剪掉多余的圖片部分耸袜。
實(shí)現(xiàn)的效果如下圖:
ok ,這次可以自適應(yīng)了牲平,但是圖片必須要固定寬度堤框,這個(gè)展示也不是那么好。最好是可以根據(jù)圖片的比例纵柿,來自動(dòng)設(shè)置寬度和高度蜈抓,于是就有了方法三。
方法三
在這個(gè)方法里面昂儒,我的想法是可以做到沟使,圖片的高寬可以按照?qǐng)D片的比例來進(jìn)行展示,而不是固定寬度和高度荆忍。這個(gè)也是可以實(shí)現(xiàn)的格带,但是需要使用javascript
來配合。
原理是這樣的:等圖片load完之后刹枉,拿到圖片的大小叽唱,然后對(duì)圖片的展示寬度按照一定的規(guī)則進(jìn)行計(jì)算,我這里是采用 (圖片的高度/屏幕的高度) * 圖片的高度 * 0.5
微宝。然后動(dòng)態(tài)設(shè)置dialog
的width
和background-size
棺亭。
實(shí)現(xiàn)的代碼如下:
<!-- html & css -->
<div class="dialog">
<div class="pic-wrap">
<img src="test.png" alt="">
</div>
</div>
<style>
.dialog {
position: relative;
border-radius: 10px;
margin-left: 40px;
background: url(test.png) -9999px 0 no-repeat;
img{
width: 100%;
position: relative;
left: -20px;
bottom: 0;
top: 0;
border-radius: 10px;
display: block;
}
.pic-wrap{
overflow: hidden;
border-radius: 10px;
}
}
.dialog:after {
content: '';
position: absolute;
top: 30px;
left: -38px;
border: solid #ccc;
border-width: 10px 20px;
background: inherit;
background-size: inherit;
border-right-color: transparent;
background-clip: border-box;
background-origin: border-box;
}
</style>
/** javascript **/
var dialog = (function(){
$('img').load(function(){
var img_real_height = parseInt($(this).height());
var win_height = parseInt(window.innerHeight);
var img_width = img_real_height / win_height * (img_real_height) * 0.5;
$(this).parents('.dialog').css(
{
'width': img_width,
backgroundSize: img_width+'px auto'
}
);
})
})()
但是這個(gè)方式也有缺點(diǎn),就是圖片的展示寬度很難用一個(gè)比較合理的公式去計(jì)算蟋软,如果你的圖片規(guī)格都是差不多的镶摘,那可以用這種方法,但是如果你的圖片規(guī)格多種岳守,就不建議用這種方式了凄敢。
方法四
在經(jīng)過一番思考之后,我決定再去仔細(xì)看看微信的處理方法湿痢。發(fā)現(xiàn)了一個(gè)規(guī)則:微信里面涝缝,如果圖片的高度大于寬度,則固定高度譬重,如果圖片的高度小于寬度拒逮,則固定寬度。
ok臀规,那我就來實(shí)現(xiàn)一番滩援。
<!-- html & css -->
<div class="dialog" style="background-image: url(../images/test1.jpg)">
<div class="pic-wrap">
<img src="../images/test1.jpg">
</div>
</div>
<style>
.dialog {
position: relative;
border-radius: 10px;
background-position: -9999px 0;
background-repeat: no-repeat;
margin-left: 10px;
img{
position: relative;
left: -20px;
border-radius: 10px;
display: block;
}
// 橫向
&.landscape {
height: auto;
background-size: px2rem(180px) auto;
img{
width: px2rem(180px);
}
}
// 豎向
&.vertical{
height: px2rem(180px);
background-size: auto px2rem(180px);
img{
height: px2rem(180px);
}
}
.pic-wrap{
overflow: hidden;
border-radius: 10px;
}
}
.dialog:after {
z-index: -2;
content: '';
position: absolute;
top: 10px;
left: -12px;
border: solid $bgGrey;
border-right-color: transparent;
border-width: 8px 6px;
background-image: inherit;
background-size: inherit;
background-repeat: no-repeat;
background-clip: border-box;
background-origin: border-box;
background-position: 0px -6px;
}
/** javascript **/
var dialog = (function(){
function loadImg() {
$('img').load(function(){
var img_real_height = parseInt($(this).height());
var img_real_width = parseInt($(this).width());
var max_width = '180px';
var max_height = '180px';
if(img_real_width / img_real_height > 1) {
// 橫向處理
$(this).parents('.dialog').addClass('landscape');
}else{
// 豎向處理
$(this).parents('.dialog').addClass('vertical');
}
})
}
loadImg();
})()
實(shí)現(xiàn)的效果如下:
補(bǔ)充
在上述獲取圖片大小的時(shí)候,我使用了load()
方法塔嬉,但是我發(fā)現(xiàn)這個(gè)方法不太靠譜玩徊,會(huì)偶爾出現(xiàn)獲取不到圖片尺寸的情況租悄。要解決這個(gè)情況,最好是通過后臺(tái)接口來取得圖片的尺寸佣赖,這樣會(huì)靠譜點(diǎn)恰矩。