Overlap outlines in css - css

I have an HTML structure with many divs next to each other or below each other that all have an outline. The problem is, these outlines do not overlap, but are shown next to each other (or on top of each other). To illustrate, this is what happens:
This is my code, with added nth-child() selectors to clearly show the issue:
.wrapper {
/* getting rid of the 'inline-block whitespace' */
font-size: 0;
white-space: nowrap;
}
.cell {
display: inline-block;
font-size: 2rem;
padding: 2px;
width: 100px;
}
.cell:nth-child(even) {
outline: 6px solid blue;
}
.cell:nth-child(odd) {
outline: 6px solid red;
}
<div class="wrapper">
<div>
<div class="cell">
one
</div>
<div class="cell">
two
</div>
</div>
<div>
<div class="cell">
three
</div>
<div class="cell">
four
</div>
</div>
</div>
My question is: How to make these outlines overlap so no 'doubles' are shown?
Update: using half the margin of the width of the outline on the cells does not always work when the outline width is 1px. For example, when the padding of .cell is 4px this is the result (when you zoom in you will see the two lines).
Update2: it seems this is a bug with Firefox on a 4k display. Running this in Firefox on a display with a HD resolution or in another browser (tested Chrome) works.

apply a margin equal to half the outline:
.wrapper {
/* getting rid of the 'inline-block whitespace' */
font-size: 0;
white-space: nowrap;
}
.cell {
display: inline-block;
font-size: 2rem;
padding: 2px;
width: 100px;
margin: 3px; /* added */
}
.cell:nth-child(even) {
outline: 6px solid blue;
}
.cell:nth-child(odd) {
outline: 6px solid red;
}
<div class="wrapper">
<div>
<div class="cell">
one
</div>
<div class="cell">
two
</div>
</div>
<div>
<div class="cell">
three
</div>
<div class="cell">
four
</div>
</div>
</div>
Or use margin on one side:
.wrapper {
/* getting rid of the 'inline-block whitespace' */
font-size: 0;
white-space: nowrap;
}
.cell {
display: inline-block;
font-size: 2rem;
padding: 2px;
width: 100px;
margin:0 6px 6px 0; /* added */
}
.cell:nth-child(even) {
outline: 6px solid blue;
}
.cell:nth-child(odd) {
outline: 6px solid red;
}
<div class="wrapper">
<div>
<div class="cell">
one
</div>
<div class="cell">
two
</div>
</div>
<div>
<div class="cell">
three
</div>
<div class="cell">
four
</div>
</div>
</div>

Related

Account for gap when calculating flex-basis

