CSS Grid Stadium Shape
Asked Answered
D

1

5

I've been trying to work with the following figure on CSS Grid, but it has turned out very challenging

enter image description here

The image represents a stadium, but it is turning very hard to make it look like the image attached. A few considerations

  • The corners are triangles, so the hardest part is to make them with that shape and also responsive.

  • I can use a CSS Mask to deal with the shapes and spacing but that will chop off a few circles.

I did my try and error and error and got it halfway through. Any idea how to make it work? or maybe If someone has a different approach also would help me out

https://jsfiddle.net/rodboc/9psa4bg3/1/

Any thoughts?

.grid {
  max-width: 80vw;
  min-height: 90vh;
  display: grid;
  grid-gap: 5px;
  grid-template-columns: 30% [main-start] 40% [main-end] 30%;
  grid-template-rows: 20% [main-start] 30% [main-end] 20%;
  margin: 0 auto;
}

[class^="item"] {
  background-color: blue;
  display: flex;
  flex-wrap: wrap;
  flex-direction: column;
  align-items: flex-start;
  align-content: flex-start;
  justify-content: center;
}

.item1 {
  background-color: red;
  grid-area: main;
}
.circle {
  width: 5px;
  height: 5px;
  overflow: hidden;
  background: #ccc;
  border-radius: 50%;
  margin: 1px;
  padding: 0;
}

.circle:hover {
  background: blue;
}

<div class="grid">
  <div class="item1">
  </div>
  <div class="item2">
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
    <div class="circle"></div>
  </div>
  <div class="item3"></div>
  <div class="item4"></div>
  <div class="item5"></div>
  <div class="item6"></div>
  <div class="item7"></div>
  <div class="item8"></div>
  <div class="item9"></div>
</div>
Drawer answered 18/6, 2020 at 23:50 Comment(2)
FWIW, your embedded example image is completely invisible on the SO dark mode.Derby
Thanks for that, I'll add a background colourDrawer
O
6

shape-outside is what you need.

Here is a basic idea for the top part that you can easily replicate for the bottom one:

body {
  width:780px;
}

