Flexbox with percent width but fixed margins - css

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/

Related

Placing a single black border around the popup image in Magnific Popup

I haven't been able to find any info on the web to help me out here. Using Magnific Popup I'd like my popup images to display with a single black border. Ive gone into the Magnific-popup.css file and added the following:
/* Main image in popup */
img.mfp-img {
width: auto;
max-width: 100%;
height: auto;
display: block;
line-height: 0;
/*my attempt at adding a border around the image */
**border: 2px solid red;**
/* end attempt */
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 40px 0 40px;
margin: 0 auto; }
What I'm getting is a red border in the display area, adding a black greyish border around the image.
Has anyone done this before? Thanks in advance.
The issue is caused by the padding that has been set to the image, try replacing the padding with margin like this:
img.mfp-img {
padding: 0;
margin: 40px auto;
/*Add your border*/
border: 2px solid red;
}
Also I must note that modifying core files for any plugin is considered bad practice because it makes upgrading to a newer version more difficult, I suggest you create a separate CSS file to override or add any custom styles.
The best way I have found to do this is to remove the padding from the image and apply it to a before and after pseudo class on the figure like so
img.mfp-img {
padding: 0;
border: 2px solid red;
}
.mfp-figure figure::before {
padding-top: 40px;
display: block;
content: "";
}
.mfp-figure figure::after {
padding-bottom: 40px;
display: block;
content: "";
}

How do i wrap a parent div to the width of a child div (dialog)?

