CSS table border spacing inside only - css

I have trying to work this out for months, and Google hasn't helped me. I'm trying to have spacing between <td> and <th> tags in a table, but when I do, it does spacing in the outside. Therefore, the table isn't inline with anything else. So it looks like the table has some padding.
I can't seem to find a solution.
Here is an example of the issue

I optimized the solution with transparent border so it has no more obliquely cut inner borders.
1) let table fill horizontal and collapse the borders:
table {
width: 100%;
border-collapse: collapse;
}
2) Set all borders of table cells to width 0 and prevent background is drawn below the border.
td {
border: 0px solid transparent;
background-clip: padding-box;
}
3) Set inner space with transparent border but not to first row and column.
tr > td + td {
border-left-width: 10px;
}
tr + tr > td {
border-top-width: 10px;
}
here is a jsbin

Had the same problem, the border spacing property was adding space around the table as well, and to my knowledge, there wasn’t anyway to limit it to only ‘the inside’, so I used transparent borders instead:
table td {
border-left: 1em solid transparent;
border-top: 1em solid transparent;
}
This sets ‘border spacing’ as normal, except that there’s ‘unwanted’ spacing at the top and left of the table.
table td:first-child {
border-left: 0;
}
Selects the first column.
table tr:first-child td {
border-top: 0;
}
Selects the td elements of the first row (assuming that the top of the table starts with a tr element, change accordingly for th).

I found a way to do this with negative margins and improves on Steven's answer in that it lets you make the table take up 100% even if it doesn't have enough content. The solution is to make the table width 100% and use a negative margin on a containing element:
#container {
margin: 0 -10px;
}
table {
border-collapse: separate;
border-spacing: 10px;
}
td, th {
background-color: #ccf;
padding: 5px;
}
See it as a jsFiddle

Similar to what Steven Vachon said, negative margin may be your best bet.
Alternatively, you can use calc() to fix the problem.
CSS:
/* border-collapse and border-spacing are css equivalents to <table cellspacing="5"> */
.boxmp {
width:100%;
border-collapse:separate;
border-spacing:5px 0;
}
/* border-spacing includes the left of the first cell and the right of the last cell
negative margin the left/right and add those negative margins to the width
ios6 requires -webkit-
android browser doesn't support calc()
100.57% is the widest that I could get without a horizontal scrollbar at 1920px wide */
.boxdual {
margin:0 -5px;
width:100.57%;
width:-webkit-calc(100% + 10px);
width:calc(100% + 10px);
}
Just add whatever margin you take off or the width will be too narrow (100% isn't wide enough).

Here is the cool hack to do that
table {
border-collapse: inherit;
border-spacing: 10px;
width: calc(100% + 20px);
margin-left: -10px;
}
use margin-left: -10px; to remove left padding but in the right there will be 20px padding. Now to update it use width: calc(100% + 20px);

Use negative margins and a container with positive padding.
#container {
box-sizing: border-box; /* avoids exceeding 100% width */
margin: 0 auto;
max-width: 1024px;
padding: 0 10px; /* fits table overflow */
width: 100%;
}
table {
border-collapse: separate;
border-spacing: 10px;
margin: 0 -10px; /* ejects outer border-spacing */
min-width: 100%; /* in case content is too short */
}
td {
width: 25%; /* keeps it even */
}
Just make sure that you have substantial content for it to stretch the table to 100% width, or else it'll be 20px too narrow.
More info: svachon.com/blog/inside-only-css-table-border-spacing/

Here is a simple and clean solution.
HTML
<div class="column-container">
<div class="column-children-wrapper">
<div class="column">One</div>
<div class="column">Two</div>
<div class="column">Three</div>
<div class="column">Four</div>
</div>
</div>
CSS
.column-container {
display: table;
overflow: hidden;
}
.column-children-wrapper {
border-spacing: 10px 0;
margin-left: -10px;
margin-right: -10px;
background-color: blue;
}
.column {
display: table-cell;
background-color: red;
}
https://jsfiddle.net/twttao/986t968c/

Related

How to add minimum margin to Zurb Ink email content?

Here is a Plunker I just created: http://plnkr.co/edit/jKo6yavo9fFNHiMsEvAL?p=preview
It is a simple single row layout. What I need is a fixed minimum margin on both sides (left and right) of the row. Let's say 25px. Resizing the window should always show at meast 25px of grey background before and after the row.
I tried modifying the table.container style from:
table.container {
width: 580px;
margin: 0 auto;
text-align: inherit;
}
to
table.container {
width: 580px;
margin: 0 25px 0 25px;
text-align: inherit;
}
But it seems it does not work for the right margin (goes out of the page). Any suggestion?
I think the simplest solution would be to use the left and right table borders instead of margin.
Something like the CSS below should do the trick.
table.container {
width: 580px;
border-left: solid 25px #f1f0ef !important;
border-right: solid 25px #f1f0ef !important;
text-align: inherit;
}
Since not all email clients support margin your other option would be to add padding/border to an outer table/tables.
If you have any questions let me know.

