在CSS中自动调整倾斜的背景(包括图像)大小

12

我将把这个PSD图像转换成CSS。在多个页面中有多个h2,因此内部文本长度和背景颜色可能会有所不同。因此,背景应该自动适应“任何”长度。

倾斜背景演示

到目前为止,标记类似于:

<h2 class="sub-heading lab-heading">Laboratori</h2>

我可能最终会将内部文本包装到一个<span>中,但保持语义有效的标记而不添加任何额外元素会更好。

内部文本被旋转,但这并非强制性要求。我现在关注的是倾斜的背景。

我对使用缩放的背景PNG(例如background-size:cover)、伪元素、画布等任何解决方案都持开放态度。但它必须是模块化的。

非常感谢任何建议。


[更新] 我正在寻找的图形示例:

我不是图形演示


[重要说明] 在h2后面有一个不规则的图案(不是“实心”颜色背景)


对于一个好问题点个赞...我想不出来。CSS3形状不能完全完成工作,也不是你想要的样子。我有一种感觉,这将不得不在JavaScript中完成。 - Michael
你需要支持哪些浏览器? - dave
@dave IE9+,我会为IE8添加一个简单的备选方案。 - Giona
谢谢,但我不需要@dave的帮助,因为MiG的答案已经解决了我的问题。 - Giona
这可能是一个选项,关于同一主题,这篇博客文章解释了如何跨浏览器应用遮罩。但正如你所说,它仍然是实验性的,我不想添加太多额外的代码。 - Giona
显示剩余2条评论
7个回答

5

对于任何感兴趣的人,这是我的临时解决方案:演示

我使用了这个精灵图片:

倾斜背景精灵

html:

<div class="container">
<h2 class="sub-heading"><span class="sub-heading-txt">Short title</span></h2>
</div>
<div class="container">
<h2 class="sub-heading"><span class="sub-heading-txt">A bit longer title</span></h2>
</div>
<div class="container">
<h2 class="sub-heading"><span class="sub-heading-txt">A damn long title is here!</span></h2>
</div>

(.container div 仅用于变体)

CSS:

.sub-heading, .sub-heading:after, .sub-heading:before {
    background:url(tha-sprite-url.png) 0 0 no-repeat;
}

.sub-heading {
    position:relative;
    display:inline-block; clear:both;
    margin-left:31px; padding:0 18px 10px 0;
    font-size:25px; font-weight:normal; color:#FFF; line-height:47px;
    background-position:0 -75px;
    background-size:100% 282px; /* the sprite's height */
}

.sub-heading:before, .sub-heading:after { content:" "; position:absolute; top:0; }
.sub-heading:before { left:-31px; width:31px; height:57px; }
.sub-heading:after { right:-12px; width:12px; height:42px; background-position:-150px 0; }

.sub-heading-txt {
    display:block;
    -webkit-transform:rotate(-2deg); -ms-transform:rotate(-2deg); transform:rotate(-2deg);
}

/* variations */
.container { margin-bottom:10px; }
.container:nth-child(3n+2) .sub-heading { background-position:0 -150px; }
.container:nth-child(3n+2) .sub-heading:before { background-position:-50px 0; }
.container:nth-child(3n+2) .sub-heading:after { background-position:-175px 0; }
.container:nth-child(3n+3) .sub-heading { background-position:0 -225px; }
.container:nth-child(3n+3) .sub-heading:before { background-position:-100px 0; }
.container:nth-child(3n+3) .sub-heading:after { background-position:-200px 0; }

适用于IE9及以上版本

