Should border-radius clip the content? - css

Shouldn't the content of my container be cut off when the container has border-radius?
Sample HTML and CSS:
.progressbar { height: 5px; width: 100px; border-radius: 5px; }
.buffer { width: 25px; height: 5px; background: #999999; }
<div class="progressbar">
<div class="buffer"></div>
</div>
As you can see I use border-radius on the container (.progressbar), but the content (.buffer) goes 'outside' the container. I'm seeing this on Google Chrome.
Is this the expected behavior?
P.S. This isn't about how to fix it, this is about whether it should work like this.

Is this the expected behavior?
Yes, as crazy as it sounds, it actually is. Here's why:
The default overflow for <div> elements (and most other things) is visible, and the spec says this about overflow: visible:
visible
This value indicates that content is not clipped, i.e., it may be rendered outside the block box.
In turn, §5.3 Corner clipping in the Backgrounds and Borders module says:
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. Also, the area outside the curve of the border edge does not accept mouse events on behalf of the element.
The sentence that I've emphasized specifically mentions that the overflow value of the box must be something other than visible (that means auto, hidden, scroll and others) in order for the corners to clip its children.
If the box is defined to have visible overflow, which like I said is the default for most visual elements, then the content is not supposed to be clipped at all. And that's why the square corners of .buffer go over the rounded corners of .progressbar.
Consequently, the simplest way to get .buffer to clip within .progressbar's rounded corners is to add an overflow: hidden style to .progressbar, as shown in this updated fiddle.

For anybody wondering what a fix would be. The easiest way would be to edit the css.
In the example given this would be a suitable fix:
.progressbar { height: 5px; width: 100px; border-radius: 5px; overflow: hidden; }
.buffer { width: 25px; height: 5px; background: #999999; }
<div class="progressbar">
<div class="buffer"></div>
</div>

Semantically speaking, it's best to simply add a border-radius inherit property to the inner div, hence the new class addition:
.buffer {
border-radius: inherit;
}
As a consequence, for others situation, you can preserve the use of overflow: auto if the content overflows your frae and you want to see everything.

The edges and corners of the parent container are covered by quilt elements, so the content of the parent element needs to be cropped, as long as the overflow value is set not visible, for example:
.parent {
overflow: hidden;
border-radius: 5px;
}

This question seems to point to the same defect, apparently this is a bug.
CSS3 border-radius clipping issues
Edit
Eek! BoltClock has mentioned that this is indended so I'll post this other SO question on the topic whilst I also hunt for a spec quote on this.
How do I prevent an image from overflowing a rounded corner box with CSS3?
Specification Link
Just for reference, I'll stick the relevant link in - but I can't find anything explicit to the example you've given.
CSS Backgrounds - Rounded Corners

This is what the specifications says, so this is the way it should work. But that doesn't mean that Chrome does it like that.
5.3. 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. Also, the area outside the curve of the border edge does not accept mouse events on behalf of the element.
http://www.w3.org/TR/css3-background/#border-radius

Related

3D transforms take up space even if taken out of flow?

I'm rotating a div in 3D space. It's pretty simple:
<div class="holder">
<div class="box">
<p>This is some text.</p>
</div>
</div>
.box {
background: orange;
color: #fff;
font-size: 6em;
transform: rotateY(60deg);
padding: 20px;
position: absolute;
}
.holder {
perspective: 300px;
max-width: 600px;
margin: 0 auto;
}
I notice that in IE11 and Firefox, if the transform makes the shape run out of the viewport, it will display scrollbars. This happens even if the item is out of the flow, by setting position: absolute. In Chrome, no scrollbars are displayed.
My understanding was that 3D transforms don't take up any additional space than the non-3D version of the item, so I'm not sure whey scrollbars are appearing in some browsers. Is this the correct behavior?
Yes, this is correct behavior as per spec: http://dev.w3.org/csswg/css-transforms-1/#transform-rendering
For elements whose layout is governed by the CSS box model, the transform property does not affect the flow of the content surrounding the transformed element. However, the extent of the overflow area takes into account transformed elements. This behavior is similar to what happens when elements are offset via relative positioning. Therefore, if the value of the overflow property is scroll or auto, scrollbars will appear as needed to see content that is transformed outside the visible area.
Common workaround for this kind of behavior would be setting overflow: hidden on html element and then reseting it to auto or scroll lower in the DOM, based on your needs.

Border disappears in Chrome when percentage height specified

I have a div with 1-pixel-border and height:29%. Chrome for some reason renders it without the bottom border.
See http://jsfiddle.net/9WVuC/4/
This issue depends on the actual percentage value and container size; when I change them, border sometimes appears and sometimes disappears. Seems that there is some rounding error in Chrome rendering engine when it's calculating actual div's height. Also, it occurs only if overflow and position are specified for that div.
Is it a known bug and maybe some workaround exists? Of course I can get rid of that percentage values by recalculating height manually and setting it with JS, but it's not very elegant solution.
this is because of the overflow:hidden; style you have on the div, the border actually appears outside of the div in question, so according to the height of the div (with it being a %) it doesn't take this border into account.
Looking at your code i would recommend moving your overflow:hidden; to the containing element of the divs (the td) that fixes the problem and will have the same effect on the content of the class="lower" element if it overflows.
You can fix this "bug" by setting height to height: 28.95%;
Make sure you do not use tables for layout. They should only be used for tabular data.
decrease the height or remove overflow: hidden
lower{
height: 28%;
position: relative;
overflow: hidden;
border: solid 1px black;
}
Fiddle demo
This is probably a rendering issue depending on screen/window size and the element's computed size (with decimals). A workaround for me was to put an invisible box-shadow where the border is missing and it fixes the rendering. For the bottom border it would look like this:
box-shadow: 0 1px 0 0 rgba(255,255,255,0);

css: absolute position doesn't favour right and bottom value?

I want to absolute position an iframe and define it's left, top, right, bottom offset:
#x {
position: fixed;
left: 10px;
top: 10px;
right: 10px;
bottom: 10px;
width: auto;
height: auto;
border: 2px solid #aaa;
z-index: 100002;
background: #abc;
display:none
}​
I found the left and top value is respected while right and bottom value is ignored. When I don't have a left and top value set, then the right and bottom value is treated correctly. Check this fiddle: http://jsfiddle.net/7fTEF/
Any idea?
Note I don't want to set width and height of the element because I want it be relative to the viewport, neither do I want to set the width and height to a percentage, I just want to keep the border offset a fixed value, say "10px" here.
Not sure why, but, after a little playing around, it seems like IFrames don't like that style of positioning for some reason.
One solution I could make was to container it in a div, and get the div to the size/position you want.
http://jsfiddle.net/7fTEF/1/
Also, despite being 500x500px, the body background color will keep going to fill up all the space in a page, but the sizing of the div is still correct. (resize the body to check it out... )
You can not set both left and right or both top and bottom property. edit: Turns out you can actually provided you are positioning absolute, as i just learned from this article: http://www.alistapart.com/articles/conflictingabsolutepositions (all credits to #thirdender for the tip!). Iframes seem to behave differently though.
You could achieve what you are after like this: http://jsfiddle.net/7fTEF/2/
Note that there is no absolute postioning required. Also i used the css3 property box-sizing. You will have to add browser specific prefixes as explained here http://www.w3schools.com/cssref/css3_pr_box-sizing.asp
Note that this solution will not work in old browser, you will end up with scrollbars. If you want to make it fully browser compatible i think yoy will have to resort to some js, but then you have problems with people who have this disabled. You could also try a combination of both. It all depends on your audience and how import you find it...
You can find the container size via javascript and after set the iframe size.
I found this page here http://www.alistapart.com/articles/conflictingabsolutepositions/ that explains a couple of solutions that are also compatible with older IE browsers using just CSS. Otherwise some JavaScript calculations would probably be required.

What is the difference between outline and border CSS properties?

What is the difference between border and outline properties in CSS?
If there is no difference, then why are there two properties for the same thing?
From: http://webdesign.about.com/od/advancedcss/a/outline_style.htm
The CSS outline property is a confusing property. When you first learn about it, it's hard to understand how it is even remotely different from the border property. The W3C explains it as having the following differences:
Outlines do not take up space.
Outlines may be non-rectangular.
In addition to some other answers... here are a few more differences I can think of:
1) Rounded corners
border supports rounded corners with the border-radius property. outline doesn't.
div {
width: 150px;
height: 150px;
margin: 20px;
display: inline-block;
position: relative;
}
.border {
border-radius: 75px;
border: 2px solid green;
}
.outline {
outline: 2px solid red;
border-radius: 75px;
-moz-outline-radius: 75px;
outline-radius: 75px;
}
.border:after {
content: "border supports rounded corners";
position: absolute;
bottom: 0;
transform: translateY(100%);
}
.outline:after {
content: "outline doesn't support rounded corners";
position: absolute;
bottom: 0;
transform: translateY(100%);
}
<div class="border"></div>
<div class="outline"></div>
FIDDLE
(NB: Although firefox has the -moz-outline-radius property which allows rounded corners on outline... this property it is not defined in any CSS standard, and is not supported by other browsers (source))
2) Styling one side only
border has properties to style each side with border-top:, border-left: etc.
outline can't do this. There's no outline-top: etc. It's all or nothing. (see this SO post)
3) offset
outline supports offset with the property outline-offset. border doesn't.
.outline {
margin: 100px;
width: 150px;
height: 150px;
outline-offset: 20px;
outline: 2px solid red;
border: 2px solid green;
background: pink;
}
<div class="outline"></div>
FIDDLE
Note: All major browsers support outline-offset except Internet Explorer
Further to other answers, outlines are usually used for debugging. Opera has some nice user CSS styles that use the outline property to show you where all the elements are in a document.
If you're trying to find out why an element isn't appearing where you expected or at the size you expected, add a few outlines and see where the elements are.
As already mentioned, outlines do not take up space. When you add a border, the element's total width/height in the document increases, but that doesn't happen with outline. Also you can't set outlines on specific sides like borders; it's all or nothing.
tldr;
The W3C explains it as having the following differences:
Outlines do not take up space.
Outlines may be non-rectangular.
Source
Outline should be used for accessibility
It should also be noted that outline's primary purpose is accessibility. Setting it to outline: none should be avoided.
If you must remove it it maybe a better idea to provide alternative styling:
I’ve seen quite a few tips on how to remove the focus indicator by using outline:none or outline:0. Please do not do this, unless you replace the outline with something else that makes it easy to see which element has keyboard focus. Removing the visual indicator of keyboard focus will give people who rely on keyboard navigation a really hard time navigating and using your site.
Source: "Do Not Remove the Outline from Link and Form Controls", 365 Berea Street
More Resources
http://outlinenone.com/
A practical use of outline deals with transparency. If you have a parent element with a background, but want a child element's border to be transparent so that the parent's background will show through, you must use "outline" rather than "border." While a border can be transparent, it will show the child's background, not the parent's.
In other words, this setting created the following effect:
outline: 7px solid rgba(255, 255, 255, 0.2);
From W3 School Site
The CSS border properties allow you to specify the style and color of an element's border.
An outline is a line that is drawn around elements (outside the borders) to make the element "stand out".
The outline shorthand property sets all the outline properties in one declaration.
The properties that can be set, are (in order): outline-color, outline-style, outline-width.
If one of the values above are missing, e.g. "outline:solid #ff0000;", the default value for the missing property will be inserted, if any.
Check here for more information :
http://webdesign.about.com/od/advancedcss/a/outline_style.htm
Border is created inside the element, where as outline is created outside the element. So border is computed along with the width and height of the element, while outline draws outside the element.
A little bit of an old question, but worth mentioning a Firefox rendering bug (still present as of Jan '13) where the outline will render on the outside of all child elements even if they overflow their parent (through negative margins, box-shadows, etc.)
You can fix this with:
.container {
position: relative;
}
.container:before {
content: '';
margin: 0;
padding: 0;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
outline: 1px solid #ff0000;
}
Super unfortunate that it's still not fixed. I much prefer outlines in many cases since they do not add to the dimensions of an element, saving you from always having to consider border widths when setting dimensions of an element.
After all, which is simpler?
.container {
width: 960px;
height: 300px;
outline: 3px solid black;
}
Or:
.container {
width: 954px;
height: 294px;
border: 3px solid black;
}
It is also worth noting, that W3C's outline is IE's border, since IE does not implement W3C box model.
In w3c box model, the border is exclusive of element's width and height. In IE it is inclusive.
Differences between border and outline:
Border is part of the box model so it counts against the element's size.
Outline is not part of the box model so it doesn't affect nearby elements.
Demo:
#border {
border: 10px solid black;
}
#outline {
outline: 10px solid black;
}
<html>
<body>
<span id="border">Border</span>Other text<br><br>
<span id="outline">Outline</span>Other text
</body>
</html>
Other differences:
The outline is displayed outside the border.
Outlines cannot have rounded corners; borders can.
I've made a little piece of css/html code just to see the difference between both.
outline is better to inclose potential overflowing child elements, especially into an inline container.
border is much more adapted for block-behaving elements.
Fiddle for you sir!
The outline property in CSS draws a line around the outside of an element. It's similar to border except that:
It always goes around all the sides, you can't specify particular
sides It's not a part of the box model, so it won't effect the
position of the element or adjacent elements
Source: https://css-tricks.com/almanac/properties/o/outline/
As a practical example of using "outline", the faint dotted border that follows the system focus on a webpage (eg. if you tab through the the links) can be controlled using the outline property (at least, I know it can in Firefox, not tried other browsers).
A common "image replacement" technique is to use, for example:
<div id="logo">Foo Widgets Ltd.</div>
with the following in the CSS:
#logo
{
background: url(/images/logo.png) center center no-repeat;
}
#logo a
{
display: block;
text-indent: -1000em;
}
The problem being that when the focus reaches the tag, the outline heads off 1000em to the left. Outline can allow you to turn off the focus outline on such elements.
I believe that the IE Developer Toolbar is also using something like outline "under the hood" when highlighting elements for inspection in "select" mode. That shows well the fact that "outline" takes up no space.
think about outline as a border that a projector draw outside something as a border is an actual object around that thing.
a projection can easily overlap but border don't let you pass.
some times when i use grid+%width, border will change the scaling on view port,for example a div with width:100% in a parent with width:100px fills the parent completely, but when i add border:solid 5px to div it make the div smaller to make space for border(although it's rare and work-aroundable!) but with outline it doesn't have this problem as outline is more virtual :D it's just a line outside the element
but the problem is if you don't do spacing properly it would overlap with other contents.
to make it short:
outline pros:
it doesn't mess with spacing and positions
cons:
high chance of overlapping
Google web.dev has a good explaintion for Box Model.
The border box surrounds the padding box and its space is occupied by the border value. The border box is the bounds of your box and the border edge is the limit of what you can visually see. The border property is used to visually frame an element.
The margin box, is the space around your box, defined by the margin rule on your box. Properties such as outline and box-shadow occupy this space too because they are painted on top, so they don't affect the size of our box. You could have an outline-width of 200px on our box and everything inside and including the border box would be exactly the same size.
Copied from W3Schools:
Definition and Usage
An outline is a line that is drawn
around elements (outside the borders)
to make the element "stand out".

Seeking CSS Browser compatibility information for setting width using left and right

Here's a question that's been haunting me for a year now. The root question is how do I set the size of an element relative to its parent so that it is inset by N pixels from every edge? Setting the width would be nice, but you don't know the width of the parent, and you want the elements to resize with the window. (You don't want to use percents because you need a specific number of pixels.)
Edit
I also need to prevent the content (or lack of content) from stretching or shrinking both elements. First answer I got was to use padding on the parent, which would work great. I want the parent to be exactly 25% wide, and exactly the same height as the browser client area, without the child being able to push it and get a scroll bar.
/Edit
I tried solving this problem using {top:Npx;left:Npx;bottom:Npx;right:Npx;} but it only works in certain browsers.
I could potentially write some javascript with jquery to fix all elements with every page resize, but I'm not real happy with that solution. (What if I want the top offset by 10px but the bottom only 5px? It gets complicated.)
What I'd like to know is either how to solve this in a cross-browser way, or some list of browsers which allow the easy CSS solution. Maybe someone out there has a trick that makes this easy.
The The CSS Box model might provide insight for you, but my guess is that you're not going to achieve pixel-perfect layout with CSS alone.
If I understand correctly, you want the parent to be 25% wide and exactly the height of the browser display area. Then you want the child to be 25% - 2n pixels wide and 100%-2n pixels in height with n pixels surrounding the child. No current CSS specification includes support these types of calculations (although IE5, IE6, and IE7 have non-standard support for CSS expressions and IE8 is dropping support for CSS expressions in IE8-standards mode).
You can force the parent to 100% of the browser area and 25% wide, but you cannot stretch the child's height to pixel perfection with this...
<style type="text/css">
html { height: 100%; }
body { font: normal 11px verdana; height: 100%; }
#one { background-color:gray; float:left; height:100%; padding:5px; width:25%; }
#two { height: 100%; background-color:pink;}
</style>
</head>
<body>
<div id="one">
<div id="two">
<p>content ... content ... content</p>
</div>
</div>
...but a horizontal scrollbar will appear. Also, if the content is squeezed, the parent background will not extend past 100%. This is perhaps the padding example you presented in the question itself.
You can achieve the illusion that you're seeking through images and additional divs, but CSS alone, I don't believe, can achieve pixel perfection with that height requirement in place.
If you are only concerned with horizontal spacing, then you can make all child block elements within a parent block element "inset" by a certain amount by giving the parent element padding. You can make a single child block element within a parent block element "inset" by giving the element margins. If you use the latter approach, you may need to set a border or slight padding on the parent element to prevent margin collapsing.
If you are concerned with vertical spacing as well, then you need to use positioning. The parent element needs to be positioned; if you don't want to move it anywhere, then use position: relative and don't bother setting top or left; it will remain where it is. Then you use absolute positioning on the child element, and set top, right, bottom and left relative to the edges of the parent element.
For example:
#outer {
width: 10em;
height: 10em;
background: red;
position: relative;
}
#inner {
background: white;
position: absolute;
top: 1em;
left: 1em;
right: 1em;
bottom: 1em;
}
If you want to avoid content from expanding the width of an element, then you should use the overflow property, for example, overflow: auto.
Simply apply some padding to the parent element, and no width on the child element. Assuming they're both display:block, that should work fine.
Or go the other way around: set the margin of the child-element.
Floatutorial is a great resource for stuff like this.
Try this:
.parent {padding:Npx; display:block;}
.child {width:100%; display:block;}
It should have an Npx space on all sides, stretching to fill the parent element.
EDIT:
Of course, on the parent, you could also use
{padding-top:Mpx; padding-bottom:Npx; padding-right:Xpx; padding-left:Ypx;}

Resources