Pixel Border and Percentage width in Proportion - css

I think I might already know the answer to this one but I need a sanity check!
Say I have
#gridtest{
width:590px;
}
I could change the width to a percentage by using RESULT=TARGET/CONTEXT. In this case the context is a container with a max-width set to 1000px so I can do this:
#gridtestpercent{
width:59%; /*590/1000*/
}
If I were to shrink the window down the div would always be in the proportion to the its container. But what if I wanted to do
#gridtest{
width:570px;
border:10px solid red;
}
I can work the width out based on the target now being 570 but as the window is shrunk the proportions all go out of sync.
#gridtestpercentnoborder{
width:57%; /*570/1000*/
border:10px solid red;
}
I can't use percentage border. I don't want to use JS to keep checking the context and I can't use the CSS3 box-border declaration yet.
If I wanted to use the technique described in responsive web design by Ethan Marcotte where everything shrinks in relation to each other would I be out of luck if using a border?
Cheers!

You could use CSS3 calc() function,
.selector{
border: 5px solid black;
width: -moz-calc(50% - 10px);
width: -webkit-calc(50% - 10px);
width: calc(50% - 10px);
}
SASS mixin
#mixin calc($property, $expression) {
#{$property}: -moz-calc(#{$expression});
#{$property}: -webkit-calc(#{$expression});
#{$property}: calc(#{$expression});
}
article {
border: 1px solid red;
#include calc( width, '100% - 2px')
}

You could use an inset box-shadow instead of a border:
box-shadow: 0px 0px 0px 10px red inset;
Just pad the inside of the container to compensate.
Edit: I write "pad" but of course if you use padding it'll throw off the box dimensions. Margin the content inside instead.

The accepted answer is not correct. You actually have 2 options:
Use the box-sizing property, so all the paddings and borders are considered part of the size:
.column {
width: 16%;
float: left;
margin: 0 2% 0 2%;
background: #03a8d2;
border: 2px solid black;
padding: 15px;
font-size: 13px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
Or, use the outline property instead of the border property. You will still have problems with the paddings, but it's easier to add. Example:
.column {
width: 16%;
float: left;
margin: 0 2% 0 2%;
background: #03a8d2;
outline: 2px solid black;
}
Full explanation: http://designshack.net/articles/css/beating-borders-the-bane-of-responsive-layout/

Unfortunately, yes, you're out of luck. One hacky way to get around this problem is with a wrapper div that you use to create your border. So the outside div would be 57% (in your example) with a background that is the color of your desired border. Then, the inner div would have a width of 96% or so (play with the exact number to find a border that is appropriate for your design).

If you want to stay semantic you can use div { box-sizing:border-box; } or some absolutely positioned :after elements. See the post How do I add 1px border to a div whose width is a percentage?

In CSS3 you can also use the new box-sizing property to include the pixel and padding count into the width of the element:
box-sizing: border-box;

If possible, depending on your design, what I like to do is put the border as an absolute div with a width of 3px ( for example ) and a height higher than its parent div. I then set overflow hidden on the parent div.

Related

Border Position

I want to try and achieve something in CSS using borders but they don't seem to have something I want. In Photoshop, when you add a Stroke (border), you select the position. Outside, Inside, or Center. Outside being where the entire border wraps around the object. Inside is where it sits on the inside (obviously), and center being half and half.
I want a 2px border that's positioned in the center. So it shows 1px outside and 1px inside. Is there anyway to do this with CSS? I imagine I can do it with a box-shadow of some kind but I'm horrendous at shadows in CSS.
There's also the issue of having to be pure CSS so I can't lay an image over it. Can someone possibly help me out with this.
Thanks.
There's a work around, since border represents outer stroke for you, you can make use of outline css property with outline-offset set to negative value to have the inner 1px stroke( 1 ) JS Fiddle
body {
padding-top: 10px;
}
#test {
width: 250px;
height: 200px;
background-color: orange;
margin: 0 auto;
border: 1px navy solid; /* outer stroke */
outline: 1px navy solid; /* inner stroke */
outline-offset: -2px; /* negative border width + outline width */
}
<div id="test"></div>
( 1 ) As the above fiddle might not demonstrate the explanation good enough, here's the same example with two colored strokes and 4px for each stroke instead of 1px Demo Fiddle
Resources:
http://caniuse.com/#search=outline
https://developer.mozilla.org/en/docs/Web/CSS/outline-offset
http://www.w3schools.com/cssref/css3_pr_outline-offset.asp
https://davidwalsh.name/outline-offset
Perhaps with a suitable sized absolutely positioned pseudo-element?
div {
box-sizing: border-box;
width: 200px;
height: 200px;
border: 1px solid black;
margin: 1em auto;
position: relative;
}
div:after {
content: '';
position: absolute;
top:-6px;
left: -6px;
width: calc(100% - 12px);
height: calc(100% - 12px);
border:12px solid rgba(255,0,0,0.5)
}
<div></div>
You could nudge the container so that it would look like it's an inner border. For example, if you have have a 2px left border and want it to appear as an inner border, you can just offset the whole container to the right, like this:
position: relative;
left: 2px;
You might have to do other corrections, such as reducing the width of the container by 2px.