不幸的是,background-size属性不支持"inherit"值,所以实际精灵的高度必须在CSS中设置 :-( 我仍在寻找更有效的解决方案。


3
结合CSS形状、定位、:before和:after选择器,我成功地使容器可扩展到任何内容。但是,这种方法只适用于现代浏览器,并且似乎没有没有JS的正确解决方案。此外,在这种情况下使用svg可能非常方便,但是受限于浏览器兼容性。
这是使用纯CSS的演示:http://jsfiddle.net/qaWKX/ 编辑:
事实证明,使用svg是没有用的,需要额外的JS函数。所以我放弃了这种方法。然而,唯一正确的解决方案依赖于CSS3,但不使用:before和:after选择器。我的旧方法依赖于创建伪元素来隐藏h3标题的两侧。当背景没有实色时,仅靠隐藏还不够。
基于这个逻辑,我需要一个将透明度和实色填充结合起来的background。答案在CSS3 linear-gradient background中。
具体如下: 1. 我旋转了h3标题 2. 用其容器mask了顶部区域(top:-value或margin-top:-value) 3. 我将2个linear-gradient背景图像分别设置在每一侧
这是演示:http://jsfiddle.net/P5gLE/1/

太酷了!但是我不能使用白色边框,因为h2的背景是不规则的图案...另外,无需使用-moz-transform。 - Giona
我了解CSS解决方案的局限性,因此建议使用svg作为background-image,并将background-size设置为100%。您的svg尺寸越大,在调整大小时质量就会更好。而且不要忘记它是矢量图形,所以浏览器的svg引擎可以决定如何加载svg背景。这里有一个演示:http://jsfiddle.net/sSaBJ/1/注意:svg文件只有481字节! - otinanai
1
呵呵,谢谢,这正是我正在使用 PNG 图像(请查看我的答案,刚刚发布)来避免 SVG 的透明度问题。此外,我不得不剪切右侧和左侧以保留“斜度”。 - Giona
临时解决方案不错。每个解决方案(无论是你的还是我的)唯一的问题是背景颜色不能通过CSS进行编辑。 - otinanai
1
太棒了!为了避免白色中间线,只需设置 background-size: 51% 100%;。此外,我会选择使用 inline-block 而不是 display:tabletable-cell(在各种浏览器中更一致)。查看我对你的编辑的版本。不幸的是,ie9 不支持 css 渐变 :-( 无论如何,做得很好! - Giona
显示剩余4条评论

1

here is the html:

<br>
<div class="scewed-shape">
    <div class="text-align">here is a very long text adsadsad</div>
</div>
<br>
<br>
<div class="scewed-shape">
    <div class="text-align">this one is shorter</div>
</div>

这是创建自定义形状的 CSS 代码:

.scewed-shape {
    display:inline-block;
    -webkit-transform: perspective(500px) rotateY(34deg);
    -ms-transform: perspective(500px) rotateY(34deg);
    left: -25px;
    height: 0;
    border-style: solid;
    border-color: red transparent transparent transparent;
    border-width: 70px 50px 0 50px;
}
.scewed-shape .text-align {
    position: relative;
    top: -25px;
}

非常感谢您花时间编写这个插件,但我可以通过将 inline-block 设置为 .scewed-shape 而无需使用 JavaScript 来实现相同的效果... 演示。这是一个好的起点,但我的演示中形状更加复杂。哦,您只需要为 transform 添加 -webkit 和 -ms 前缀即可;-) - Giona
无论您的形状有多复杂,您都可以使用此JavaScript代码来调整宽度,然后一切都应该准备就绪。 - David Tolioupov
嗯,这确实是谜题的一部分。但我仍然需要用CSS构建该形状或调整/切割图像,以使形状本身自动调整。这就是问题的关键所在。 - Giona
形状完全没问题,非常感谢。但是使用这种方法后,文本也会变形,我使用的自定义字体也无法正常显示 :-( 无论如何,如果您将原始答案更改为新演示文稿,我会点赞的 ;-) - Giona
@Giona,我修改了原来的回答。 - David Tolioupov

1

我认为仅使用h2是不可能实现的。问题在于倾斜边缘的不同角度,这意味着您需要一个进行倾斜和变换的“容器”。

根据您的示例,我想到了以下内容:

http://jsfiddle.net/Cbx2q/1/

正如您所看到的,这里有一些维护问题:

  • 'Magic Numbers' - 这些数字需要根据您选择的偏移和大小进行微调。
  • 使用 transform 属性渲染字体效果较差。

除此之外,它似乎是有效的。在不使用伪元素和 CSS3 的情况下,最好的解决方案可能是为每个菜单项的背景坚持使用普通的图像。


这个想法本来很完美,但不幸的是我没有一个坚实的背景颜色,所以在我的情况下,带有伪元素的 #fff 三角形无法使用。不管怎样,做得很好,点赞! - Giona
@Giona 我没有注意到实心背景颜色的部分... 你最好是采用整个菜单的实心背景,然后为每个菜单项设置一个背景图像。倾斜的文本也意味着你可以使用图像中的文本来获得良好的IE支持。谢谢。 - Hux
这不是针对菜单项,而是针对文章中的子标题,这些子标题是通过CMS由不同的作者编写的。因此,我无法为每个新的子标题制作一张图片。文章背景是木质的不规则图案...也许我应该干掉Photoshop设计师;-) - Giona
我能想到的唯一替代方案是使用canvas或SVG(如果可能的话)来创建和显示背景,以及可能的文本。不确定这会对透明度产生什么影响。 - Hux
我几个月前用SVG做了一些测试案例,即使在现代浏览器中透明度也存在问题(叹气)。Canvas肯定是一个选择,但我真的不知道从哪里开始。 - Giona

