why body overflow not working? - html

Why body overflow:hidden not working when viewport height is grater then css height?
ViewPort height is >700px and
css height is 300px
codepen http://codepen.io/vinaymavi/pen/aNMVYX
div{
border: 1px dashed;
height:55px;
}
body{
padding:10px;
width:100%;
height:300px;
border:2px solid red;
overflow:hidden;
}
<html>
<body>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
</body>
</html
Output

From the CSS 2.2 spec for the overflow property
UAs must apply the 'overflow' property set on the root element to the
viewport. When the root element is an HTML "HTML" element or an XHTML
"html" element, and that element has an HTML "BODY" element or an
XHTML "body" element as a child, user agents must instead apply the
'overflow' property from the first such child element to the viewport,
if the value on the root element is 'visible'.
That is, overflow:hidden set on the body element, is moved to apply to the viewport instead. To avoid that happening, you can set the <html> element to not be overflow:visible.
i.e. add html { overflow:auto; } to the CSS.

Consider use a wrap around all divs. Like this:
<main class="main">
<div>1</div>
<div>2</div>
<div>3</div>
...
</main>
.main{
padding:10px;
width:100%;
height:300px;
border:2px solid red;
overflow: hidden;
}

Try overflow: auto; if you want the overflow to be visible with a scroll or overflow: hidden; if you want to hide it.
Also, Use parent div instead of using the body as the container..
See this:
div{
border: 1px dashed;
height:55px;
}
#container{
padding:10px;
width:80%;
height:300px;
border:2px solid red;
overflow: auto;
word-wrap: break-word;
}
<html>
<body>
<div id="container">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
</div>
</body>
</html>

You need to define css for html as well as for body:
div{
border: 1px dashed;
height:55px;
}
html, body{
padding:10px;
margin: 0;
width:100%;
height:300px;
border:2px solid red;
overflow:hidden;
}

div {
border: 1px dashed;
height: 55px;
background-color:yellow;
}
body {
padding: 10px;
width: 500px;
height: 300px;
border: 2px solid red;
overflow: hidden;
}
.content {
height: 100%;
background-color: red;
overflow: hidden;
}
<html>
<body>
<div class="content">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
</div>
</body>
</html>

Add you divs inside a wrapper
div {
border: 1px dashed;
height: 55px;
background-color:yellow;
}
body {
padding: 10px;
width: 500px;
height: 300px;
border: 2px solid red;
overflow: hidden;
}
.content {
height: 100%;
background-color: red;
overflow: hidden;
}
<html>
<body>
<div class="content">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
</div>
</body>
</html>

Related

Avoid double border when aligning elements with flex [duplicate]