Jsfiddle to demonstrate my issue.
I have a SPA (Single Page Application).
In the appliation several dialogs can popup on the screen.
Every popup has it own width and height.
The title and content of the dialogs are added by angularJs
The problem i have here is the size of the dialog.
Currently all popups are made and added seperatly. I want to change this into one popup with variable content. The problem that comes with this is that the popup must wrap the contents width.
Example (as shown in the Jsfiddle)
<div class="dialog">
<div class="titlebar"></div>
<div class="content">
The content that is added has css that tells it has a width of 400px
This means the dialog needs to wrap to this 400px
</div>
</div>
How do i solve this by only using CSS?
Some examples of the variation of popups (although the width of both look the same, this is not the case)
Use display:table for the dialog.
Here is your Updated Fiddle.
For young browser you may use :
1) display:flex; property (includes centering) DEMO
.backdrop {
position: fixed;
top:0;
}
.backdrop {
width: 100%;
height: 100%;
z-index: 100;
background-color: rgba(0, 0, 0, 0.2);
display: flex;
align-items: center;
justify-content: center;
}
.dialog {
margin:auto;
position:relative;
}
2) max-content as value for width and not set any width to inner
content . (exept some padding to keep room for the close button) :
DEMO
Info on W3C about those new keywords value, soon avalaible i hope.
CSS updated
.dialog {
width: max-content;
z-index: 101;
margin: auto;
/* basic way t o center */
top:50%;
left:50%;
margin:-80px -150px;
}
.titlebar {
height: 50px;
line-height: 50px;
background-color: #000000;
border-radius: 10px 10px 0px 0px;
}
.title{
color:#FFFFFF;
font-size: x-large;
padding:0 50px 0 10px;
}
.close_button {
position: absolute;
right: 0px;
top: 0px;
line-height:30px;
padding: 5px;
margin: 5px;
border-radius: 10px;
background-color: #ffd549;
color: #000000;
}
.content {
background-color: #FFFFFF;
}
.content-width {
background-color:#FFF000;
}
or as already said , use the display: table, inline-table
Using display: inline-block; text-align: center;
Works in ie >= 8.
Fiddle.
I don't understand the problem.
If you want to center the content-width div element, simply add margin: auto;.
If you want the container to fit the WIDTH of its content, you must change the display property from block to something else, like inline-block or table (as suggested by #jacelysh).
What is it exactly that you are trying to do?
A div without a set width will take up the width of the parent.
try this.
.content {
background-color: #FFFFFF;
min-width: 100%;
}
.content-width {
width: 100%;
background-color:#FFF000;
}
http://jsfiddle.net/VQA4k/6/
Checking again now. You can just remove the width from those two classes and it will work.
This is what you want I think.
http://jsfiddle.net/VQA4k/16/

Align <hr> to the left in an HTML5-compliant way

Currently, I'm using
<hr align="left" />
on my HTML5 page, but I've read that the align property was deprecated in XHTML 4.01 and supposedly removed from HTML5. I'd like to be using CSS rather than an inline attribute like this, but when I tried
hr{align: left; max-width: 800px;}
or hr{text-align: left;} or hr{left: 0;} or hr{float: left;}, it just showed up in the center.
So what should I use instead of the inline attribute above?
One option would be to set the left margin to zero:
hr{max-width: 800px; margin-left:0;}
You're trying to use something in a way that (as Eliezer Bernart mentions.. and apparently that comment with the link to the MDN doc disappeared) no longer "works that way". You can, as long as you don't mind it being screwy in IE, just set the margin to zero - http://jsfiddle.net/s52wb/
hr {
max-width: 100px;
margin: 0px;
}
A better idea though would be to mimic the HR's old way of doing things by way of CSS without the use of the HR. Check out http://jsfiddle.net/p5ax9/1/ for a demo:
p:first-child:before {
display: none;
}
p:before {
content: " ";
border: 1px solid black;
margin-top: 15px;
margin-bottom: 15px;
display: block;
max-width: 100px;
}
I don't know what browsers were used for some above answers, but I found neither text-align:left nor margin-left:0 worked in both IE (11, Standards mode, HTML5) and Firefox (29).
IE11: text-align:left works, margin-left:0 leaves rule centred.
FF: margin-left:0 works, text-align:left leaves rule centred.
So, either use both, or I found that margin-right:100% works for both!
You can use div tag instead.
<div style="border: thin solid lightgray; width: 100px;"></div>
do this
hr {
display: inline; //or inline-block
text-align: left;
}
<hr> tags have margin-inline-start and margin-inline-end properties set to auto, which centers the element horizontally (similar to setting both left and right margins of an element to auto).
To left-align an hr tag, you can set margin-inline-start to 0:
hr {
margin-inline-start: 0;
}
...and you can right-align an hr tag by setting margin-inline-end to 0:
hr {
margin-inline-end: 0;
}
.line {
height: 2px;
background-color: var(--itemBorder);
color: var(--itemBorder);
}
.width100 {
width: 100% !important;
}
.width90 {
width: 90% !important;
}
.width80 {
width: 80% !important;
}
.width70 {
width: 70% !important;
}
.width60 {
width: 60% !important;
}
.width50 {
width: 50% !important;
}
.width40 {
width: 40% !important;
}
.width30 {
width: 30% !important;
}
.width20 {
width: 20% !important;
}
.width10 {
width: 10% !important;
}
<div class="line width100" />

Margin behavior of "overflow:hidden" div after floating div on webkit

I've found that an "overflow:hidden" div following a "float:left" div has doubled margin on the right. This can be tested with following code:
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
div.intro {
border: 1px solid #DBDBDB;
margin: 10px 0;
padding: 10px 0;
}
div.intro>div {
border: 1px solid #DBDBDB;
height: 150px;
margin: 0 10px;
}
div.brief {
float: left;
width: 150px;
}
div.list {
overflow: hidden;
}
</style>
</head>
<body>
<div class="intro">
<div class="brief"></div>
<div class="list"></div>
</div>
</body>
</html>
The space between right border of div.list and right border of div.intro is 20px in chrome(17.0.963.56 m) and safari(5.1.2), while being 10px in Firefox(11.0) and IE9.
Is this a bug of webkit or just an undefined preference of css?
Thanks!
I was able to reproduce this on Chrome for Mac, 17.0.963.56.
The problem stems from the fact you've given #brief and #list a height, but haven't contained the float. There actually isn't a double margin; the margin-right of 10px is combining with .intro's 10px padding-right to give the allusion of a 20px double-margin.
All things considered, the fact the WebKit (Chrome's & Safari's renderer), rendered things that way is a little strange.
Everything worked as expected with this CSS (see the Fiddle):
.intro {
margin: 0 0 20px;
padding: 20px;
background: #FFA;
overflow: auto;
height: 100%;
}
.brief {
background: rgba(255, 0, 0, 0.25);
width: 150px;
float: left;
}
.list {
background: rgba(0, 0, 255, 0.25);
margin: 0 0 0 170px;
}
The above solution seems to do the trick as long as the width of your floating element is static and predictable (as the margin of the non-floating div is set to span the floating div's width, plus the required space between the two).
If, however, you're working with a floating div with a dynamic width, you can target what appears to be a Webkit-specific issue with a -webkit-margin-start property which all other browsers will ignore:
.div.list {
overflow: hidden;
-webkit-margin-start: 0px !important; /* you can ditch the 'important' by adding 'div.intro' to the front of your selector */
}
This effectively sets div.list's margin-left: 0 in Webkit only, while accommodating a dynamic width for your floating div. Unfortunately, I haven't been able to test this in Chrome 19b yet, so I'm not sure how it'll handle this kludge.

CSS table border spacing inside only

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/

Resources