I'm trying to use gap to specify gaps between flexed items within my grid system, but running in to a major drawback. It seems that when you're using flex-grow: 0;/flex-shrink: 0; in conjunction with gap and flex-basis values that fill the entire available width (i.e. three columns with flex: 0 0 33.3333%;), the columns overflow their parent container as the gap doesn't account for the fixed width as specified with flex: 0 0 33.3333%.
Similar to box-sizing: border-box;, is there some way to instruct the rendering engine that the gap should be subtracted when determining the width of these columns?
Demonstration:
.row {
display: flex;
gap: 30px;
border: 2px solid red;
}
.col {
flex: 0 0 33.3333%;
background: teal;
border: 2px solid #004D4D;
color: white;
font-weight: 700;
padding: 50px;
text-align: center;
}
:root {
font-family: sans-serif;
}
* {
box-sizing: border-box;
}
<h2>With gap:</h2>
<div class="row">
<div class="col">
1
</div>
<div class="col">
2
</div>
<div class="col">
3
</div>
</div>
<h2>Without gap:</h2>
<div class="row" style="gap:0;">
<div class="col">
1
</div>
<div class="col">
2
</div>
<div class="col">
3
</div>
</div>
Note: I could account for this with a formula like flex-basis: calc($width - ($gap / ($number-of-columns / 2));, but as this is for a reusable grid system, I can't practically account for every possible scenario.
Here is another not very elegant quick way to hack your way forward. Similar to the answer by UPinar it alters the outer flex container. Here with negative margin on the right (this might cause other layout problems!). This "solution" is using shrink 0. Also it works with a wrapping flex.
I agree that this should not be so complicated and hacky. Maybe we are missing something? I am also under the impression that this is not the really the desired box-sizing border-box behavior which I hoped to find in combination with the gap property.
flex and gap should be hack free like: Draw three containers each consuming a third of the width and have some space between em. AFAIK gap works that way with CSS grid and CSS columns.
.flex {
display: flex;
flex-grow: 0;
flex-shrink: 0;
flex-wrap: wrap;
}
.flex.gap {
gap: var(--space-s);
margin-right: calc(-1 * var(--space-s));
}
.col {
flex-basis: 33.3333%;
background: teal;
border: 2px solid #004D4D;
color: white;
font-weight: 700;
padding: 50px;
text-align: center;
}
.flex.gap .col {
flex-basis: calc(33.3333% - var(--space-s));
background: teal;
border: 2px solid #004D4D;
color: white;
font-weight: 700;
padding: 50px;
text-align: center;
}
:root {
font-family: sans-serif;
--space-s: 1rem;
}
* {
box-sizing: border-box;
}
<h2>With gap</h2>
<div class="flex gap">
<div class="col">
1
</div>
<div class="col">
2
</div>
<div class="col">
3
</div>
<div class="col">
4
</div>
<div class="col">
5
</div>
<div class="col">
6
</div>
</div>
<h2>Without gap</h2>
<div class="flex">
<div class="col">
1
</div>
<div class="col">
2
</div>
<div class="col">
3
</div>
<div class="col">
4
</div>
<div class="col">
5
</div>
<div class="col">
6
</div>
</div>
The formula you mentioned works... you can use CSS variables to make a reuseable grid system. A buddy and I came up with this:
.flex{
--columns:3;
--gap:30px;
--gap-count:calc( var(--columns) - 1 );
display:flex;
gap:var(--gap);
}
.flex-child {
flex-basis: calc( calc( 100% / var(--columns) ) - calc( var(--gap) / var(--columns) * var(--gap-count) ) );
}
#media (max-width: 992px) {
.flex{
--columns:2;
}
}
#media (max-width: 767px) {
.flex{
--columns:1;
}
}
So then all you need to change are the variables --columns and --gap
https://codepen.io/pyledigital/pen/mdWmjQb
When you add a padding-right: calc(var(--gap-space) * 2); to parent container. Parent container width will calculte before child containers use 100% which is parent container width. You need to change parent containers width before using its width inside child container.
*,
*::before,
*::after {
box-sizing: border-box;
}
body {
min-height: 100vh;
text-rendering: optimizeSpeed;
line-height: 1.5;
margin: 0;
background-color: bisque;
display: grid;
place-content: center;
}
:root{
--gap-space:30px;
font-family: sans-serif;
}
.row-1 {
display: flex;
gap: var(--gap-space);
border: 2px solid red;
padding-right: calc(var(--gap-space) * 2);
}
.row-1 .col{
background: teal;
border: 2px solid #004D4D;
color: white;
font-weight: 700;
padding: 50px;
text-align: center;
flex: 0 0 calc(100% / 3);
}
.row-2{
display: flex;
flex-direction: row;
border: 2px solid red;
}
.row-2 .col{
background: teal;
border: 2px solid #004D4D;
color: white;
font-weight: 700;
padding: 50px;
text-align: center;
flex: 0 0 calc(100% / 3);
}
<h2>With gap:</h2>
<div class="row-1">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
</div>
<h2>Without gap:</h2>
<div class="row-2" style="gap: 0">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
</div>
What's wrong with using only width?
.col {
width: 33.3333%;
...
}
.row {
display: flex;
gap: 30px;
border: 2px solid red;
}
.col {
width: 33.3333%;
background: teal;
border: 2px solid #004D4D;
color: white;
font-weight: 700;
padding: 50px;
text-align: center;
}
:root {
font-family: sans-serif;
}
* {
box-sizing: border-box;
}
<h2>With gap:</h2>
<div class="row">
<div class="col">
1
</div>
<div class="col">
2
</div>
<div class="col">
3
</div>
</div>
<h2>Without gap:</h2>
<div class="row" style="gap:0;">
<div class="col">
1
</div>
<div class="col">
2
</div>
<div class="col">
3
</div>
</div>

CSS Text align when wrapping

