I have that little css which draws a circle and fills it till half using backgrounds. Both containing div's have the same size but the lower one's background is still visible.
Shouldn't the div.bg cover the div.fill? So the upper half of the cirlce should be completely black? (there is a thin white line)
body {
background: black;
}
#asd {
height: 35px;
width: 35px;
border-radius: 35px;
overflow: hidden;
position: relative;
}
span {
color: red;
text-align: center;
font-size: 10px;
line-height: 35px;
position: absolute;
height: 100%;
width: 100%;
z-index: 3;
}
#asd div {
height: 100%;
width: 100%;
position: absolute;
}
div.bg {
background: white;
z-index: 1;
}
div.fill {
background: black;
height: 50% !important;
z-index: 2;
}
<div id="asd">
<span>lorem</span>
<div class="bg"></div>
<div class="fill"></div>
</div>
This is due to anti aliasing, and colour addition.
First, the browser paints a perfectly white circle:
The white circle is behind the black circle, and to make the edges look smooth, the edge pixels are blended slightly. This is called anti-aliasing or supersampling.
Now the background circle has been anti-aliased, we're left with a perfect white circle surrounded by a grey outline. The exact shade of grey is decided by the browser, but usually this decision is made by interpolating between the background and foreground colours. Let's assume this creates 50% black/white.
The next step is to create a black circle over the top of the white circle, and this will be anti-aliased in exactly the same way. This is where the problem occurs, as an incorrect assumption is made by the browser.
The black circle, exactly the same size as the white circle, is blended into the background to look smooth. Because there are already 50% black/white pixels surrounding the white circle, the black is added to these using the same algorithm, creating 25% black/white.
This is simply a limitation/design choice of the individual browsers, and some would argue that it is indeed correct behaviour. As you've found, or will find, in web design there are many ways to skin a cat, so my advice would be to look for an alternative solution rather than hack this exact problem.
General rule of thumb: try not to include extra markup to achieve visual style. One can usually achieve everything with just CSS. Keep in mind background gradients, pseudo-elements and borders and most visuals are in reach.
As a head start, I would not suggest using two div elements for this styling. Instead, I would use the background property of the white circle to describe the visual effect you are looking for.
Specifically: background: linear-gradient(to bottom, black 50%, white 50%);
body {
background: black;
}
#asd {
height: 35px;
width: 35px;
border-radius: 35px;
overflow: hidden;
position: relative;
}
span {
color: red;
text-align: center;
font-size: 10px;
line-height: 35px;
position: absolute;
height: 100%;
width: 100%;
z-index: 3;
}
#asd div {
height: 100%;
width: 100%;
position: absolute;
}
div.bg {
background: linear-gradient(to bottom, black 50%, white 50%);
z-index: 1;
}
<div id="asd">
<span>lorem</span>
<div class="bg"></div>
</div>
I think you're referring to the jagged edges around your circle, which I think is a rendering artifact caused anti-aliassing.
The border-radius on the elements get sharpened so-to-speak by anti-aliassing, which renders differently coloured pixels around the element to smoothen out hard edges (please correct me if this is wrong, I'm no expert on this). Normally this is behaviour is fine, but in your case it cases artifacts.
Have a look at my snippet below. The result is the same, but uses a background gradient to achieve it.
body {
background: black;
}
.circle {
width: 35px;
height: 35px;
line-height: 35px;
font-size: 11px;
border-radius: 50%;
color: red;
text-align: center;
background: linear-gradient(0deg, white 50%, black 50%);
}
<div class="circle">
lorem
</div>
Related
I'm seeking for some advice on creating a "ring" shape in CSS. Here's some important detailed goals I need to achieve:
the ring border thickness must be a percentage number, not rm or absolute pixel number, so that the ring shape can be fully responsive based on container size;
The ring border need to have a background, for my scenario, the background could be sometimes a combination of 3-4 solid colors, or a gradient color;
The filling of the ring must be transparent so user can see the background through it.
Here's a quick example:
Here are a few attempts I used:
Make a border-radius: 50% div with only border width but soon I noticed the border width cannot be a percentage number;
SVG clipping a round div to a ring shape. so far I was not able to successfully make it working... If this is the right approach, please share some snippet.
You can achieve this considering mask where the idea is to use a radial-gradient to create the hole and use fixed value which will make the visible part (the thickness) to be responsive.
.box {
border-radius:50%;
background:linear-gradient(red,purple,orange);
-webkit-mask: radial-gradient(transparent 89px,#000 90px);
mask: radial-gradient(transparent 89px,#000 90px);
}
.box:before {
content:"";
display:block;
padding-top:100%;
}
.container {
margin:0 auto;
max-width:200px;
animation:change 3s linear alternate infinite;
}
#keyframes change{
to {
max-width:400px;
}
}
body {
background:linear-gradient(to right,yellow,pink);
}
<div class="container">
<div class="box">
</div>
</div>
Making responsive rings in CSS is tough. The best I've found is to simply create two circles stacked on top of each other where the top circle's background is the same as the container background. You could do this with 2x elements like in my example or with a pseudo-class.
Pros:
You get lots of control
Easily add other content (like pie charts) since the content is "masked"
Cons:
Background needs to be a flat color and nothing will show through the ring
.outer {
width: 200px;
height: 200px;
border-radius: 50%;
position: relative;
background-color: #9273B0;
margin: 10px;
cursor:pointer;
}
.inner {
position: absolute;
width: 50%;
height: 50%;
border-radius: 50%;
background-color: #ffffff;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transition: all 0.5s ease-out;
}
.outer:hover .inner {
width: 90%;
height: 90%;
}
<div class="outer">
<div class="inner"></div>
</div>
If you MUST see the background through the ring, I'd look into a SVG clip path but that gets really complicated pretty quick.
In order to maintain percentage values you can try using a radiel-gradient. However the borders tend to get a little choppy looking.
.circle {
display: flex;
justify-content: center;
align-items: center;
font-family: sans-serif;
color: #fff;
height: 100%;
width: 100%;
border-radius: 50%;
background: radial-gradient(ellipse at center,
rgba(255,113,12,0) 60%,
rgba(255,113,12,1) 51.5%);
}
Example: https://codepen.io/SROwl/pen/BMEJzj
You could use vw or vh as a metric. The border-width will be calculated based on the viewport width or height depending what you choose. You'll have to do some calculation of what value you want to use:
.ring {
border: 10vw solid red;
border-radius: 50%;
height: 100%;
position: absolute;
width: 100%;
}
https://codepen.io/anon/pen/ErJbxN?editors=1100
With JS: https://codepen.io/anon/pen/rPbYvm
I could really use your help.
I have an inner div which needs to extend past an outer div...that part isn't a problem. My issue is, I need help making the outer div clip where the inner div is extending. Problem is, they both need to be transparent.
Please see the below image to understand what I'm trying to achieve.
inner and outer div image
Here is what I have so far:
CSS:
.infoBoxOuter {
border: 10px solid #ffffff;
padding: 50px;
width: 300px;
}
.infoBoxInner {
width: 350px;
}
HTML:
<div class="infoBoxOuter">
<div class="infoBoxInner">
<h1 class="white">Lorem Ipsum dolor</h1>
</div>
</div>
Any help is greatly appreciated. Thanks.
Since you need transparency, I think you are basically looking at one of two possibilities:
Use an SVG for the border shape with the cutout on the side
Generate the top, left, and bottom borders one way or another (most easily with a border on .infoBoxOuter) and then use a pseudo element or two to create the right side with the gap.
Below is an example of approach #2. You could either do the top-right line as one pseudo element and the bottom-right line as another one, or you can do what I've done below and use a gradient to go between white and transparent.
You can adjust the numbers as needed for your situation. I just tried to get something roughly similar to your example image to get you an idea of how this works.
html, body {
height: 100%;
}
body {
background: linear-gradient(to bottom, midnightblue, steelblue);
}
.infoBoxOuter {
color: white;
border-top: 10px solid #ffffff;
border-left: 10px solid #ffffff;
border-bottom: 10px solid #ffffff;
padding: 50px;
width: 150px;
box-sizing: border-box;
position: relative;
}
.infoBoxOuter::after {
content: '';
display: block;
background: linear-gradient(to bottom, white, white 25px, transparent 25px, transparent 140px, white 140px, white);
width: 10px;
height: 100%;
position: absolute;
top: 0;
right: 0;
}
.infoBoxInner {
width: 350px;
box-sizing: border-box;
}
<div class="infoBoxOuter">
<div class="infoBoxInner">
<h1 class="white">Lorem Ipsum dolor</h1>
</div>
</div>
I have a round image (a .png file) which is transparent in the middle. I need to make the background inside the image a solid color. To do this, I made the background solid, and then put border-radius:50%, but this creates an ugly small white line. Is there anyway to get rid of this, or would I have to manually color the image in an image editor?
div {
width: 500px;
height: 500px;
background: black;
}
div img {
margin: 100px;
max-width: 50%;
background: white;
border-radius: 50%;
}
<div>
<img src="http://i.imgur.com/sDU7Lhz.png">
</div>
Fiddle here: https://jsfiddle.net/h3nwkoe1/
The problem is not with the image. The image is a transparent one and has no background to it at all. The problem is caused by the background: white and the border-radius: 50% added to the image element. It is due to the anti-aliasing pixel in browsers and is the same issue described in this thread.
The solution would be to use some method to fill the background partially to the element and not fully (that is, just enough to cover till the black circle that is already present on the image). Since the img tag cannot have pseudo-elements (atleast it won't work cross-browser), the best option is to use a radial-gradient for the background like in the below snippet.
Note: The thick green border is only for demo and can be removed without any side effect.
div {
width: 500px;
height: 500px;
background: black;
}
div img {
margin: 100px;
max-width: 50%;
background: radial-gradient(circle at center, white 60%, transparent 61%);
border-radius: 50%;
overflow: hidden;
border: 4px solid green;
}
<div>
<img src="http://i.imgur.com/sDU7Lhz.png">
</div>
I totally agree with Harry's explanation.
Another workaround could be to enclose the image in a div slightly smaller than the image (like 1px on each side), so that the circle formed using border-radius is smaller than the external black circle on the image.
It is a bit messier than the solution proposed by Harry. But it could be an alternative to gradient.
div#black {
width:500px;
height:500px;
background:black;
border: solid black 1px;
box-sizing: border-box;
}
div#circle {
margin: 100px;
width: 250px;
height: 250px;
background: white;
border-radius: 50%;
text-align: center;
}
div#circle img {
width: 252px;
height: 252px;
margin-left: -1px;
margin-top: -1px;
}
<div id="black">
<div id="circle">
<img src="http://i.imgur.com/sDU7Lhz.png">
</div>
</div>
Please excuse me if this question has been answered before, but I couldn't find an answer when searching.
Essentially what I'm trying to do is to create a header bar which is 107px high and spans 100% width of the page with a split in colour 50% (50% the left is white, 50% on the right is green) along its width. I have been able to accomplish this using CSS gradients, however I work in the education sector and schools seem to be reluctant to use anything but legacy versions of IE and so, inevitably, it doesn't work properly.
Is there anyway to do this which is IE friendly or is there any kind of work around that can give me the same or similar results?
Thanks in advance!
You have a couple of options:
Use a background image (5px high, really wide, left half is white, right half is green) - it'll cost you less than 100 bytes.
Why not use two divs (floated left, both 50% width)?
Here is the HTML:
<div class="header">
<div style="background: white;">
white bg
</div>
<div style="background: green;">
green bg
</div>
</div>
Here is the CSS:
.header { overflow: hidden; height: 107px; border: 1px solid #000;}
.header div { float: left; width: 50%; height: 100%;}
http://jsfiddle.net/PUWCh/
Like this? http://jsfiddle.net/2gGdD/
I'm using pseudo selectors (works back to IE8) to create each half and layer them behind the div with a negative z-index so you can place content on top of them.
.header {
height: 107px;
position: relative;
width: 100%;
}
.header:before,
.header:after {
content: '';
height: 100%;
position: absolute;
width: 50%;
z-index: -1;
}
.header:before {
background: red;
left: 0;
}
.header:after {
background: blue;
right: 0;
}
I have a small png with a transparent area I want to act as the bottom-right hand corner of a solid color div, but I can't seem to come up with an elegant way of doing this with css.
my current css:
div.example {
border-radius: 9px;
background-color: #fff;
background-image: url(bottom-right-corner-peel.png);
background-repeat: no-repeat;
background-position: right bottom;
}
The problem with the above code is that the background color of the div (#fff) shows through the transparent part of the png, ruining the effect. I can think of a couple extremely hacky approaches to fix this (for example - creating another div (or using ::after) to put an element below div in question, and use some tricks to make that work, but there must be a better way, right?
View the [revised] Demo:
http://jsbin.com/abacey/8/
Here is a solution to your problem: http://jsfiddle.net/promatik/uZFpZ/
I've added a #content-bottom next to #content:
<div id="content">
<h1>Corner Peel Demo</h1>
</div>
<div id="content-bottom">
<div id="content-space"></div>
<div id="content-corner"></div>
</div>
And added this in CSS:
div#content{
...
border-bottom-right-radius: 0px;
border-bottom-left-radius: 0px;
}
div#content-bottom {
height: 30px;
position: relative;
}
div#content-space {
height: 27px;
border-bottom-left-radius: 9px;
background-color: #fff;
margin-right: 42px;
}
div#content-corner {
position: absolute;
top: 0px;
right: 0px;
height: 27px;
width: 42px;
background-color: transparent;
background-image: url(data:image/png;base64,...');
}
My Ideas is to use the png to cover up the entire corner of the div.
Lets assume your png is 40x40px and the upper left part is white while the lower part is transparent.
You can use
border-bottom-right-radius: 40px;
to "cut off" the corner of the div. Therefore you have the background image visible. Now you lay your png over it to cover up the ugly round corner.
http://jsfiddle.net/Xd8CD/
(needs a better png...)