Flexbox with percent width but fixed margins

I'm trying to switch from a CSS grid framework to a flex layout (because of different items height, and flexbox handles that very nicely).
So, this is what I did: http://jsfiddle.net/c3FL2/
.container {
display: flex;
flex-wrap: wrap;
padding: 15px;
background: #9999FF;
}
.g {
background: #FF9999;
border: 1px solid red;
border-radius: 8px;
padding: 15px;
}
.grid-33 {
width: 33.3333%;
}
.grid-50 {
width: 50%;
}
.grid-66 {
width: 66.6666%;
}
.grid-100 {
width: 100%;
}
My question is: how can i add a margin between flex items? I want exactly 15px, not a percentage. If I add that, it breaks the layout because of too much width. Padding is not a solution because I want a border outside elements.
The solution doesn't have to be compatible with old browser, just the latest ones since this will be running on a controlled environment.
Edit: If needed, the HTML can be changed.
The "easiest" way to do this is to use calc(). (It would of course be easier if you didn't have to solve for IE quirks to get there, but the end result is very straightforward.) Your code would look like this:
.container {
padding: 15px 15px 0 0;
}
.g {
margin: 0 0 15px 15px;
}
.grid-33 {
with: calc(33.3333% - 15px);
}
.grid-50 {
width: calc(50% - 15px);
}
.grid-66 {
width: calc(66.6666% - 15px);
}
.grid-100 {
width: calc(100% - 15px); // needed for IE10
}
The reason for using width is because IE10-11 aren't great fans of calc being used together with flex. In this case it's a box-sizing: border-box issue. This example is cross-browser compatible with IE10+.
Demo
(To see vendor prefixes, click "View Compiled" in CSS.)
You might try : background-clip and box-shadow and transparent borders: DEMO
.g {
background: #FF9999;
border: 8px solid transparent;/* you may tune individually border-size to get your 15px */
box-shadow:inset 0 0 0 1px red;/* this will fake your border if set with out blur */
background-clip:padding-box;/* do not show bgcolor under borders */
border-radius: 15px;/* increase value so it has effect deeper seen on inset box-shadow */
padding: 15px;
}
Only tested this in chrome but seems to work
try changing the styles to this:
.g {
//add margin style
margin:15px;
}
.grid-33 {
flex: 1 1 33.3333%;
}
.grid-50 {
flex: 1 1 50%;
}
.grid-66 {
flex: 1 1 66.6666%;
}
.grid-100 {
flex: 1 1 100%;
}
Even though this is old, I had a similar problem. I achieved the margins by adding an extra element and moving the styling to that element. This seems quite robust, calc() no matter how well supported doesn't feel neat enough.
.padder {
background: #FF9999;
border: 1px solid red;
border-radius: 8px;
margin: 0 15px 15px 0;
display:flex;
}
Placing display:flex on the extra element ensures its contents fill the space within.
http://jsfiddle.net/c3FL2/28/

How to add borders to div without messing up the layout?

I have the following elements:
<body>
<div id="container">
<div id="sidebar1"></div>
<div id="content">
<h3>Lorem ipsum</h3>
<p>Whatnot.</p>
</div>
<div id="sidebar2"></div>
</div>
</body>
Following this style:
/* ~~ this fixed width container surrounds all other divs~~ */
#container {
width: 960px;
background-color: #FFF;
margin: 0 auto;
overflow: hidden;
}
#sidebar1 {
float: left;
width: 180px;
/*border: 2px solid black;*/
background-color: #EADCAE;
padding: 0px 0px 100% 0px;
}
#content {
padding: 10px 0;
width: 600px;
float: left;
}
#sidebar2 {
float: left;
width: 180px;
/*border: 2px solid black;*/
background-color: #EADCAE;
padding: 0px 0px 100% 0px;
}
I am trying to achieve this layout: http://jsfiddle.net/QnRe4/
But as soon as I un-comment the borders it turns into this: http://jsfiddle.net/FZxPQ/
** Solved **
The border width was added to each element's total width making them too wide to fit in the container. Removing 2x the border width from each column's width solves the problem: http://jsfiddle.net/FZxPQ/4/
CSS box-sizing to the rescue! This property
alters the default CSS box model used to calculate widths and heights of elements
The border-box value means that
the width and height properties include the padding and border
/* support Firefox, WebKit, Opera and IE8+ */
#container, #sidebar1, #sidebar2 {
box-sizing: border-box;
-moz-box-sizing: border-box;
}
However, browser support is not 100% standardized.
As other answers have already mentioned the extra width which pushes the sidebars out of alignment is because the width calculation includes the border width. box-sizing simply tells the browser that an element with a given width/height should include any border and padding values into the final width/height calculations.
The problem is that when you add in the boarder, the size of the outer divs increased by 4, 2px on each size. So, your container needs to grow in size by 8px.
So change your container to:
#container {
width: 970px;
background-color: #FFF;
margin: 0 auto;
overflow: hidden;
}
See: http://jsfiddle.net/QnRe4/13/
When you apply the borders, that goes outer the divs, so the sidebars will have 184px width which doesn't fits to the container. try addig width: 176px
http://jsfiddle.net/QnRe4/12/
#sidebar1 {
float: left;
width: 176px;
border: 2px solid black;
background-color: #EADCAE;
padding: 0px 0px 100% 0px;
}
Like this? http://jsfiddle.net/QnRe4/3/
What's happening is that your elements are losing their block display properties when you remove the borders.
So, adding display: block to those elements resolves that.
I've also adjusted your element's widths by 4px in width to retain the layout, since removing those borders essentially reduces the space that those elements occupy on-page.

