CSS Grid: How to Apply Color to Grid Gaps

CSS Grid: Is it possible to apply color to grid gaps?

Sadly, there is currently no way in the CSS Grid spec to style grid-gap. I came up with a solution that works well though that involves just html and css: show border grid lines only between elements

SVGs in a CSS Grid with 0px gap displays background color

You are running into a rounding versus antialiasing trap: Your grid has 10 rows and ten columns, over a total width of 504px. Sizing with repeat(1fr) means each cell gets a width of 50.4px. The SVG gets sized to that value, with the <rect> filling the complete viewport.

This means that the outline of the grafical element does not coincide with full pixels, and the outermost pixel in each direction gets a partial transparency.

In principle, the attempt to improve the display with shape-rendering: crispEdges or shape-rendering: geometricPrecision might yield results, but that is not guaranteed. However you divy up 50.4px, either there can be at least one side with an antialiasing artefact, or the browser might round the number of pixels down on some rows or columns.

The end verdict is always the same:

The shape-rendering property provides a hint to the implementation about what tradeoffs to make as it renders vector graphics elements...

Hints are not rules. Every browser is at large to implement its own solution.

Sizing the container

Making sure elements have full pixel sizes is one solution, and should always be the first choice. If you have a grid of ten elements per dimension, you would have to make sure the grid container has always a multiple of 10px size.

But if you want your grid to be responsive, this might prove complicated. Only media queries can achieve that. (The CSS calc() function only accepts the four basic operators and will not round values.)

Cheating the rounding function

But there is also another way to go. Some overlap between neighbouring <svg> elements can be achieved with an overflow: visible, so that content outside the viewBox is not clipped, and increasing the area of rendered content. This does not change the computation of box sizes, it only means the implicit clip path surrounding the <svg> element is removed.

This obviously errs to the opposite side, and if it is critical that the outermost pixel is diplayed correctly, this might be just the wrong solution. But for your example, it improves the result.

The choosen size of the width of 102% is enough to cover 1px if the svg is diplayed on screen at a size of ~50px. Obviously, this value might be the wrong one for other scales, but that is the nature of drawing vector graphics onto a screen divided into pixels.

div {
position: relative;
height: 51px;
width: 101px;
margin: 20px;
background: red;
}
svg {
width: 50.4px;
height: 50.4px;
}
rect {
fill: blue;
}
path {
stroke: white;
}
.overflowing svg {
overflow: visible;
}
<div>
<svg viewBox="0 0 8 8">
<rect width='100%' height='100%' />
<path d="M4 0v2"/><path d="M6 4h2"/>
<path d="M4 6v2"/><path d="M0 4h2"/>
</svg><svg viewBox="0 0 8 8">
<rect width='100%' height='100%' />
<path d="M4 0v2"/><path d="M6 4h2"/>
<path d="M4 6v2"/><path d="M0 4h2"/>
</svg><br/>
</div>
<div class="overflowing">
<svg viewBox="0 0 8 8">
<rect width='102%' height='102%' />
<path d="M4 0v2"/><path d="M6 4h2"/>
<path d="M4 6v2"/><path d="M0 4h2"/>
</svg><svg viewBox="0 0 8 8">
<rect width='102%' height='102%' />
<path d="M4 0v2"/><path d="M6 4h2"/>
<path d="M4 6v2"/><path d="M0 4h2"/>
</svg>
</div>

CSS Grid: Grid-gap causing items to overflow?

Update the code like below (related question to understand the first code adjustment: Why does minmax(0, 1fr) work for long elements while 1fr doesn't?)

* {
margin: 0;
}

.container {
display: flex;
justify-content: center;
background-color: firebrick;
}

.form {
display: flex;
flex-direction: column;
padding: 2rem;
margin: 2rem;
width: 25rem;
background-color: white;
}
.content {
border: 1px solid red;
display: grid;
grid-template-columns: repeat(2, minmax(0,1fr)); /* here */
grid-gap: 4rem;
}

/* here */
input {
max-width: 100%;
box-sizing: border-box;
}
<div class="container">
<form class="form">
<div class="content">
<div class="field">
<label for="title" class="label">Title</label>
<input type="text" placeholder="Job Title" id="title" class="input">
<i class="icon icon--success"></i>
<i class="icon icon--fail">
</i>
<small class="error-msg"></small>
</div>
<div class="field">
<label for="company" class="label">Company</label>
<select name="company" id="company" class="input">
<!-- options added in js -->
</select>
<i class="icon icon--success"></i>
<i class="icon icon--fail"></i>
<small class="error-msg"></small>
</div>

<div class="field">
<label for="location" class="label">Location</label>
<select name="location" id="location" class="input">
<!-- options added in js -->
</select>
<i class="icon"></i>
<i class="icon"></i>
<small class="error-msg"></small>
</div>

<div class="field">
<label for="wage" class="label">Wage</label>
<input type="text" placeholder="Wage" id="wage" class="input">
<i class="icon icon--success"></i>
<i class="icon icon--fail"></i>
<small class="error-msg"></small>
</div>

<div class="field">
<label for="type" class="new-job__label">Type</label>
<select name="type" id="type" class="input">
<!-- options added in js -->
</select>
<i class="icon icon--success"></i>
<i class="icon icon--fail"></i>
<small class="error-msg"></small>
</div>

<div class="field">
<label for="position" class="label">Position</label>
<select name="position" id="position" class="input">
<!-- options added in js -->
</select>
<i class="icon icon--success"></i>
<i class="icon icon--fail"></i>
<small class="error-msg"></small>
</div>

<div class="field">
<label for="pqe" class="label">PQE</label>
<select name="pqe" id="pqe" class="input">
<!-- options added in js -->
</select>
<i class="icon icon--success"></i>
<i class="icon icon--fail"></i>
<small class="error-msg"></small>
</div>

<div class="field">
<label for="featured" class="label">Featured</label>
<select name="featured" id="featured" class="input">
<!-- options added in js -->
</select>
<i class="icon icon--success"></i>
<i class="icon icon--fail"></i>
<small class="error-msg"></small>
</div>
</div>
<button class="new-job__submit">Submit</button>

</form>
</div>

Trying to find display: contents alternative that I can use with my CSS grid

You could convert it into table:

.grid-row {
display: table-row;
}

.grid-row:hover > div {
background-color: #262626;
color: #fff;
}

.grid-cell {
background-color: #000;
color: #808080;
padding: .5rem;
line-height: 4rem;
display: table-cell;
position: relative;
}

.grid {
margin: 0 auto;
display: table;
background-color: #808080 !important;
white-space: pre-wrap !important;
border-spacing: 1px;
}

.grid > :first-of-type
{
width: 100%;
}
<div class="grid">
<div class="grid-cell"></div>
<div class="grid-cell">Price</div>
<div class="grid-cell">Quantity</div>

<div class="grid-row">
<div class="grid-cell">Item 1</div>
<div class="grid-cell">10.00</div>
<div class="grid-cell">1</div>
</div>

<div class="grid-row">
<div class="grid-cell">Item 2</div>
<div class="grid-cell">20.00</div>
<div class="grid-cell">2</div>
</div>

<div class="grid-row">
<div class="grid-cell">Item 3</div>
<div class="grid-cell">30.00</div>
<div class="grid-cell">3</div>
</div>
</div>


Related Topics



Leave a reply



Submit