I just found that border-radius: 50% and border-radius: 100% look the same.
Does anyone have an explanation on that?
You’ll notice a difference if you round each corner individually. 100% rounds 100% of each edge, 50% only 50% of each edge. If the corner is to be rounded by a radius that is too large for any given edge, then the effective radius will be smaller.
Consider this example:
div{
display: inline-block;
vertical-align: middle;
background: rebeccapurple;
border: 1px solid black;
width: 100px;
height: 100px;
margin-bottom: 10px;
}
code{
display: inline-block;
vertical-align: middle;
margin-left: 20px;
padding: 3px;
background: #eee;
}
.half{
border-top-right-radius: 50%;
}
.full{
border-top-right-radius: 100%;
}
.weird{
border-top-left-radius: 50%;
border-top-right-radius: 100%;
}
<div class="half"></div><code>border-top-right-radius: 50%;</code><br/>
<div class="full"></div><code>border-top-right-radius: 100%;</code><br/>
<div class="weird"></div><code>border-top-left-radius: 50%;<br/>border-top-right-radius: 100%;</code>
Anything more than the radius defaults to the actual radius. By definition a radius is the same in all directions, defining a circle. In other words, half of the diameter. 50%.
That means that anything above the radius (a radius is half, so 50%) defaults to the radius. So the browser thinks of anything above 50% as simply 50%, and will have the same effect.
I found this here.
The actual radius will always be used if the radius is exceeded. By definition, a radius defines a circle by being the same in all directions. Alternatively said, the diameter's half. 50%. This is recognised by the browser.
Some authors decide to write exclusively, although I'm not sure why they do it. The browser just appears to have to work harder to determine what the actual radius is (in order to prevent curves from overlapping). The browser will only calculate the circle's diameter to be half that even if we use px units. Choose 50% if that seems the most logical option for your own sanity.
Related
I'm trying to create a "tag"-like element where the radii of the borders are different on the left side.
border-radius: 50px; /* for a completely rounded right side */
border-top-left-radius: 3px;
border-bottom-left-radius: 3px;
Here's a very brief example:
.tag {
border-radius: 50px;
border-bottom-left-radius: 5px;
border-top-left-radius: 5px;
background-color: red;
color: white;
font-family: Helvetica, sans-serif;
}
<span class="tag">Jeanne Oliver</span>
View on JSFiddle
The problem: the two corners on the left, where I should have 3px rounded corners, don't seem to have any rounding at all (see it in the fiddle)
Possible starting point
I've noticed that if I reduce the larger radius to something like 10-12px the issue stops manifesting.
However I don't understand WHY this is happening, and also I need the larger number because the code needs to be used on a variety of tag sizes and don't want to rewrite the border-radius for each size.
This happens when 2 adjacent corners exceed the size of the border box (in your case it's 50px top-right and 50px bottom-right, which exceeds the element's dimenions) and the browser has to scale down all border radius until they won't intersect.
More details on www.w3.org - corner-overlap and a better exemplification here (Lea Verou, "The Humble Border-Radius")
left radius is applied, nothing is going wrong - you can check it by setting display: inline-block; height: 200px; to span. 3px is very small radius to make visible effect on your original span size.
I would like to use the CSS property "border-image": https://developer.mozilla.org/de/docs/Web/CSS/border-image
But for some reason it fills only the four corners of the element:
My code:
.wrap {
width: 400px;
height: 300px;
margin: 50px auto;
position: relative;
}
.item {
width: 100px;
height: 100px;
background-color: lightGray;
border: 50px solid transparent;
border-image: url(http://lorempixel.com/50/50/) 50 50 50 50 stretch stretch;
}
<div class="wrap">
<div class="item"></div>
</div>
What do I wrong?
I would expect the little image to be repeated as well vertically as horizontally.
So that the grey box is enclosed with the image pattern.
Any help very much appreciated.
No, it won't because your image is a 50x50 image and the border-image-slice is set as 50 too.
The way border-image-slice works is that the UA will split the image into 9 pieces based on offsets indicated in the slice. In your case, once you slice the image by 50px, there is nothing left in middle to set for the areas marked as 5, 6, 7 and 8 in the below image (Image is copied from MDN).
From the W3C Spec on border-image-slice:
The regions given by the ‘border-image-slice’ values may overlap. However if the sum of the right and left widths is equal to or greater than the width of the image, the images for the top and bottom edge and the middle part are empty, which has the same effect as if a nonempty transparent image had been specified for those parts. Analogously for the top and bottom values.
You'd have to set the border-image-slice as something lesser than 25 for the areas in the middle to get covered with the image.
Note: Though the spec says top and bottom edge image are also considered as empty, I am not sure why browsers show the image on all four corners. That may be down to browser implementation. Plus browsers seem to work fine even when we specify the border-image-slice as 25. It is slightly contradicting with the spec but you atleast get the reason :)
Not sure what works, but using an image of larger size sort of fixed it.
Please note that usually the images that are used for border-image are images with graphics at their edges. It's not that entire image is repeated along the edges. It's sort of all four corners of the image are aligned to the corners of our div and then rest of the image is adjusted according to specified properties.
.wrap {
width: 400px;
height: 300px;
margin: 50px auto;
position: relative;
}
.item {
width: 100px;
height: 100px;
background-color: lightGray;
border: 50px solid;
border-image: url(http://lorempixel.com/150/150/) 25;
}
<div class="wrap">
<div class="item"></div>
</div>
Not sure if this is what you where looking for. You need to add box-sizing:border-box; to your .item class.
.wrap {
width: 400px;
height: 300px;
margin: 50px auto;
position: relative;
}
.item {
width: 100px;
height: 100px;
background-color: lightGray;
border: 50px solid transparent;
border-image: url(http://lorempixel.com/50/50/) 50 50 50 50 stretch stretch;
box-sizing:border-box;
}
<div class="wrap">
<div class="item"></div>
</div>
Hope this helps :)
The core issue here is that your source image is not properly created! Using any plain image in border-image rules is generally not going to produce the desired effect.
One must prepare the border image in advance so that it provides the 9 regions required by the specification. Here's a good visual example (taken from MDN):
Given this source image of 90x90px (i.e. each diamond is 30x30px)...
...and applying the following width and slice rule...
border-width: 30px;
border-image-slice: 30;
...we get this result:
You can see the full details of how the source image is split here but the main point is that you must have a properly setup source image first.
This question already has answers here:
How to draw circle in html page?
(19 answers)
Closed 6 years ago.
In CSS it is allowed to write something like this.
#div-with-border {
width: 100%; // scales with parent wrapper
height: 30%; // scales with parent wrapper
border: 1px solid black;
border-radius: 10%;
}
If #div-width-border isn't a perfect square the border won't be a circle, since this means, that 10% of the width and 10% of the height are used for the border-radius (which differ). I would like to get perfect circles... I can't use px, since the border-radius depends on the height/width.
I'm sure that the width of #div-width-border is always greater than the height, of the element. I would need a border radius of the size 100% of element height to get a perfect circle, but just 100% won't do it, since it'll use the element width for one part of the radius calculation.
If you know the ratio between the width and the height, you may use the Slash-Annotation to specify different %-values for horizontal and vertical border-radius. An Example is below:
.wrapper {
width: 300px;
height: 300px;
margin: 0 auto;
}
.div-with-border {
width: 100%;
height: 25%;
background-color: blue;
border: 1px solid black;
border-radius: 10% / 40%;
}
<div class="wrapper">
<div class="div-with-border"></div>
</div>
Have you tried border-radius: 50%; ? Since you're saying that the div is a perfect square, setting border radius to 50% should work
I know this question has been asked in another form very popularly here:
How do CSS triangles work?
and I have extensively read the entire thread, but it does not address what I'm trying to do.
I want to make a cross-browser equilateral triangle clip that is responsive.
I found a lot of css like this that uses pixels:
#triangle-up {
width: 0;
height: 0;
border-left: 60px solid transparent;
border-right: 60px solid transparent;
border-bottom: 100px solid red;
}
But it's not responsive. I'm currently drawing it using polygon below like so:
.tri-Up {
-webkit-clip-path: polygon(50% 0, 0 100%, 100% 100%);
clip-path: polygon(50% 0, 0 100%, 100% 100%);
}
But this is not compatible in Firefox. I've been exploring this question for weeks, but have yet to find a way to clip a equilateral triangle, have it be responsive, and have it work in firefox, chrome, and Safari.
Any thoughts or attempts/success at this would garner much of my appreciation and respect.
Yeah it can be done, I needed that a while ago, and found a solution to this issue right here:
you can use a <div> or some other that you think it can represent a triangle, and a :pseudo selector from it (actually you can use 2x <div> and leave out the :pseudo selector)
the :pseudo selector can be used to represent the triangle itself, like you posted in your question, with border prop.
the parent <div> acts like a mask that either shrinks/grows the :pseudo selector, using a combination of width and padding specified in percetage
as this mask grows, with your container, more of the triangle is revealed and as soon as it shrinks, it covers up the triangle
the border prop set on the :pseudo element acts like a max-width to which the triangle will grow, so you can specify some larger values to it, to the point you think that will the max that it needs to be
Kudos for the author of this solution, and more about this:
One div, a :pseudo element, and a responsive triangle
Two divs and a responsive triangle
Documentation website
Check out the demo here or the snippet bellow:
*,
*:after,
*before {
box-sizing: border-box;
}
h3 {
margin: 10px;
text-align: center;
}
.small-container {
max-width: 10%;
float: left;
}
.medium-container {
max-width: 30%;
float: left;
}
.large-container {
float: left;
max-width: 50%;
}
.fancy-triangle {
width: 50%;
height: 0;
padding-left: 50%;
padding-bottom: 50%;
overflow: hidden;
}
.fancy-triangle:after {
content: "";
display: block;
width: 0;
height: 0;
margin-left: -2000px;
border-left: 2000px solid transparent;
border-right: 2000px solid transparent;
border-bottom: 2000px solid #4679BD;
}
<h3>Now isnt that nice?</h3>
<div class='fancy-triangle'></div>
UPDATE
Ok, since you need to actually mask a image in a sorta responsive triangle, the above method wont cut it.
Instead, you could use a svg and some percentage clip path points like so:
use the svg to draw up a triangle, used to clip the image if the clip-path isnt working properly custom points/shapes
then use the clip-path to draw a triangle with custom percentage points representing a triangle
Alternatively, you could a position absolute on the <img> wrapper, and set the width/height in some percentage values that will be bound to a set parent with a position relative, that will then grow/shrink with it.
Demo here
Resources
UPDATE V3
Instead of using a <img> tag you could alternatively use a <svg> with the src attr of you're image and it should work out pretty nice.
Demo here
Resources
.fancy-triangle-image {
max-width: 1200px;
-webkit-clip-path: polygon(50% 0%, 100% 100%, 0% 100%);
clip-path: url(#triangle);
}
.fancy-triangle-image img{
width: 100%;
}
<div class='fancy-triangle-image'>
<img src='http://insolitebuzz.fr/wp-content/uploads/2014/10/test-all-the-things.jpg'/>
</div>
<svg display="none;">
<defs>
<clipPath id="triangle">
<polygon points="150 0, 300 300, 0 300" />
</clipPath>
</defs>
</svg>
The best bet I can think of is using vw as your unit on the triangle, as this is the only responsive unit that you can use in the border property. See gist here http://sassmeister.com/gist/1b0d70bf4cc35ff05fec
Browser support for vw is pretty good. http://caniuse.com/#search=vw
Something I've been wondering for a while whilst doing CSS design.
Are decimal places in CSS widths respected? Or are they rounded?
.percentage {
width: 49.5%;
}
or
.pixel {
width: 122.5px;
}
If it's a percentage width, then yes, it is respected:
#outer {
width: 200px;
}
#first {
width: 50%;
height: 20px;
background-color: red;
}
#second {
width: 50.5%;
height: 20px;
background-color:green;
}
#third {
width: 51%;
height: 20px;
background-color:blue;
}
<div id="outer">
<div id="first"> </div>
<div id="second"> </div>
<div id="third"> </div>
</div>
As Martin pointed out, things break down when you get to fractional pixels, but if your percentage values yield integer pixel value (e.g. 50.5% of 200px in the example) you'll get sensible, expected behaviour.
Edit: I've updated the example to show what happens to fractional pixels (in Chrome the values are truncated, so 50, 50.5 and 50.6 all show the same width.)
#percentage {
width: 200px;
color: white;
}
#percentage .first {
width: 50%;
height: 20px;
background-color: red;
}
#percentage .second {
width: 50.5%;
height: 20px;
background-color:green;
}
#percentage .third {
width: 51%;
height: 20px;
background-color:blue;
}
#pixels {
color: white;
}
#pixels .first {
width: 50px;
height: 20px;
background-color: red;
}
#pixels .second {
width: 50.5px;
height: 20px;
background-color:green;
}
#pixels .third {
width: 50.6px;
height: 20px;
background-color:blue;
}
#pixels .fourth {
width: 51px;
height: 20px;
background-color:red;
}
<div id="percentage">
<div class="first">50%=100px</div>
<div class="second">50.5%=101px</div>
<div class="third">51%=102px</div>
</div>
<br />
<div id="pixels">
<div class="first">50px</div>
<div class="second">50.5px</div>
<div class="third">50.6px</div>
<div class="fourth">51px</div>
</div>
Even when the number is rounded when the page is painted, the full value is preserved in memory and used for subsequent child calculation. For example, if your box of 100.4999px paints to 100px, it's child with a width of 50% will be calculated as .5*100.4999 instead of .5*100. And so on to deeper levels.
I've created deeply nested grid layout systems where parents widths are ems, and children are percents, and including up to four decimal points upstream had a noticeable impact.
Edge case, sure, but something to keep in mind.
Although fractional pixels may appear to round up on individual elements (as #SkillDrick demonstrates very well) it's important to know that the fractional pixels are actually respected in the actual box model.
This can best be seen when elements are stacked next to (or on top of) each other; in other words, if I were to place 400 0.5 pixel divs side by side, they would have the same width as a single 200 pixel div. If they all actually rounded up to 1px (as looking at individual elements would imply) we'd expect the 200px div to be half as long.
This can be seen in this runnable code snippet:
body {
color: white;
font-family: sans-serif;
font-weight: bold;
background-color: #334;
}
.div_house div {
height: 10px;
background-color: orange;
display: inline-block;
}
div#small_divs div {
width: 0.5px;
}
div#large_div div {
width: 200px;
}
<div class="div_house" id="small_divs">
<p>0.5px div x 400</p>
<div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</div>
<br>
<div class="div_house" id="large_div">
<p>200px div x 1</p>
<div></div>
</div>
The width will be rounded to an integer number of pixels.
I don't know if every browser will round it the same way though. They all seem to have a different strategy when rounding sub-pixel percentages. If you're interested in the details of sub-pixel rounding in different browsers, there's an excellent article on ElastiCSS.
edit: I tested #Skilldrick's demo in some browsers for the sake of curiosity. When using fractional pixel values (not percentages, they work as suggested in the article I linked) IE9p7 and FF4b7 seem to round to the nearest pixel, while Opera 11b, Chrome 9.0.587.0 and Safari 5.0.3 truncate the decimal places. Not that I hoped that they had something in common after all...
They seem to round up the values to the closest integer; but Iam seeing inconsistency in chrome,safari and firefox.
For e.g if 33.3% converts to 420.945px
chrome and firexfox show it as 421px.
while
safari shows its as 420px.
This seems like chrome and firefox follow the floor and ceil logic while safari doesn't.
This page seems to discuss the same problem
http://ejohn.org/blog/sub-pixel-problems-in-css/
Elements have to paint to an integer number of pixels, and as the other answers covered, percentages are indeed respected.
An important note is that pixels in this case means css pixels, not screen pixels, so a 200px container with a 50.7499% child will be rounded to 101px css pixels, which then get rendered onto 202px on a retina screen, and not 400 * .507499 ~= 203px.
Screen density is ignored in this calculation, and there is no way to paint* an element to specific retina subpixel sizes. You can't have elements' backgrounds or borders rendered at less than 1 css pixel size, even though the actual element's size could be less than 1 css pixel as Sandy Gifford showed.
[*] You can use some techniques like 0.5 offset box-shadow, etc, but the actual box model properties will paint to a full CSS pixel.