Given the current CSS grid example, how can I collapse the borders in order to avoid the double borders ?
This is such a simple thing to achieve using an Html table. How do I do it using display: grid ?
.wrapper {
display: grid;
grid-template-columns: 50px 50px 50px 50px;
}
.wrapper > div {
padding: 15px;
text-align: center;
border: 1px solid black;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
Instead of using an actual border around grid items, use the background color on the container (for "border" color) and the grid-gap property (for "border" width).
.wrapper {
display: inline-grid;
grid-template-columns: 50px 50px 50px 50px;
border: 1px solid black;
grid-gap: 1px;
background-color: black;
}
.wrapper > div {
background-color: white;
padding: 15px;
text-align: center;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
You may do like this :
.wrapper {
display: inline-grid;
grid-template-columns: 50px 50px 50px 50px;
border-bottom: 1px solid black;
border-left: 1px solid black;
}
.wrapper > div {
padding: 15px;
text-align: center;
border-top: 1px solid black;
border-right: 1px solid black;
}
body {
background:pink;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
Another idea is to rely on gradient to fill gaps like below:
.wrapper {
display: inline-grid;
grid-template-columns: 50px 50px 50px 50px;
grid-gap:1px;
background:
linear-gradient(#000,#000) center/100% 1px no-repeat,
repeating-linear-gradient(to right,transparent 0 50px,#000 0 51px);
border:1px solid;
}
.wrapper > div {
padding: 15px;
text-align: center;
}
body {
background:pink;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
You can also adjust the initial solution to make it more flexible and it will work with any number of items inside a row.
Run the below code on full page and resize the window:
.wrapper {
display: grid;
max-width:800px;
grid-template-columns: repeat(auto-fill,minmax(100px,1fr));
border-top: 1px solid black;
border-left: 1px solid black;
}
.wrapper > div {
padding: 15px;
text-align: center;
border-bottom: 1px solid black;
border-right: 1px solid black;
}
body {
background:pink;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
</div>
I found a solution by using the outline property.
.grid {
width: 100%;
height: 700px;
display: grid;
grid-template-columns: repeat(4, 25fr);
grid-template-rows: repeat(4, 25fr);
margin-bottom: 30px;
grid-gap: 1px;
}
.grid-item {
background-color: silver;
outline: 1px solid gray; /* The outline creates the border */
text-align: center;
position: relative;
z-index: 1; /* original z-index */
}
/* If you want to change the color on the hover state */
.grid-item:hover {
outline: 1px solid red;
z-index: 2; /* You must apply a z-index bigger than the original z-index or else some parts of the outline will be behind other grid elements */
}
<div class="grid">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
</div>
.wrapper {
display: grid;
grid-template-columns: 50px 50px 50px 50px;
}
.wrapper > div {
padding: 15px;
text-align: center;
border: 1px solid black;
margin:0 -1px -1px 0;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
margin:0 -1px -1px 0;
This should do the trick.
There is an easy way to do this:
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 1px;
}
.grid__item {
border: 1px solid gray;
box-sizing: content-box;
width: 100%;
height: 100%;
}
<div class="grid">
<div class="grid__item">1</div>
<div class="grid__item">2</div>
<div class="grid__item">3</div>
<div class="grid__item">4</div>
<div class="grid__item">5</div>
<div class="grid__item">6</div>
<div class="grid__item">7</div>
<div class="grid__item">8</div>
<div class="grid__item">9</div>
<div class="grid__item">10</div>
<div class="grid__item">11</div>
<div class="grid__item">12</div>
</div>
P.s. The main trick here is in box-sizing: content-box. You don't need it if you do not globally override it with another value. But many people uses border-box, in that case, this override solves the problem with the gap.
Something I've used with success is simply adding a box shadow to the grid items, along with a column and row gap. This then allows the columns size to always be exactly as determined in grid-template-columns.
Then simply changing the column and row gap and box shadow size allows for a thicker border.
.wrapper {
display: grid;
grid-template-columns: 50px 50px 50px 50px;
grid-column-gap: 1px;
grid-row-gap: 1px;
}
.wrapper > div {
padding: 15px;
text-align: center;
box-shadow: 0 0 0 1px;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
For anyone who will struggle with an odd number of elements and a specific amount of frames you can use the following approach
<style>
.wrapper {
width: 100%;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
border: 1px solid;
grid-gap: 1px;
}
.element {
display: flex;
flex-direction: column;
background-color: azure;
min-height: 10rem;
border: 1px solid;
margin: -1px;
}
</style>
<body>
<div class="wrapper">
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
</div>
</body>
https://codepen.io/sergeytkhojevskiy/pen/XWZOJOL
The win-win code would be to set
grid items: border-bottom & border-right
grid wrapper: border-top & border-left
So it would correct even if top columns not equal to bottom columns
.wrapper {
display: inline-grid;
grid-template-columns: 50px 50px 50px 50px;
border-top: 1px solid black;
border-left: 1px solid black;
}
.wrapper > div {
padding: 15px;
text-align: center;
border-bottom: 1px solid black;
border-right: 1px solid black;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
</div>
If you will fix the number of item per row this solution will fit you,
this example for 3 each row, but you can edit
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr;
gap: 0;
grid-template-areas: '. . .';
}
.grid-item {
order: 0;
flex: 0 1 auto;
text-align: center;
padding: 1rem;
font-size: 12px;
background-color: #e8e8e8;
border-color: #000;
border-style: solid;
border-width: 0;
border-right-width: 1px;
border-bottom-width: 1px;
}
/*first 3 items*/
.grid-item:nth-child(-n + 3) {
border-top-width: 1px;
}
/*last item on each row*/
.grid-item:nth-child(3n + 0) {
border-right-width: 1px;
background-color: cadetblue;
}
/*first item on each row*/
.grid-item:first-child,
.grid-item:nth-child(3n + 1) {
border-left-width: 1px;
background-color: red;
}
/*middel item on each row (not used)*/
.grid-item:nth-child(3n - 1) {
// border-left-width: 1px;
background-color: yellow;
}
/*last item (not used)*/
.grid-item:last-child {
// border-left-width: 0;
background-color: green
}
<div class="grid-container">
<div class="grid-item"> 1 </div>
<div class="grid-item"> 2 </div>
<div class="grid-item"> 3 </div>
<div class="grid-item"> 1 </div>
<div class="grid-item"> 2 </div>
<div class="grid-item"> 3 </div>
<div class="grid-item"> 1 </div>
<div class="grid-item"> 2 </div>
</div>

Make divs overflow and allow horizontal scroll (dynamic amount of divs)

This is an example of my current code:
.parent div{
background: #fff;
padding: 1rem;
text-align: center;
width: 200px;
border-radius: 5px;
margin: 16px;
box-shadow: 0 3px 6px 0 rgba(0,0,0,0.1);
display: inline-block;
}
<div class="parent">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
As you can see they go below each other. I know I can wrap them in a div with a 100000px width but I don't want it to be white space, I want the user to be able to scroll up to the last item and that's it. Is there a way to do this without involving JS?
Probably many ways to do that - I would use flexbox which creates a row by default and then can overflow the parent and set the flex-basis to 200px on the divs.
.parent {
display: flex;
width: 100%;
overflow-x: auto;
}
.parent div{
background: #fff;
padding: 1rem;
text-align: center;
width: 200px;
border-radius: 5px;
margin: 16px;
box-shadow: 0 3px 6px 0 rgba(0,0,0,0.1);
flex: 1 0 200px; // grow but not shrink, 200px basis
}
<div class="parent">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>

CSS Grid: border between all elements in the grid [duplicate]

Given the current CSS grid example, how can I collapse the borders in order to avoid the double borders ?
This is such a simple thing to achieve using an Html table. How do I do it using display: grid ?
.wrapper {
display: grid;
grid-template-columns: 50px 50px 50px 50px;
}
.wrapper > div {
padding: 15px;
text-align: center;
border: 1px solid black;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
Instead of using an actual border around grid items, use the background color on the container (for "border" color) and the grid-gap property (for "border" width).
.wrapper {
display: inline-grid;
grid-template-columns: 50px 50px 50px 50px;
border: 1px solid black;
grid-gap: 1px;
background-color: black;
}
.wrapper > div {
background-color: white;
padding: 15px;
text-align: center;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
You may do like this :
.wrapper {
display: inline-grid;
grid-template-columns: 50px 50px 50px 50px;
border-bottom: 1px solid black;
border-left: 1px solid black;
}
.wrapper > div {
padding: 15px;
text-align: center;
border-top: 1px solid black;
border-right: 1px solid black;
}
body {
background:pink;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
Another idea is to rely on gradient to fill gaps like below:
.wrapper {
display: inline-grid;
grid-template-columns: 50px 50px 50px 50px;
grid-gap:1px;
background:
linear-gradient(#000,#000) center/100% 1px no-repeat,
repeating-linear-gradient(to right,transparent 0 50px,#000 0 51px);
border:1px solid;
}
.wrapper > div {
padding: 15px;
text-align: center;
}
body {
background:pink;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
You can also adjust the initial solution to make it more flexible and it will work with any number of items inside a row.
Run the below code on full page and resize the window:
.wrapper {
display: grid;
max-width:800px;
grid-template-columns: repeat(auto-fill,minmax(100px,1fr));
border-top: 1px solid black;
border-left: 1px solid black;
}
.wrapper > div {
padding: 15px;
text-align: center;
border-bottom: 1px solid black;
border-right: 1px solid black;
}
body {
background:pink;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
</div>
I found a solution by using the outline property.
.grid {
width: 100%;
height: 700px;
display: grid;
grid-template-columns: repeat(4, 25fr);
grid-template-rows: repeat(4, 25fr);
margin-bottom: 30px;
grid-gap: 1px;
}
.grid-item {
background-color: silver;
outline: 1px solid gray; /* The outline creates the border */
text-align: center;
position: relative;
z-index: 1; /* original z-index */
}
/* If you want to change the color on the hover state */
.grid-item:hover {
outline: 1px solid red;
z-index: 2; /* You must apply a z-index bigger than the original z-index or else some parts of the outline will be behind other grid elements */
}
<div class="grid">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
</div>
.wrapper {
display: grid;
grid-template-columns: 50px 50px 50px 50px;
}
.wrapper > div {
padding: 15px;
text-align: center;
border: 1px solid black;
margin:0 -1px -1px 0;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
margin:0 -1px -1px 0;
This should do the trick.
There is an easy way to do this:
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 1px;
}
.grid__item {
border: 1px solid gray;
box-sizing: content-box;
width: 100%;
height: 100%;
}
<div class="grid">
<div class="grid__item">1</div>
<div class="grid__item">2</div>
<div class="grid__item">3</div>
<div class="grid__item">4</div>
<div class="grid__item">5</div>
<div class="grid__item">6</div>
<div class="grid__item">7</div>
<div class="grid__item">8</div>
<div class="grid__item">9</div>
<div class="grid__item">10</div>
<div class="grid__item">11</div>
<div class="grid__item">12</div>
</div>
P.s. The main trick here is in box-sizing: content-box. You don't need it if you do not globally override it with another value. But many people uses border-box, in that case, this override solves the problem with the gap.
Something I've used with success is simply adding a box shadow to the grid items, along with a column and row gap. This then allows the columns size to always be exactly as determined in grid-template-columns.
Then simply changing the column and row gap and box shadow size allows for a thicker border.
.wrapper {
display: grid;
grid-template-columns: 50px 50px 50px 50px;
grid-column-gap: 1px;
grid-row-gap: 1px;
}
.wrapper > div {
padding: 15px;
text-align: center;
box-shadow: 0 0 0 1px;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
For anyone who will struggle with an odd number of elements and a specific amount of frames you can use the following approach
<style>
.wrapper {
width: 100%;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
border: 1px solid;
grid-gap: 1px;
}
.element {
display: flex;
flex-direction: column;
background-color: azure;
min-height: 10rem;
border: 1px solid;
margin: -1px;
}
</style>
<body>
<div class="wrapper">
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
</div>
</body>
https://codepen.io/sergeytkhojevskiy/pen/XWZOJOL
The win-win code would be to set
grid items: border-bottom & border-right
grid wrapper: border-top & border-left
So it would correct even if top columns not equal to bottom columns
.wrapper {
display: inline-grid;
grid-template-columns: 50px 50px 50px 50px;
border-top: 1px solid black;
border-left: 1px solid black;
}
.wrapper > div {
padding: 15px;
text-align: center;
border-bottom: 1px solid black;
border-right: 1px solid black;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
</div>
If you will fix the number of item per row this solution will fit you,
this example for 3 each row, but you can edit
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr;
gap: 0;
grid-template-areas: '. . .';
}
.grid-item {
order: 0;
flex: 0 1 auto;
text-align: center;
padding: 1rem;
font-size: 12px;
background-color: #e8e8e8;
border-color: #000;
border-style: solid;
border-width: 0;
border-right-width: 1px;
border-bottom-width: 1px;
}
/*first 3 items*/
.grid-item:nth-child(-n + 3) {
border-top-width: 1px;
}
/*last item on each row*/
.grid-item:nth-child(3n + 0) {
border-right-width: 1px;
background-color: cadetblue;
}
/*first item on each row*/
.grid-item:first-child,
.grid-item:nth-child(3n + 1) {
border-left-width: 1px;
background-color: red;
}
/*middel item on each row (not used)*/
.grid-item:nth-child(3n - 1) {
// border-left-width: 1px;
background-color: yellow;
}
/*last item (not used)*/
.grid-item:last-child {
// border-left-width: 0;
background-color: green
}
<div class="grid-container">
<div class="grid-item"> 1 </div>
<div class="grid-item"> 2 </div>
<div class="grid-item"> 3 </div>
<div class="grid-item"> 1 </div>
<div class="grid-item"> 2 </div>
<div class="grid-item"> 3 </div>
<div class="grid-item"> 1 </div>
<div class="grid-item"> 2 </div>
</div>

Preventing double borders in CSS Grid

Given the current CSS grid example, how can I collapse the borders in order to avoid the double borders ?
This is such a simple thing to achieve using an Html table. How do I do it using display: grid ?
.wrapper {
display: grid;
grid-template-columns: 50px 50px 50px 50px;
}
.wrapper > div {
padding: 15px;
text-align: center;
border: 1px solid black;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
Instead of using an actual border around grid items, use the background color on the container (for "border" color) and the grid-gap property (for "border" width).
.wrapper {
display: inline-grid;
grid-template-columns: 50px 50px 50px 50px;
border: 1px solid black;
grid-gap: 1px;
background-color: black;
}
.wrapper > div {
background-color: white;
padding: 15px;
text-align: center;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
You may do like this :
.wrapper {
display: inline-grid;
grid-template-columns: 50px 50px 50px 50px;
border-bottom: 1px solid black;
border-left: 1px solid black;
}
.wrapper > div {
padding: 15px;
text-align: center;
border-top: 1px solid black;
border-right: 1px solid black;
}
body {
background:pink;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
Another idea is to rely on gradient to fill gaps like below:
.wrapper {
display: inline-grid;
grid-template-columns: 50px 50px 50px 50px;
grid-gap:1px;
background:
linear-gradient(#000,#000) center/100% 1px no-repeat,
repeating-linear-gradient(to right,transparent 0 50px,#000 0 51px);
border:1px solid;
}
.wrapper > div {
padding: 15px;
text-align: center;
}
body {
background:pink;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
You can also adjust the initial solution to make it more flexible and it will work with any number of items inside a row.
Run the below code on full page and resize the window:
.wrapper {
display: grid;
max-width:800px;
grid-template-columns: repeat(auto-fill,minmax(100px,1fr));
border-top: 1px solid black;
border-left: 1px solid black;
}
.wrapper > div {
padding: 15px;
text-align: center;
border-bottom: 1px solid black;
border-right: 1px solid black;
}
body {
background:pink;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
</div>
I found a solution by using the outline property.
.grid {
width: 100%;
height: 700px;
display: grid;
grid-template-columns: repeat(4, 25fr);
grid-template-rows: repeat(4, 25fr);
margin-bottom: 30px;
grid-gap: 1px;
}
.grid-item {
background-color: silver;
outline: 1px solid gray; /* The outline creates the border */
text-align: center;
position: relative;
z-index: 1; /* original z-index */
}
/* If you want to change the color on the hover state */
.grid-item:hover {
outline: 1px solid red;
z-index: 2; /* You must apply a z-index bigger than the original z-index or else some parts of the outline will be behind other grid elements */
}
<div class="grid">
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
<div class="grid-item"></div>
</div>
.wrapper {
display: grid;
grid-template-columns: 50px 50px 50px 50px;
}
.wrapper > div {
padding: 15px;
text-align: center;
border: 1px solid black;
margin:0 -1px -1px 0;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
margin:0 -1px -1px 0;
This should do the trick.
There is an easy way to do this:
.grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 1px;
}
.grid__item {
border: 1px solid gray;
box-sizing: content-box;
width: 100%;
height: 100%;
}
<div class="grid">
<div class="grid__item">1</div>
<div class="grid__item">2</div>
<div class="grid__item">3</div>
<div class="grid__item">4</div>
<div class="grid__item">5</div>
<div class="grid__item">6</div>
<div class="grid__item">7</div>
<div class="grid__item">8</div>
<div class="grid__item">9</div>
<div class="grid__item">10</div>
<div class="grid__item">11</div>
<div class="grid__item">12</div>
</div>
P.s. The main trick here is in box-sizing: content-box. You don't need it if you do not globally override it with another value. But many people uses border-box, in that case, this override solves the problem with the gap.
Something I've used with success is simply adding a box shadow to the grid items, along with a column and row gap. This then allows the columns size to always be exactly as determined in grid-template-columns.
Then simply changing the column and row gap and box shadow size allows for a thicker border.
.wrapper {
display: grid;
grid-template-columns: 50px 50px 50px 50px;
grid-column-gap: 1px;
grid-row-gap: 1px;
}
.wrapper > div {
padding: 15px;
text-align: center;
box-shadow: 0 0 0 1px;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
</div>
For anyone who will struggle with an odd number of elements and a specific amount of frames you can use the following approach
<style>
.wrapper {
width: 100%;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
border: 1px solid;
grid-gap: 1px;
}
.element {
display: flex;
flex-direction: column;
background-color: azure;
min-height: 10rem;
border: 1px solid;
margin: -1px;
}
</style>
<body>
<div class="wrapper">
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
<div class="element"></div>
</div>
</body>
https://codepen.io/sergeytkhojevskiy/pen/XWZOJOL
The win-win code would be to set
grid items: border-bottom & border-right
grid wrapper: border-top & border-left
So it would correct even if top columns not equal to bottom columns
.wrapper {
display: inline-grid;
grid-template-columns: 50px 50px 50px 50px;
border-top: 1px solid black;
border-left: 1px solid black;
}
.wrapper > div {
padding: 15px;
text-align: center;
border-bottom: 1px solid black;
border-right: 1px solid black;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
</div>
If you will fix the number of item per row this solution will fit you,
this example for 3 each row, but you can edit
.grid-container {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr;
gap: 0;
grid-template-areas: '. . .';
}
.grid-item {
order: 0;
flex: 0 1 auto;
text-align: center;
padding: 1rem;
font-size: 12px;
background-color: #e8e8e8;
border-color: #000;
border-style: solid;
border-width: 0;
border-right-width: 1px;
border-bottom-width: 1px;
}
/*first 3 items*/
.grid-item:nth-child(-n + 3) {
border-top-width: 1px;
}
/*last item on each row*/
.grid-item:nth-child(3n + 0) {
border-right-width: 1px;
background-color: cadetblue;
}
/*first item on each row*/
.grid-item:first-child,
.grid-item:nth-child(3n + 1) {
border-left-width: 1px;
background-color: red;
}
/*middel item on each row (not used)*/
.grid-item:nth-child(3n - 1) {
// border-left-width: 1px;
background-color: yellow;
}
/*last item (not used)*/
.grid-item:last-child {
// border-left-width: 0;
background-color: green
}
<div class="grid-container">
<div class="grid-item"> 1 </div>
<div class="grid-item"> 2 </div>
<div class="grid-item"> 3 </div>
<div class="grid-item"> 1 </div>
<div class="grid-item"> 2 </div>
<div class="grid-item"> 3 </div>
<div class="grid-item"> 1 </div>
<div class="grid-item"> 2 </div>
</div>

css 3 column grid applying equal margin

.num_pad_wrap {
width:300px;
background:#eee;
height:300px;
}
.num_pad_wrap div {
float: left;
width: 30%;
background: #666C77;
height: 50px;
margin:1%;
border: 1px solid #000;
}
<div class="num_pad_wrap">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>0</div>
<div>C</div>
</div>
I'm trying to do a calculator. As you can see I failed to calculate the margin to fit well in the container. It's easy if I can just hardcode the pixel but in my case I have to do percentage. How to style the margin equally for all sides?
CSS:
.num_pad_wrap {
width: 300px;
background:#eee;
height:300px;
}
.num_pad_wrap .row {
margin-left: 2%;
}
.num_pad_wrap .row div {
float: left;
width: 30%;
background: #666C77;
height: 50px;
margin:1%;
border: 1px solid #000;
}
HTML:
<div class="num_pad_wrap">
<div class="row">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
<div class="row">
<div>4</div>
<div>5</div>
<div>6</div>
</div>
<div class="row">
<div>7</div>
<div>8</div>
<div>9</div>
</div>
<div class="row">
<div>0</div>
<div>C</div>
</div>
</div>
Since your 3 buttons take up 96% of the width, (32% * 3), your total margins left is 4%.
You can wrap each row around a row class, then set margin-left to half of your total margin, which is 2% in this case.
You can try like this: Demo
.num_pad_wrap {
overflow: hidden;
width:300px;
background:#eee;
height:auto;
padding:1.2% 1.2% 0% 1.2%;
}
.num_pad_wrap div {
background: #eee;
float: left;
margin-left: 3.2%;
margin-bottom: 3.2%;
background: #666C77;
height: 50px;
width: 31.2%;
margin-bottom: 3.2%;
}
/* clear col */
.num_pad_wrap div:nth-of-type(3n+1) {
margin-left: 0;
clear: left;
}
HTML:
<div class="num_pad_wrap">
<div>1</div>
........
<div>C</div>
</div>