Creating an irregular border with CSS overlapping colours - image

How would you go about creating an irregular border with variable colours like the one in the screenshot?
I considered creating a border image in a graphics editor and then using border-image property as described in the docs.
However, this technique would not allow me to achieve the effect of multiple background colours (grey and white in the screenshot) entering the border "waves".
Another solution would be to just produce the whole background white and grey in say Photoshop, and the just use it on the website. I really wanted to avoid this for performance reasons, and would prefer to just produce a grey, checked pattern fragment and repeat it.
Moreover, as you can see in the screenshot, the dark fragment is an image from a carousel - the images will all come in different colours so applying a border-image to the carousel container is not a solution either.
I would appreciate some advice. Thanks.

Using SVG:
You can do this using SVG. I would say it is pretty complex because the approach uses patterns for the repeating circles, a mask with the pattern as its fill to produce the transparent cuts. This mask is then applied to the image to produce the full effect. This in my opinion is the closest to what you want and also has good browser support. It works fine in IE10+, Edge, Firefox, Chrome, Opera and Safari.
There are a couple of points to note though - (1) You would have to somehow get your carousel work with SVG image because otherwise mask will have no effect (2) the radius of circles change as the width of the container change and so you'd either have to use a fixed size container (or) assign width of the container to the viewBox attribute using JS (or find some setting to prevent the radius change from happening, I don't know of any) .
.masked {
position: relative;
height: 175px;
width: 100%;
background: linear-gradient(60deg, #EEE 35%, white 35.5%), linear-gradient(300deg, #EEE 35%, white 35.5%);
background-size: 51% 100%;
background-repeat: no-repeat;
background-position: 0% 0%, 100% 0%;
padding-top: 100px;
}
.masked svg {
position: absolute;
top: 0px;
left: 0px;
height: 100px;
width: 100%;
}
path {
fill: #fff;
}
image {
mask: url("#mask");
}
<div class='masked'>
<svg viewBox='0 0 1200 100' preserveAspectRatio='none'>
<defs>
<pattern id="circles" patternUnits="userSpaceOnUse" width="10" height="100">
<path d="M0,0 L10,0 10,95 A5,5 0 0,0 0,95 L0,0" />
</pattern>
<mask id="mask">
<rect height="100%" width="100%" fill="url(#circles)" />
</mask>
</defs>
<image xlink:href='http://lorempixel.com/1200/100/nature/1' x="0" y="0" height="100%" width="100%" />
</svg>
Lorem Ipsum Dolor Sit Amet...
</div>
Using CSS:
This can be done using CSS masks but unfortunately the browser support for this feature is terrible. It is currently supported only in WebKit powered browsers. If other browsers need not be supported then this is a wonderful option. All that we need to do is create a radial gradient (that repeats in X axis) for the mask like in the below snippet, give it the required size and position it accordingly.
.masked {
position: relative;
height: 175px;
width: 100%;
background: linear-gradient(60deg, #EEE 35%, white 35.5%), linear-gradient(300deg, #EEE 35%, white 35.5%);
background-size: 51% 100%;
background-repeat: no-repeat;
background-position: 0% 0%, 100% 0%;
padding-top: 80px;
}
.masked:before {
position: absolute;
content: '';
top: 0px;
height: 80px;
width: 100%;
background: url(http://lorempixel.com/1000/100/nature/1);
-webkit-mask-image: linear-gradient(to bottom, black, black), radial-gradient(circle at 50% 100%, transparent 50%, black 55%);
-webkit-mask-size: 100% calc(100% - 12px), 12px 12px;
-webkit-mask-position: 0% 0%, 0px 68px;
-webkit-mask-repeat: repeat-x;
}
<div class="masked">Lorem Ipsum Dolor Sit Amet</div>

Related

Drawing a curved border-right in a box using CSS3

How can I draw a border-right in a box using CSS3 like in this image?
One possible solution would be this,
#curve{
margin:0 auto;
position:relative;
width:50px;
height:50px;
border-top:1px solid red;
border-right:1px solid red;
border-top-right-radius:50px;
float:left;
margin-left:50px;
}
#curve:after{
content: "";
position: absolute;
width: 50px;
height: 50px;
border-bottom: 1px solid red;
border-left: 1px solid red;
border-bottom-left-radius: 50px;
left: 50px;
top: 50px;
}
<div id="curve"></div>
SVG is much better option to create such kind of shapes. It is simple and scale able.
We can use SVG's path element to create this shape and fill it with some color, gradient or pattern.
Only one attribute d is used to define shapes in path element. This attribute itself contains a number of short commands and few parameters that are necessary for those commands to work.
Below is the necessary code to create this shape:
<path d="M10,10
L210,10
Q230,10 250,50
T290,90
L10,90
Z" />
I've used 5 commands inside path element. Below is a brief description:
M command is used to define the starting point. It appears at the beginning and specify the point from where drawing should start.
L command is used to draw straight lines.
Q command is used to draw curves.
T produces the same type of curve as earlier, but if it follows another Q command or a T command.
Z command is used to close the current path.
Output:
Working Example:
body {
background: linear-gradient(#466273, #5c8ea8) no-repeat;
min-height: 100vh;
margin: 0;
}
<svg width="300" height="100" viewBox="0 0 300 100">
<path d="M10,10 L210, 10 Q230,10 250,50 T290,90 L10,90 Z" stroke="#000" stroke-width="2" fill="yellowgreen" />
</svg>
Useful Resources:
SVG: Specs, MDN

CSS border/outline image over image

I have an image that needs a border-image over the image and not around it.
The border is an transparent png.
See here what happens if I use border:
You can see that the image holds a white background.
I would like to have the border to be over the image. After some Googleling I found outline. Here I can set a negative value. The problem here is that outline can't hold images......
I tried setting negative values on margin for the image and the border but that didn't help.
Anyone ideas?
Here is the code (not very interesting):
<div class="top_img">
<!-- some content -->
</div>
Here is the CSS:
<style>
background-image: url(the_image.jpg);
background-repeat: no-repeat;
background-attachment: scroll;
background-size: cover;
border: 20px solid transparent;
border-image: url(images/border_image.png) 30 round;
</style>

Rounded CSS border looks pixelated

I need some help to fix my rounded border. It looks so ugly. I want it more smooth, but I can't seem to fix it no matter what. I don't know what I am doing wrong.
Here is a picture of it:
Here is my HTML:
<div class="sidebar">
<!-- User avatar/message/notification/settings buttons -->
<div class="userpanel">
<div class="userpanel-image">
<img src="image.jpg">
</div>
<div class="userpanel-buttons">
<ul>
<li><span class="glyphicon glyphicon-envelope"></span></li>
<li><span class="glyphicon glyphicon-bell"></span></li>
<li><span class="glyphicon glyphicon-cog"></span></li>
</ul>
</div>
</div>
</div>
And here is my CSS:
.sidebar > .userpanel > .userpanel-image img {
border: 1px solid white;
border-radius: 25px;
margin: 3px;
margin-right: 25px;
}
This ultimately depends upon the pixel density of the monitor you are using.
Pixels per inch (PPI) or pixels per centimeter (PPCM) is a measurement of the pixel density (resolution) of an electronic image device, such as a computer monitor or television display, or image digitizing device such as a camera or image scanner. Horizontal and vertical density are usually the same, as most devices have square pixels, but differ on devices that have non-square pixels.
For example, a 15 inch (38 cm) display whose dimensions work out to 12 inches (30.48 cm) wide by 9 inches (22.86 cm) high, capable of a maximum 1024×768 (or XGA) pixel resolution, can display around 85 PPI in both the horizontal and vertical directions. This figure is determined by dividing the width (or height) of the display area in pixels by the width (or height) of the display area in inches. It is possible for a display to have different horizontal and vertical PPI measurements (e.g., a typical 4:3 ratio CRT monitor showing a 1280×1024 mode computer display at maximum size, which is a 5:4 ratio, not quite the same as 4:3). The apparent PPI of a monitor depends upon the screen resolution (that is, the number of pixels) and the size of the screen in use; a monitor in 800×600 mode has a lower PPI than does the same monitor in a 1024×768 or 1280×960 mode.
Monitors with a higher pixel density will tend to smooth curves much better visually.
There's really nothing you can generally do to improve the pixel density display via HTML/CSS or really, anything. You merely have to learn to live with the quality of your monitor or upgrade it.
In some cases, applying a slight 1px box-shadow the same color as your circle can assist in the monitor anti-aliasing. However, that's not 100% successful either.
You're definetly not doing anything wrong.
Maybe that just because the border is too thin. Try to change border: 1px solid white; to 2px, 3px, or whatever you like. Give it try.
For me this looks best:
.userpanel-image {
width: 100px;
height: 100px;
border-radius: 100%;
box-shadow: 0 0 1px 1px white;
overflow: hidden;
}
.userpanel-image img {
width: 98px;
height: 98px;
}
Unfortunately i had the same problem several times. I think this might be a render problem which cant be solved 100%. Maybe you can use the workaround i used for my "border-problem" to make it look sharper (I did not test it on every single browser so u might have to check that out)
body {background:black;}
div {
width:100px;
height:100px;
display:block;
background:#fff;
border-radius:100%;
padding:2px;
}
img {
display:block;
border-radius:100%;
display:block;
width:100px;
height:100px;
}
<div>
<img src="https://unsplash.it/100" alt="">
</div>
Usually when I'm faced with this problem, I just reduce the contrast of the colors to help ease the pixelated anti-aliasing (as I mentioned in my comment). This is not always an option however. The real problem you are facing is that the browser will apply a certain amount of anti-aliasing to prevent complete jaggedness and you don't really have control over the intensity of that anti-aliasing that's applied. Here's an alternative that you can use to help take control of the appearance. You can use box-shadow to supplement or replace your existing border:
body {
background: #223;
padding-bottom: 25px;
text-align: center;
color: white;
}
div {
margin-top: 25px;
}
img {
display:inline-block;
border-radius: 50%;
border: 1px solid white;
vertical-align: middle;
}
div + div img {
box-shadow: 0 0 1px 0 white;
}
div + div + div img {
box-shadow: 0 0 0 1px white;
border: none;
}
<div>border only: <img src="//placehold.it/50/933/FFF"></div>
<div>border + box-shadow: <img src="//placehold.it/50/933/FFF">
<div>box-shadow only: <img src="//placehold.it/50/933/FFF">

Is it possible to avoid blur when scaling down image with transform?

I have a background-image set on a div at 100%.
<div style="width: 990px; height: 742px; background-image: url('http://images.nationalgeographic.com/wpf/media-live/photos/000/913/cache/deadvlei-africa-namibia_91343_990x742.jpg'); background-size: 100%; background-repeat: no-repeat;"></div>
When I scale that image down by editing the width/height of the element, it retains its quality.
<div style="width: 247.5px; height: 185.5px; background-image: url('http://images.nationalgeographic.com/wpf/media-live/photos/000/913/cache/deadvlei-africa-namibia_91343_990x742.jpg'); background-size: 100%; background-repeat: no-repeat;"></div>
However, when I scale the image down using transform: scale, the image loses quality.
<div style="width: 990px; height: 742px; background-image: url('http://images.nationalgeographic.com/wpf/media-live/photos/000/913/cache/deadvlei-africa-namibia_91343_990x742.jpg'); background-size: 100%; background-repeat: no-repeat; transform: scale(.25);"></div>
Here is a demo of the results.
The image only seems to lose quality in webkit browsers. Chrome is worse than Safari.
Does anyone know why the image loses quality using transform: scale and if there is a way around it?
This question has been already asked. Simply set blur filter to 0.
Check -webkit-transform: scale / blurry images

Latest opera won't hide the overflow while using border-radius property

while using border-radius Opera won't actually hide the overflowing parts of elements. I already tried to apply things I managed to find in similar threads, such as defining the border style or paying attention to positioning with absolute and relative parameters. It is still not working though.
html
<div class="node">
<div class="skill skill1"></div>
<div class="skill skill2"></div>
<div class="skill skill3"></div>
<div class="skill skill4"></div>
</div>
css
.node {
position: relative;
width: 250px;
height: 250px;
opacity: 0.9;
border-radius: 50%;
overflow: hidden;
left: -60px;
border: solid 1px transparent;
}
.skill {
position: absolute;
top: 0;
left: 0;
width: 50%;
height: 50%;
transform-origin: 100% 100%;
-webkit-transform-origin: 100% 100%;
}
.skill1 {
background-color: #26ac79;
-webkit-transform: rotate(90deg) skewX(45deg);
transform: rotate(90deg) skewX(45deg);
}
.skill2 {
background-color: #25765f;
-webkit-transform: rotate(135deg) skewX(45deg);
transform: rotate(135deg) skewX(45deg);
}
.skill3 {
background-color: #25313f;
-webkit-transform: rotate(180deg) skewX(45deg);
transform: rotate(180deg) skewX(45deg);
}
.skill4 {
background-color: #25193d;
-webkit-transform: rotate(225deg) skewX(45deg);
transform: rotate(225deg) skewX(45deg);
}
Here's the fiddle:
http://jsfiddle.net/Mu9Ar/
Thanks for any help.
Actually the code you provided works in latest Opera with Blink engine, so I guess you can leave your code as is. However if you need it to work in versions up to 12.16 and your page background is white, what you can do is to put .png overlay over your chart which will clip the chart, just like webdevelopers did in old days when there were no border-radius:)
According to the W3 specification:
http://www.w3.org/TR/css3-background/#corner-clipping
A box's backgrounds, but not its border-image, are clipped to the
appropriate curve (as determined by ‘background-clip’). Other effects
that clip to the border or padding edge (such as ‘overflow’ other than
‘visible’) also must clip to the curve. The content of replaced
elements is always trimmed to the content edge curve.
It appears that Firefox implemented the spec correctly by clipping the content to the edge of the curve when using overflow: hidden.
However, Opera is not compliant on this detail.
As an aside, if you add border-radius property to an img element, the image will be clipped correctly.
At this moment, there is no work-around that I know of unless you try HTML5 canvas.

Resources