I'm having trouble aligning text when the window is resized, e.g. on mobile.
Here's the HTML:
.count-panel {
float: left;
width: 64px;
border: 1px #888 solid;
}
.count {
font: 15px/18px Roboto, sans-serif;
font-size: 42px;
}
.message {
font-size: 20px;
}
.row {
clear: both;
margin-bottom: 16px;
}
<div class='table'>
<div class='row'>
<div class='count-panel'>
<span class='count'>1</span>
</div>
<div class='message'>This is line one</div>
</div>
<div class='row'>
<div class='count-panel'>
<span class='count'>2</span>
</div>
<div class='message'>This is line two which is longer than the rest so it can test wrapping</div>
</div>
<div class='row'>
<div class='count-panel'>
<span class='count'>3</span>
</div>
<div class='message'>This is line three</div>
</div>
At larger sizes: Larger
At smaller sizes: Smaller
I need the text in the second line to align with the others and not wrap hard left as in the image. Thanks.
That behaviour on mobile is due to the float applied to the .count-panel element. You could instead use flexbox and clean a bit the css code, like so:
Codepen demo
.count-panel {
border: 1px #888 solid;
flex: 0 0 64px;
}
.count {
font: 15px/18px Roboto, sans-serif;
font-size: 42px;
}
.message {
font-size: 20px;
}
.row {
margin-bottom: 16px;
display: flex;
}
It's just your float: left that's taking the count-panel out of sync.
I have replaced your example with display: flex instead. I would suggest avoiding float when positioning your elements as it was never intended to be used for layout. Flex is a much cleaner solution and I think it gives you more flexibility of layout choices. :-)
I've also amended the HTML layout slightly to include the border on the number itself so that it doesn't stretch the full size of the text content on smaller devices.
.count {
font: 42px Roboto, sans-serif;
min-width: 64px;
border: 1px #888 solid;
text-align: center;
max-height: max-content;
}
.message {
font-size: 20px;
}
.row {
display: flex;
flex-direction: row;
margin: 0 10px 16px 0;
}
<div class='table'>
<div class="row">
<span class="count">1</span>
<div class="message">This is line one</div>
</div>
<div class="row">
<span class="count">2</span>
<div class="message">This is line two which is longer than the rest so it can test wrapping</div>
</div>
<div class="row">
<span class="count">3</span>
<div class="message">This is line three</div>
</div>
</div>

Set space between columns, so each column is same size (using foundation)