CSS: containing five floated 20% elements with borders

I'm trying to align five horizontal menu elements with 'float:left' next to each other inside a container that spans 80% of the screen and a minimum of 960px. For this, I had initially set their min-width to 192px (960/5) and their width to 20%, but quickly realized this does not play well with adding 1px borders, causing one of the buttons to be 'thrown overboard'.
Changing the widths to 19.895333% and 191px, respectively, solved the issue, however this is clearly a hacky solution which also leaves an ugly space of 2-3 pixels at the right side of the menu.
Is there a more elegant way to align these elements and account for the bonus width added by borders, padding etc? I have tried 'overflow:hidden' to simply hide whatever may poke outside the container, but this just hides the entire 5th button.
A picture to illustrate the result:
The html code:
<div class="menucontainer">
<div class="menutab" id="menutab_first">News</div>
<div class="menutab">Game Guide</div>
<div class="menutab">Articles</div>
<div class="menutab">Media</div>
<div class="menutab" id="menutab_last">Community</div>
</div>
The css code:
.menucontainer {
height: 26px;
margin-left: auto;
margin-right: auto;
border-width: 1px;
border-style: solid;
border-color: #303030 #101010 #000 #101010;
border-radius: 0px 0px 8px 8px;
}
.menutab {
line-height: 26px;
float: left;
width: 19.895333%;
text-align: center;
min-width: 191px;
border-right: 1px solid #202020;
background-image: url('../img/menubutton2.png');
background-size: 100% 100%;
font-family: 'Cabin', sans-serif;
}
#menutab_first {
border-radius: 0px 0px 0px 8px;
}
#menutab_last {
border-right: 0px;
width: 20%;
min-width: 192px;
border-radius: 0px 0px 8px 0px;
}
Thank you in advance!
For this you can make use of the box-sizing property to set your borders to appear within your elements rather than outside of them:
elem {
-webkit-box-sizing: border-box; /* Some mobile browsers. */
-moz-box-sizing: border-box; /* Firefox. */
box-sizing: border-box; /* All other browsers IE8+. */
}
border-box
The specified width and height (and respective min/max properties) on this element determine the border box of the element. That is, any padding or border specified on the element is laid out and drawn inside this specified width and height. The content width and height are calculated by subtracting the border and padding widths of the respective sides from the specified ‘width’ and ‘height’ properties.
So in the case of your CSS:
.menutab {
...
width: 20%;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
...
}
What you need is box-sizing:border-box;
This CSS property will change the box model for the element such that the border is included inside the width, rather than outside of it as with the standard box model.
This means that your boxes will then be 20% of the width of the page, rather than 20% + the width of the borders.
Problem solved.
box-sizing: border-box causes the width of the borders to be counted as part of the 20%. That's the best solution but if that will interfere with your layout in some way, an alternative is use calc to subtract the borders from the 20%, e.g. width: calc(20% - 2px);

css3 need help in understanding box-sizing