0
<!--[if lt IE 9]>
<script src="http://ie7-js.googlecode.com/svn/version/2.1(beta4)/IE9.js"></script>
<![endif]-->

以上代码将使IE 5.5到8在页面的样式/功能方面运行得像现代兼容浏览器一样。此脚本专门用于解决过去版本的IE中的CSS/渲染错误。

以下是脚本的文档: http://www.charlescooke.me.uk/web/lab_notes/ie7_script.html

这有点像“IE回退”,但更好的方法来解决这个问题。不必为了使用不同的浏览器呈现完全相同的内容而制作大量版本,这只是强制早期版本的IE具有现代兼容性。

我曾经使用过这个脚本来修复类似的CSS渲染错误。上面的特定脚本是为了将IE5.5-8升级到9。如果您故意希望将IE5.5-7升级到8(不知道为什么需要,但如果您愿意),则可以在下面的URL中使用其他脚本来完成。

这是Google页面和相关文档(也包括上面的链接) http://code.google.com/p/ie7-js/


0

这就是我之前看过的,但这并不是一个非常理想的解决方案,定位文本可能会很困难。 - Michael
2
CSS形状使用边框来实现效果,由于边框宽度无法使用百分比设置,因此该技术在此用例中无法工作,因为不可能使它们按不同的文本长度进行缩放。 - Jeff-Meadows

0

我能想到的一个简单解决方案是使用三个元素(我会使用div)来表示形状的三个不同底角,左右两个元素具有固定大小,中间的元素只需根据其中包含的文本(标题)进行缩放。也许不是最优雅的解决方案,但肯定有效。一个缺点是你需要很多图片,特别是如果你想要不同颜色的形状。(我不知道如何给背景图片上色)。

不过,如果形状周围的空间有一个纯色背景,你实际上可以将3个元素的背景颜色设置为你想要的颜色,并且你使用的实际图像与背景颜色相同作为负空间,在你想要实际形状的地方是透明的。

此外,如果你真的不想使用比所需更多的元素,你总是可以使用:after和:before选择器来伪造它。


抱歉,我应该明确指出颜色变化将由第二个CSS类处理,每个h2都会有所不同。 不幸的是,容器的背景是一种不规则的纹理,因此我需要倾斜的背景是透明的。 您的想法可能是有效的,但我不确定“碎片”是否适合。感谢您的建议! - Giona

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接