I'm trying to make some space between my columns, but can't seem to find the right solution.
Code:
<div class="content wrapper">
<div class="row">
<div class="red window border-right column small-12 medium-3">
Section 1
</div>
<div class="green window border-left border-right column small-12 medium-3">
Section 2
</div>
<div class="blue window border border-left border-right column small-12 medium-3">
Section 3
</div>
<div class="yellow window border-left column small-12 medium-3">
Section 4
</div>
</div>
</div>
Have tried setting classes as border-right, border-left on the columns, but then, the left and right column will be bigger in size than the two in the middle (I'm using middle-3, so have 4 columns).
Image:
Css:
.window {
background-color: white;
height: 450px;
}
.window.border-left {
border-left: 8px solid #EAEDEE;
}
.window.border-right {
border-right: 8px solid #EAEDEE;
}
.yellow {
background-color: yellow;
padding: 1rem;
}
.red {
background-color: red;
padding: 1rem;
}
.blue {
background-color: cadetblue;
padding: 1rem;
}
.green {
background-color: green;
padding: 1rem;
}
Is this possible, without applying it global?
please you can try this, i hope you need this.
CSS:
.content.wrapper {
float: left;
width: 100%;
}
.row {
float: left;
margin: 0;
width: 100%;
}
.window {
background-color: white;
height: 450px;
}
.window.border-left {
border-left: 8px solid #EAEDEE;
}
.window.border-right {
border-right: 8px solid #EAEDEE;
}
.yellow {
background-color: yellow;
padding: 1rem;
}
.red {
background-color: red;
padding: 1rem;
}
.blue {
background-color: cadetblue;
padding: 1rem;
}
.green {
background-color: green;
padding: 1rem;
}
.border-right, .border-left {
float: left;
width: 25%;
}
See Bootply Updeted Demo
Could please try this code
<div class="content wrapper">
<div class="row" data-equalizer="">
<div class="column small-12 medium-3">
<div class="red window border-right" data-equalizer-watch="">Section 1</div>
</div>
<div class="border-right column small-12 medium-3">
<div class="green window border-left" data-equalizer-watch="">Section 2</div>
</div>
<div class="border-left border-right column small-12 medium-3">
<div class="blue window border" data-equalizer-watch="">Section 3</div>
</div>
<div class="column small-12 medium-3">
<div class="yellow window border-left" data-equalizer-watch="">Section 4</div>
</div>
</div>
</div>
I have modified only the HTML part. you can use the same css
.row {
.row {
display:flex;
justify-content:space-between;
}
`.row div {
flex:0 1 23%;
}`
be sure to use http://autoprefixer.github.io/
try this...
in a include your head part this link.
this link is zurb foundation css.
https://cdnjs.cloudflare.com/ajax/libs/foundation/6.2.3/foundation-flex.css

Why the spurious excess separation between divs?

This jsFiddle shows the problem.
The spacing (shown in white) between the innermost divs (shown in blue) should be the same as the outermost div's padding (20px, shown in green), but it's not hard to see that it's greater.
This is can be seen even more clearly in the lower series, in which a translucent 20px outline (in light orange) has been added to the even-numbered innermost divs.
Why is there extra spacing between the innermost divs?
And now, the obligatory code:
<div class="outermost">
<div class="row">
<div class="innermost"></div>
<div class="innermost"></div>
<div class="innermost"></div>
<div class="innermost"></div>
<div class="innermost"></div>
<div class="innermost"></div>
</div>
</div>
<div class="outermost">
<div class="row">
<div class="innermost"></div>
<div class="innermost"></div>
<div class="innermost"></div>
<div class="innermost"></div>
<div class="innermost"></div>
<div class="innermost"></div>
</div>
</div>
html {
font-family: consolas, monaco, courier, monospace;
font-size: 16px;
}
body {
padding: 5px;
max-width: 530px;
}
div {
margin: 0;
border: 0;
}
div:not(.row) {
display: inline-block;
vertical-align: top;
overflow: auto;
padding: 20px;
cursor: default;
}
.outermost {
background: #c3cd84;
}
.row {
display: block;
padding: 0;
white-space: nowrap;
background: #fff;
}
div.row > :not(:first-child) {
margin-left: 20px;
}
.innermost {
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
background: #90b2c0;
}
.outermost:last-child {
margin-top: 20px;
}
.outermost:last-child .innermost:nth-child(even) {
outline: 20px solid rgba(243, 204, 152, 0.6);
}
Inline elements are sensitive to the white space in your code. One way to deal with this is to simply remove the white space:
</div><div class="innermost">
jsFiddle example
Another option is to use HTML comments:
</div><!--
--><div class="innermost">
jsFiddle example
Yet another way is to set the font size on the parent element to zero:
.row {
display: block;
padding: 0;
white-space: nowrap;
background: #fff;
font-size:0;
}
jsFiddle example

three divs next to each other with two rows (six divs in total). if I do float they all go in one row

So I got a question about DIVs. I want 2 rows with 3 divs in each, centered. But the problem is if I do clear: left; all 6 will be next o eachother. Here is how my code looks like right now and I hope you can help me out.
CSS:
.row1 {
position: absolute;
height: 270px;
}
.row2 {
position: absolute;
height: 270px;
}
.columns {
width: 190px;
height: 274;
border-top: 1px solid #EBEBEB;
border-right: 1px solid #EBEBEB;
padding-top: 25px;
padding-right: 15px;
padding-bottom: 25px;
padding-left: 15px;
}
Here is my HTML:
<div id="row1">
<div class="columns"> </div>
<div class="columns"> </div>
<div class="columns"> </div>
</div>
<div id="row2">
<div class="columns"> </div>
<div class="columns"> </div>
<div class="columns"> </div>
</div>
this is one div:
head text
paragraph text
They are all floating next to each other. You should add a clear row where you want to seperate them. We usually call it clearfix.
<style>
.clearfix{ clear:both; }
</style>
</div>
<div class="clearfix"></div>
<div id="row2">
Try to use "display: inline-block" instead of float and remove "position: absolute". Add closing divs for the columns. And change css for the rows to refer to id, not class.
CSS:
.columns {
display: inline-block;
width: 190px;
border-top: 1px solid #EBEBEB;
border-right: 1px solid #EBEBEB;
}
#row1 {
height: 270px;
}
#row2 {
height: 270px;
}
HTML:
<div id="row1">
<div class="columns">1.1</div>
<div class="columns">1.2</div>
<div class="columns">1.3</div>
</div>
<div id="row2">
<div class="columns">2.1</div>
<div class="columns">2.2</div>
<div class="columns">2.3</div>
</div>
JsFiddle: http://jsfiddle.net/a5vKH/1/

Resources