Keeping/scaling DIV Ratio with percentages

At the moment I have a layout that pulls a number of thumbnails into a grid - each is defined by a style that keeps them a fixed ratio, (roughly 16:9) which is defined by pixel dimensions (389px x 230px) but they are looking a bit small on high-res screens.
The images are actually pulled into the DIV as a background that covers 100% width and height of the DIV and then the DIV's obviously control the aspect and size.
What I am looking to do is have these DIV's dynamically resize based on the page size of the device but to keep the ratio of the DIV's.
Is this possible?
My thoughts would be to set the width based on the percentage of the page but then I'm not sure how I would set the height and keep the correct aspect ratio (due to different resolutions etc.)
What would be the best way to do this?
EDIT - Thanks for all your ideas so far, thought maybe I should show you how I'm pulling in the data at the moment.
In my HTML I've got the following code which generated the grid
<a class="griditem" href="../video.php?video=13" style="background-image:url(../video/Relentless/Relentless.jpg); background-size:100% 100%;">
<div class="titles">
<h5>Relentless Short Stories</h5>
<h6>Frank Turner: The Road</h6>
</div>
This is styled with the following CSS
.griditem {
position: relative;
float: left;
margin-right: 17px;
margin-bottom: 17px;
background-color: #777;
-webkit-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.5);
-moz-box-shadow: 0 1px 5px rgba(0, 0, 0, 0.5);
box-shadow: 0 1px 5px rgba(0, 0, 0, 0.5);
-webkit-border-radius: 2px;
-moz-border-radius: 2px;
border-radius: 2px;
width: 389px;
height: 230px;
text-align: left;
}
.titles {
padding: 5px;
position: absolute;
bottom: 10px;
left: -1px;
right: -1px;
background: transparent url(../images/layout/white80.png) top left;
-moz-border-radius: 1px 1px 0 0;
border-radius: 1px 1px 0 0;
text-align: left;
}
The reason I'm implementing it this way is so that the Div can float over the bottom of the image.
Just a quick idea which might be useful for you.
It is based on the fact that vertical padding/margin use the WIDTH of the parent box when it is set to percentages, so it is possible to resize a div relative its parent box
http://jsfiddle.net/xExuQ/2/
body,html { height:100%; }
.fixed-ratio-resize {
width: 50%; /* child width = parent width * percent */
padding-bottom: 50%; /* child height = parent width * percent */
height: 0; /* well, it is not perfect :) */
}
​If you want to put some (non-background) content into this nicely resized box, then put an absolutely positioned div inside it.
Reference:
http://www.w3.org/TR/CSS2/box.html#margin-properties and
http://www.w3.org/TR/CSS2/box.html#padding-properties says:
Margins: "The percentage is calculated with respect to the width of the generated box's containing block. Note that this is true for 'margin-top' and 'margin-bottom' as well. If the containing block's width depends on this element, then the resulting layout is undefined in CSS 2.1."
Paddings:"The percentage is calculated with respect to the width of the generated box's containing block, even for 'padding-top' and 'padding-bottom'. If the containing block's width depends on this element, then the resulting layout is undefined in CSS 2.1."
EDIT
http://jsfiddle.net/mszBF/6/
HTML:
<a class="griditem" href="#" style="background-image: url(http://pic.jpg);">
<span class="titles">
<span class="name">Unicomp Studios</span>
<span class="title">Springs Buckling (2012)</span>
</span>
</a>
CSS:
.griditem {
float: left;
margin-right: 17px;
margin-bottom: 17px;
min-width: 100px; /* extremely narrow blocks ==> crap looking */
width: 30%;
background: blue no-repeat;
background-size: contain; /* from IE9 only: https://developer.mozilla.org/en/CSS/background-size */
border: 1px solid transparent; /* prevent .titles:margin-top's margin collapse */
}
.titles {
/* <a> elements must only have inline elements like img, span.
divs, headers, etc are forbidden, because some browsers will display a big mess (safari) */
display: block; /* so display those inline elements as blocks */
padding: 5px;
margin: 0 auto;
margin-top: 105%;
background: yellow;
}
.titles > span {
display: block;
}​
I know this might not be the best solution, but
<html>
<style type="text/css">
#cool{
width:40%;
background:blue;
padding-bottom:10%;
}
</style>
<div id="cool" >
</div>
</html>
Here Ive used padding-bottom, to maintain its height relative to its width. U can set padding-bottom as a percentage. Hope this helped.

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