I have found the following from the site: http://www.htmlgoodies.com/html5/tutorials/learn-css3-from-a-z-getting-started-with-layouts-.html#fbid=Byc3E58e8v-
"The CSS3 code for this is very simple. You just need to add the following property to switch the model for a particular element.
#W3C-model {
box-sizing: content-box;
}
#traditional-model {
box-sizing: border-box;
}
Having understood how box-sizing works, the next question is where can you use it? Well, its very useful when you have two equal columns. If you give them 50% width each and add some padding and maybe a border, the columns won't show up side by side. This is an ideal scenario where you can set box-sizing to border-box and happily set the width to 50% for both boxes."
I am not sure what is meant by the columns won't show up side by side? It sounds like what is expected here is the dividing border between the two columns would vanish or something like that - I am not sure. I have this sample code to experiment with:
http://jsfiddle.net/hE8UZ/
I am not seeing any effect at all. Besides not sure why the span elements didn't occupy 250px as width was mentioned as 50% of body.
Please help.
Thanks
If you have any container with 500px width and child with 1px border, 10px padding, 100% width and set box-sizing to border-box then the width will be 500px if you set box-sizing to content box then the width will be 500px + 2x10px + 2x1px = 522px.
.container {
display: block;
width: 500px;
}
.one {
display: block;
padding: 10px;
-webkit-box-sizing: border-box;
width: 50%;
border: 1px solid;
}
.two {
display: block;
padding: 10px;
-webkit-box-sizing: content-box;
width: 50%;
border: 1px solid;
}
http://jsfiddle.net/Vaj5x/
EDIT:
If you wanna have tow columns add them float to left. Like here http://codepen.io/Chovanec/pen/cuBpg

how to use box-sizing:border-box on a fluid element with no height assigned?