.top {
  height:150px;
  text-align:justify;
}
i {
  display:inline-block;
  width:30px;
  height:30px;
  margin:2px;
  background:red;
  border-radius:50%;
}
.top::before {
  content:"";
  height:100%;
  width:150px;
  float:left;
  shape-outside:linear-gradient(to bottom left,transparent 49%,#fff 50%);
}
.top span::before {
  content:"";
  height:100%;
  width:150px;
  float:right;
  shape-outside:linear-gradient(to bottom right,transparent 49%,#fff 50%);
}

.left,
.right{
   width:150px;
   height:150px;
   float:left;
   transform:translateY(-90%);
   clip-path:polygon(0 0,100vh 100vh,0 100vh );
} 
.left::before,
.right::before{
  content:"";
  height:100%;
  width:100%;
  float:right;
  shape-outside:linear-gradient(to bottom left,#fff 49%,transparent 50%);
}
.right {
  float:right;
  text-align:right;
   clip-path:polygon(-100vh 100vh,100vh 100vh,100% 0);
}
.right::before{
  float:left;
  shape-outside:linear-gradient(to bottom right,#fff 49%,transparent 50%);
}

i:hover{
  background:blue;
}
<div class="top"><span></span>
<i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i>
</div>

<div class="left">
<i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i>
</div>

<div class="right">
<i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i>
</div>

Update

Full example of the stadium shape:

var t = document.querySelector('.top');
var tl = document.querySelector('.top-left');
var tr = document.querySelector('.top-right');
var b = document.querySelector('.bottom');
var bl = document.querySelector('.bottom-left');
var br = document.querySelector('.bottom-right');
var sl = document.querySelector('.side-left');
var sr = document.querySelector('.side-right');
for (var i = 0; i < 5000; i++) {
  var l = document.createElement("i");
  t.appendChild(l);
  l = document.createElement("i");
  tl.appendChild(l);
  l = document.createElement("i");
  tr.appendChild(l);
  l = document.createElement("i");
  b.appendChild(l);
  l = document.createElement("i");
  bl.appendChild(l);
  l = document.createElement("i");
  br.appendChild(l);
  l = document.createElement("i");
  sl.appendChild(l);
  l = document.createElement("i");
  sr.appendChild(l);
}
body {
  margin: 0;
}

.stadium {
  display: grid;
  min-width:600px;
  min-height:500px;
  grid-template-columns: 20% 1fr 20%;
  grid-template-rows: 150px 1fr 150px;
  row-gap:10px;
  height: 100vh;
  line-height: 0;
}

.top,
.bottom{
  height: 100%;
  grid-column: 1/-1;
  grid-row: 1;
  text-align: justify;
  overflow: hidden;
}
.bottom {
  grid-row: 3;
}

.top::before,
.bottom::before{
  content: "";
  height: 100%;
  width: 20%;
  float: left;
  shape-outside: linear-gradient(to bottom left, transparent 49%, #fff 50%);
}
.bottom::before{
  shape-outside: linear-gradient(to top left, transparent 49%, #fff 50%);
}

.top span::before,
.bottom span::before {
  content: "";
  height: 100%;
  width: 20%;
  float: right;
  shape-outside: linear-gradient(to bottom right, transparent 49%, #fff 50%);
}
.bottom span::before {
  shape-outside: linear-gradient(to top right, transparent 49%, #fff 50%);
}

.top-left,
.top-right,
.bottom-left,
.bottom-right{
  width: 100%;
  height: 100%;
  float: left;
  grid-row: 1;
  grid-column: 1;
  overflow: hidden;
  clip-path: polygon(0 0, 100% 100%, 0 100%);
}

.bottom-left {
  grid-row: 3;
  grid-column: 1;
  clip-path: polygon(0 0, 100% 0,0 100%);
}


.top-left::before,
.top-right::before,
.bottom-left::before,
.bottom-right::before{
  content: "";
  height: 100%;
  width: 100%;
  float: right;
  shape-outside: linear-gradient(to bottom left, #fff 49%, transparent 50%);
}
.bottom-left::before {
  shape-outside: linear-gradient(to top left, #fff 49%, transparent 50%);
}
.top-right,
.bottom-right{
  float: right;
  text-align: right;
  grid-column: 3;
  clip-path: polygon(0 100%, 100% 100%, 100% 0);
}
.bottom-right {
  grid-row: 3;
  clip-path: polygon(0 0, 100% 0,100% 100%);
}

.top-right::before {
  float: left;
  shape-outside: linear-gradient(to bottom right, #fff 49%, transparent 50%);
}
.bottom-right::before {
  float: left;
  shape-outside: linear-gradient(to top right, #fff 49%, transparent 50%);
}

.side-right,
.side-left {
 height:100%;
 overflow:hidden;
}
.side-right {
  grid-column:3;
  text-align:right;
}

i {
  display: inline-block;
  vertical-align: top;
  width: 8px;
  height: 8px;
  margin: 1px;
  background: red;
  border-radius: 50%;
}

i:hover {
  background: blue;
}
<div class="stadium">
  <div class="top-left"></div>
  <div class="top"><span></span></div>
  <div class="top-right"></div>
  
  <div class="bottom-left"></div>
  <div class="bottom"><span></span></div>
  <div class="bottom-right"></div>
  
  <div class="side-left"></div>
  <div class="side-right"></div>
</div>
Overelaborate answered 19/6, 2020 at 0:13 Comment(8)
Unfortunately, it is not what I'm looking for cause the border turns inaccessible for mouse actions like hover or clickingDrawer
@Drawer what borders are inaccesible?Overelaborate
Those circles close to the edges are can't be hovered cause the shape-outside property jsfiddle.net/Gemobu/g4057zsa/1 @temaniafifDrawer
@Drawer they can be hovered, check the update. Clip-path can solve thisOverelaborate
clip-path will mask them? cause, in that case, a few dots might end up not visible @temaniafifDrawer
@Drawer no, the clip-path will follow the shape created using shape-outside to cut the extra part that is creating the hover issueOverelaborate
With clip-path and shape-outside there are not reachable area jsfiddle.net/Gemobu/f40mp18b, had a look and each block should overlap the next one @ temaniafifDrawer
@Drawer check the update, I made a full working example. Still need some tweaking but it should do what you wantOverelaborate

© 2022 - 2024 — McMap. All rights reserved.