How can I create a grid like the image below? I am trying to make a grid that can be used for my project but I am really unsure of how I should go about this problem.
Can somebody please help me?
PICTURE
<div class="grid">
<div class="triangle"></div>
<div class="row2">
<div class="triangle2"></div>
<div class="triangle3"></div>
<div class="triangle2"></div>
</div>
<!-- Add more triangles as needed -->
</div>
.grid {
display: flex;
flex-wrap: wrap;
}
.triangle {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
margin: 10px;
}
.triangle2 {
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
margin: 10px;
}
With clip-path you can the create triangles you need and use a negative left and right margin to put them side by side.
triangle pointing up: clip-path: polygon(50% 0%, 0% 100%, 100% 100%)
triangle pointing down: clip-path: polygon(50% 100%, 0% 0%, 100% 0%)
negative margin: -1 x 1/4th of the width of a triangle
Beware: when you need borders, the previously adviced SVG solutions may be a better choice as clip-path clips borders as well.
Note: make sure to hover the triangles in the snippet.
/* Grid setup */
.grid { display: flex; flex-direction: column; justify-content: center; }
.row { display: flex; justify-content: center; }
.row > * { display: grid; place-items: center }
/* Triangle setup */
.grid { --triangle-size: calc(12.5vw + 1rem); /* y=mx+b for points p1(160,36) p2(1920,256) */ }
.row > :nth-child(odd) { clip-path: polygon(50% 0%, 0% 100%, 100% 100%); background-color: LemonChiffon } /* up */
.row > :nth-child(even) { clip-path: polygon(50% 100%, 0% 0%, 100% 0%); background-color: LightBlue } /* Down */
.row > * {
width : var(--triangle-size);
height: var(--triangle-size);
margin: 0 calc(-1 * var(--triangle-size)/4);
}
/* Action */
.row > :hover { background-color: tomato }
<div class="grid">
<div class="row">
<div>1</div>
</div>
<div class="row">
<div>1</div>
<div>2</div>
<div>3</div>
</div>
<div class="row">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
<div class="row">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
</div>
</div>
Related
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>
I would like to build something similar to a TV schedule with a "live" line. The schedule would scroll vertically (more channels) and horizontally (timeline).
I can't seem to achieve this with an absolute positioning. The line doesn't reach the bottom of the container when scrolling vertically.
The height of the contents of the container is dynamic, so I cannot assign a fixed height either. Would like to achieve this with CSS only. Simple example of my failure below.
<style type="text/css">
.wrapper { height: 150px; width: 400px; overflow: scroll; position: relative; }
.line { width: 3px; background: blue; position: absolute; left: 200px; top: 0; bottom: 0; z-index: 200; }
.list > div { width: 600px; height: 50px; margin: 5px; background: red }
</style>
<div class="wrapper">
<div class="line"></div>
<div class="list">
<div>0</div>
<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>
</div>
What I would do is place the .line inside of the .list, so it can use that elements height as the context for its own height.
Also, I laid this out using css grid, which will give you a lot of flexibility with this type of layout. It's basically what it was intended for.
.wrapper {
width: 100%;
border: 2px solid black;
}
.line {
position: absolute;
left: 200px;
top: -20px;
width: 3px;
height: calc(100% + 20px);
z-index: 200;
background: goldenrod;
}
.list {
position: relative;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
grid-gap: 5px;
margin: 20px 0 0;
}
.show {
height: 50px;
background: royalblue;
}
<div class="wrapper">
<div class="list">
<div class="show">0</div>
<div class="show">1</div>
<div class="show">2</div>
<div class="show">3</div>
<div class="show">4</div>
<div class="show">5</div>
<div class="show">6</div>
<div class="show">7</div>
<div class="show">8</div>
<div class="show">9</div>
<div class="show">10</div>
<div class="show">11</div>
<div class="show">12</div>
<div class="show">13</div>
<div class="line"></div>
</div>
</div>
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>
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>
How can I add items down to be able to scroll?
There is a hack using transform: scaleY(-1) to start adding elements from the bottom
transform: scaleY(-1) on the container to invert it vertically
transform: scaleY(-1) on the children of the container to rectify the inversion on the children.
Even the overflow for the container starts from the bottom!
See demo below:
body {
margin: 0;
}
* {
box-sizing: border-box;
}
.wrapper {
border: 1px solid red;
height: 100vh;
overflow-y: auto;
transform: scaleY(-1);
}
.wrapper > div {
height: 100px;
width: 50vh;
border: 1px solid;
margin: 10px auto;
transform: scaleY(-1);
/*align text inside*/
display: flex;
justify-content: center;
align-items: center;
}
<div class="wrapper">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
</div>
Let me know your feedback on this. Thanks!
Is this what u mean?
<div style="overflow-y:scroll;, height: 5px;">
<span></span>
<span></span>
<span></span>
<!-- any number of elements you want-->
</div>