I have an issue when using box-sizing:border-box on a fluid grid I have built. I have 1 main column and then a secondary column that contains 2 grid items. If I add border-bottom: 2px solid grey to the first grid item in the secondary column box-sizing is ignored which makes the grid look off as the second column is now slightly taller that the main one. Can anyone advise how I can make these look even, I understand that this is probably because I havent set heights but I'm not sure how to work round this?
Here is my JS Fiddle http://jsfiddle.net/97qpV/
CSS
body * {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.featured-news-col {
width: 66.66667%;
float: left;
margin-right: 0%;
display: inline;
border-right: 2px solid grey;
}
.m-news-thumb {
position: relative;
display: block;
}
.sub-article{
border-bottom: 2px solid grey;
}
.sub-article:last-child{
border:none;
}
img {
display: block;
height: auto;
max-width: 100%;
min-width: 100%;
}
.additional-news-col {
width: 33.33333%;
float: right;
}
You'll need to set heights if you want them to be the same height. HTML elements will, by default "shrink-wrap" their contents, and be only as tall as the contents.
box-sizing doesn't change this. What it does change is how height and width are determined when things like margins, paddings, and borders are added.
So, for example, if you have a div with the following:
div {
height: 50px;
width: 50px;
border: 5px solid black;
}
With the default box-sizing (content-box), the calculated size of that div would actually be 60x60px (the height/width, plus the size of the border on both sides). However, with box-sizing: border-box, that border is now counted as part of the box size, making its calculated dimensions 50x50px.
Jeff Kaufman has a good demonstration of how box-sizing works, and why border-box makes more sense.
The boxes only line up when the contents match the ratio 3:2 (eg those 600x400 dummy images). By adding borders the boxes no longer fit that ratio.
I don't think there is any way to make this work with CSS borders. If the final content will be images I suggest making the borders part of the image. Then they will always line up at any size.

How to give border to any element using css without adding border-width to the whole width of element?

How to give border to any element using css without adding border-width to the whole width of element?
Like in Photoshop we can give stroke- Inside , center and outside
I think default css border properties is center like center in photoshop, am i right?
I want to give border inside the box not outside. and don't want to include border width in box width.
outline:1px solid white;
This won't add the extra width and height.
Check out CSS box-sizing...
The box-sizing CSS3 property can do this. The border-box value (as opposed to the content-box default) makes the final rendered box the declared width, and any border and padding cut inside the box. You can now safely declare your element to be of 100% width, including pixel-based padding and border, and accomplish your goal perfectly.
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box; /* Opera/IE 8+ */
I'd suggest creating a mixin to handle this for you. You can find more information on box-sizing at W3c http://www.w3schools.com/cssref/css3_pr_box-sizing.asp
Depending on your intended browser support you can use the box-shadow property.
You can set the blur value to 0 and the spread to what ever thickness you're after. The great thing about box shadow is that you can control whether it is drawn outside (by default) or inside (using the inset property).
Example:
box-shadow: 0 0 0 1px black; // Outside black border 1px
or
box-shadow: 0 0 0 1px white inset; // Inside white border 1px
One great advantage of using box shadow is you can get creative by using multiple box shadows:
box-shadow: 0 0 0 3px black, 0 0 0 1px white inset;
The only thing I can't say is what difference this will make rendering performance wise. I would assume it might become an issue if you had hundreds of elements using this technique on the screen at once.
I ran into the same issue.
.right-border {
position: relative;
}
.right-border:after {
content: '';
display: block;
position: absolute;
top: 0; right: 0;
width: 1px;
height: 100%;
background: #e0e0e0;
}
This answer allows you to specify one single side. And would work in IE8+ - unlike using box-shadow.
Of course change your pseudo elements properties as you need to single out a specific side.
* New and Improved *
&:before {
content: '';
display: block;
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
border: 1px solid #b7b7b7;
}
This allows ability to use border and hit multiple sides of a box.
Use box-sizing: border-box in order to create a border INSIDE a div without modifying div width.
Use outline to create a border OUTSIDE a div without modifying div width.
Here an example:
https://jsfiddle.net/4000cae9/1/
Notes:
border-box currently it is not supported by IE
Support:
http://caniuse.com/#feat=outline
http://caniuse.com/#search=border-box
#test, #test2 {
width: 100px;
height:100px;
background-color:yellow;
}
#test {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
border: 10px dashed blue;
}
#test2 {
outline: 10px dashed red;
}
<p>Use box-sizing: border-box to create a border INSIDE a div without modifying div width.</p>
<div id="test">border-box</div>
<p>Use outline to create a border OUTSIDE a div without modifying div width.</p>
<div id="test2">outline</div>
As abenson said, you can use an outline but one gotcha is that Opera might draw a "non-rectangular shape". Another option that seems to work is to use negative margins, such as this css:
div {
float:left;
width: 50%;
border:1px solid black;
margin: -1px;
}
With this html:
<body>
<div>A block</div>
<div>Another block</div>
</body>
One other less clean option is to add extra markup to the html. For example, you set the width of an outer element and add the border to the inner one. The CSS:
.outer { width: 50%; float: left;}
.inner { border: 1px solid black; }
And the html:
<body>
<div class="outer">
<div class="inner">A block</div>
</div>
<div class="outer">
<div class="inner">Another block</div>
<div>
</body>
Use padding when there is no border. Remove padding when there is a border.
.myDiv {
width: 100px;
height: 100px;
padding-left: 2px;
padding-right: 2px;
}
.myDiv:hover {
padding-left: 0;
padding-right: 0;
border-left: 2px solid red;
border-right: 2px solid red;
}
Essentially, just replace the 2px padding with 2px borders. Div size remains the same.
Usually, layout shifting is the problem.
If you don't need border-radius then outline: 1px solid black; works.
If you do, make the border transparent and change its color when it's supposedto show:
/* RELEVANT */
.my-div {
border-radius: 8px;
border: 2px solid transparent;
}
.my-div:hover {
border: 2px solid #ffffffa8;
}
/* NOT RELEVANT */
.pretty {
color: white;
padding: 10px 20px;
background: #0077b6;
font-size: 16px;
transition: border .15s ease-out;
cursor:pointer;
}
<button class="pretty my-div">
Button
</button>
In your case can you fudge it by subtracting half the border from the padding? (-2.5 from the padding if your border is 5px wide, you can't have negative padding so to go smaller reduce the overall width of the box). You can add an extra 2.5px to the margin to keep the overall box the same size.
I really don't like this suggestion, but I don't think there is a way do handle this cleanly.
Thus, you're trying to achieve the same as the well known IE box model bug? That's not possible. Or you want to support clients with IE on Windows only and choose a doctype which forces IE into quirksmode.
Another option, if your background color is solid:
body { background-color: #FFF; }
.myDiv {
width: 100px;
height: 100px;
border: 3px solid #FFF; // Border is essentially invisible since background is also #FFF;
}
.myDiv:hover {
border-color: blue; // Just change the border color
}
outline:3px solid black || border:3px solid black
div{
height:50px;
width:150px;
text-align:center;
}
div{ /*this is what you need ! */
outline:1px solid black
}
<div>
hello world
</div>

Resources