Auto-resizing skewed background in CSS (+ images?)

泪湿孤枕 提交于 2019-12-20 12:21:51

问题


I'm going to convert this PSD image to CSS. I've multiple h2s in multiple pages, so the inner text lenght and background-color may vary. Therefore the background should automatically adapt to "any" length.

So far, the markup is something like:

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

I may eventually wrap the inner text into a <span>, but keeping a semantic valid markup without any additional element would be ♥ly.

The inner text is rotated, but it's not mandatory. What i'm focusing on now is the skewed background.

I'm open-minded to any solution using scaled background pngs (eg. background-size:cover), pseudo-elements, canvas etc. But it must be modular.

Thanks a lot for any suggestion.


[update] A graphical example of what i'm looking for:


[important note] Behind the h2 there's an irregular pattern (not a "solid" color background)


回答1:


For anyone who's interested, here's my temporary solution: live demo.

I used this sprite image:

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>

(the .container div is only needed for variations)

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; }

Works on IE9+

Unfortunately, background-size property doesn't support an "inherit" value, so the actual sprite's height must be set in the css :-( I'm still looking for a more efficient solution.




回答2:


With the combination of CSS shapes, positioning, :before and :after selectors I've managed to make the container expandable to any content. However, this approach only works in modern browsers and it seems that there's no proper solution without js. Also, the use of svg could be really handful in this case but again you're limited to the browser compatibility.

Here is the demo using pure CSS: http://jsfiddle.net/qaWKX/

EDIT

The use of svg turned out to be useless without an extra JS function. So I dropped this approach. However, the only proper solution relies on CSS3 but without the use of :before and :after selectors. My previous approach was relying on creating pseudo elements that hide both sides of the h3 title. Hiding is not enough when there's no solid color for the background.

With this logic I needed to have a background that will combine transparency and solid fill. The answer was on CSS3 linear-gradient background.

In details: 1. I rotated the h3 title 2. I masked the top area with its container (top:-value or margin-top:-value) 3. I set 2 linear-gradient background images to each side

Here's the demo: http://jsfiddle.net/P5gLE/1/




回答3:


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>

and here is the css that makes the custom shape:

.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;
}



回答4:


I don't think it is possible to do with just the h2. The problem occurs with the different angles of the skewed sides, meaning you need a 'container' for the skewing and transforms.

Given your example, I came up with the following:

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

As you will see, this is has a couple of maintenance problems:

  • 'Magic Numbers' - these will need tweaking dependent on the skew + size you choose.
  • Font rendering with the transform is somewhat worse.

Otherwise, it seems to work. The best solution outside of using pseudo-elements and CSS3 is likely to stick with plain old images for the background of each menu item.




回答5:


What about using CSS shapes? I haven't worked with them a ton, but it seems like a good place to start.

http://css-tricks.com/examples/ShapesOfCSS/




回答6:


One easy solution I can think of is using 3 elements(I would use divs) for the three different bottom angles of the shape, having the left and right ones have a fixed size and the middle one simply scale with the text(headline) contained in it. Maybe not the most elegant solution, but it would definitely work. A downside is that you need a lot of images, especially if you want to have different coloured shapes. (I know of no way to colour a background image).

Though, if the space around the shape has a solid background colour, you could actually set the background colour of the 3 elements to the colour you want and have the actual images you use have the same colour as the background as negative space, being transparent where you want the actual shape.

Also, if you really do not want more elements than you need to, you can always use the :after and :before selectors to fake it.




回答7:


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

The above code will make IE 5.5 through 8 run like a modern compliant browser, as far as styling/functionality in the page is concerned. This script is specifically made to address CSS/rendering errors in past versions of IE.

Here is documentation on the script: http://www.charlescooke.me.uk/web/lab_notes/ie7_script.html

This is kind of an "IE Fallback", but a better way to approach the issue. Instead of making a ton of versions of the content to render the exact same way using different browsers, this simply forces modern compatibility upon early versions of IE.

I've used this script in the past to fix similar CSS rendering errors. This specific script above is to update IE5.5-8 up to 9. If you deliberately wish to upgrade IE5.5-7 up to 8 (no idea why you'd need to, but if you so desire), additional scripts at the URL below can do this.

Here is Google's page and into docs on it (includes the link above on this page as well) http://code.google.com/p/ie7-js/



来源:https://stackoverflow.com/questions/14714033/auto-resizing-skewed-background-in-css-images

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!