I have 20 element for a grid view. But I want only 3✕3 grid view, where there will be only 9 element in the view window. And the rest of the element should be placed in the right side of the window as a scrollable asset.**
No matter what the screen size is I want to show only the first 9 element in the grid.
.cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
grid-gap: 5px;
}
.card {
background-color: dodgerblue;
color: white;
padding: 1rem;
height: 4rem;
}
<div class="cards">
<div class="card">ONE</div>
<div class="card">TWO</div>
<div class="card">THREE</div>
<div class="card">FOUR</div>
<div class="card">FIVE</div>
<div class="card">SIX</div>
<div class="card">SEVEN</div>
<div class="card">EIGHT</div>
<div class="card">NINE</div>
<div class="card">TEN</div>
<div class="card">ELEVEN</div>
<div class="card">TWELVE</div>
</div>
In this case the grid should flow vertically. And you can set it up like this with some calculation:
.cards {
/* how many columns on the first screen */
--cols: 3;
/* how many rows on the first screen */
--rows: 3;
/* grid gap */
--gap: 5px;
--width: calc((100% - var(--gap) * (var(--cols) - 1)) / var(--cols));
display: grid;
position: relative;
grid-auto-flow: column dense;
grid-template-rows: repeat(var(--rows), 1fr);
grid-auto-columns: var(--width);
grid-gap: var(--gap);
overflow-x: auto;
}
.card {
background-color: dodgerblue;
color: white;
padding: 1rem;
height: 4rem;
}
<div class="cards">
<div class="card">ONE</div>
<div class="card">TWO</div>
<div class="card">THREE</div>
<div class="card">FOUR</div>
<div class="card">FIVE</div>
<div class="card">SIX</div>
<div class="card">SEVEN</div>
<div class="card">EIGHT</div>
<div class="card">NINE</div>
<div class="card">TEN</div>
<div class="card">ELEVEN</div>
<div class="card">TWELVE</div>
<div class="card">THIRTEEN</div>
<div class="card">FOURTEEN</div>
</div>
.cards {
display: grid;
grid-template-columns: auto auto auto;
background-color: #2196F3;
padding: 10px;
}
.card {
background-color: rgba(255, 255, 255, 0.8);
border: 1px solid rgba(0, 0, 0, 0.8);
padding: 20px;
font-size: 30px;
text-align: center;
}
<div class="cards">
<div class="card">ONE</div>
<div class="card">TWO</div>
<div class="card">THREE</div>
<div class="card">FOUR</div>
<div class="card">FIVE</div>
<div class="card">SIX</div>
<div class="card">SEVEN</div>
<div class="card">EIGHT</div>
<div class="card">NINE</div>
</div>
A simple way to achieve this is by using nth-child CSS selector on your card class. Since, you want to display only he first 9 cards in the container, you will have to hide the cards from 10th position onwards.
Consider :nth-child(an + b). Here, the term b is the offset that you can specify to target cards. If you remove a and substitute the value of b as 10, it will target all the cards that appear as 10th child and later. The selector will be like so: :nth-child(n + 10). This is a comparatively readable solution.
Bonus Tip: To make sure the cards show up as 3 x 3 grid, you can explicitly update grid-template-columns CSS property to be repeat(3, 1fr) instead of repeat(auto-fill, minmax(150px, 1fr))
This is the final snippet:
.cards {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 5px;
}
.card {
background-color: dodgerblue;
color: white;
padding: 1rem;
height: 4rem;
}
/* Hide card which occurs at 10th position and above */
.card:nth-child(n + 10) {
display: none;
}
<div class="cards">
<div class="card">ONE</div>
<div class="card">TWO</div>
<div class="card">THREE</div>
<div class="card">FOUR</div>
<div class="card">FIVE</div>
<div class="card">SIX</div>
<div class="card">SEVEN</div>
<div class="card">EIGHT</div>
<div class="card">NINE</div>
<div class="card">TEN</div>
<div class="card">ELEVEN</div>
<div class="card">TWELVE</div>
</div>
I use this tool and it makes everything easier : https://cssgrid-generator.netlify.app/
You just select wich grid you want, how many rows... and it gives you the css + html :)
Related
i found jQuery code that prints out the div that is clicked inside a grid, how can i modify this code so that it adds class ".active" only to the div .grid_item that has been clicked, can somebody help me understand how to do this?
I have added the html and js down below.
$(".grid").click(function(event) {
var hoveredGridItems = $(this).children()
.filter(function() { return $(this).is(":hover"); });
if (hoveredGridItems.length > 0)
console.log(hoveredGridItems[0]);
else
console.log("no element detected!");
});
.grid {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
grid-gap: 10px;
}
/* styles just for demo */
.grid__item {
background-color: tomato;
color: white;
/* styles for centering text */
display: flex;
align-items: center;
justify-content: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="grid">
<div class="grid__item">One</div>
<div class="grid__item">Two</div>
<div class="grid__item">Three</div>
<div class="grid__item">Four</div>
<div class="grid__item">Five</div>
<div class="grid__item">Six</div>
<div class="grid__item">Seven</div>
<div class="grid__item">Eight</div>
<div class="grid__item">Nine</div>
</div>
$(".grid__item").click(function(event) {
$(".grid__item").removeClass("active");
$(event.currentTarget).addClass("active");
});
.grid {
display: grid;
grid-template-columns: repeat(3, 100px);
grid-template-rows: repeat(3, 100px);
grid-gap: 10px;
}
/* styles just for demo */
.grid__item {
background-color: tomato;
color: white;
/* styles for centering text */
display: flex;
align-items: center;
justify-content: center;
}
.grid__item.active {
border: 1px solid yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="grid">
<div class="grid__item">One</div>
<div class="grid__item">Two</div>
<div class="grid__item">Three</div>
<div class="grid__item">Four</div>
<div class="grid__item">Five</div>
<div class="grid__item">Six</div>
<div class="grid__item">Seven</div>
<div class="grid__item">Eight</div>
<div class="grid__item">Nine</div>
</div>
Easiest way is to set an event handler on the individual "grid__item", not on the whole grid (rather than using the hover method which is a bit overly complex).
Then you can use the currentTarget of the event to get the item clicked to add the class. I also, before that, remove that active class from all the grid items so only the most recently clicked gets the class.
I was trying hard to open a modal on button click to display the calendar date and time also but nt getting anything. can any one share your knowledge.
i added the sample image how i want to display it.
Since you gave an image as an example I thought you wanted to create that exact look.
The following should work inside your modal.
const dateInput = document.getElementById('input-date');
const displayDate = document.getElementById('currentDate');
// init view
(() => {
let date = new Date().toISOString().slice(0, 10);
dateInput.value = date;
displayDate.innerText = date;
})();
.wrapper {
padding: 1rem;
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
}
#time-picker {
padding: 1rem;
border: 1px solid #000;
-webkit-box-shadow: 0 0 10px #000;
box-shadow: 0 0 10px #000;
text-align: center
}
#header-row {
display: grid;
grid-template-columns: 2fr 1fr;
}
#data-row {
display: grid;
grid-template-columns: repeat(3, 1fr);
}
.bordered {
border: 1px solid #000;
margin: 1rem;
}
#time-picker .bordered > div {
margin: 0.5rem;
}
#time-picker > a {
width: 100%;
}
#currentDate {
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
}
#button-row {
display: flex;
flex-flow: row nowrap;
justify-content: space-evenly;
align-items: center;
}
<div id="outer">
<div class="wrapper">
<label for="input-date">Need Date</label>
<input type="date" id="input-date">
</div>
<div id="time-picker">
<div id="header-row">
<div>Hours of Day</div>
<div>Minutes</div>
</div>
<div id="data-row">
<div class="bordered">
<div>00</div>
<div>01</div>
<div>02</div>
<div>03</div>
<div>04</div>
<div>05</div>
<div>06</div>
<div>07</div>
<div>08</div>
<div>09</div>
<div>10</div>
<div>11</div>
</div>
<div class="bordered">
<div>12</div>
<div>13</div>
<div>14</div>
<div>15</div>
<div>16</div>
<div>17</div>
<div>18</div>
<div>19</div>
<div>20</div>
<div>21</div>
<div>22</div>
<div>23</div>
</div>
<div class="bordered">
<div>00</div>
<div>05</div>
<div>10</div>
<div>15</div>
<div>20</div>
<div>25</div>
<div>30</div>
<div>35</div>
<div>40</div>
<div>45</div>
<div>50</div>
<div>55</div>
</div>
</div>
Clear Time
</div>
<h2 id="currentDate" class="row"></h2>
<div id="button-row">
<button>Cancel / Exit</button>
<button>Save / Exit</button>
</div>
</div>
I'm trying to set the background of a div when it is clicked, and then when it is clicked again it reverses back to no color.
Here is my code:
<div class="wrapper">
<div onclick="set()" id="square"></div>
<div onclick="set()" id="square"></div>
<div onclick="set()" id="square"></div>
<div onclick="set()" id="square"></div>
<div onclick="set()" id="square"></div>
<div onclick="set()" id="square"></div>
<div onclick="set()" id="square"></div>
</div>
.wrapper {
display: grid;
grid-template-columns: repeat(107, 1fr);
grid-template-rows: repeat(59, 1fr);
grid-gap: 0px;
}
.wrapper div {
padding: 5px;
background-color: none;
text-align: center;
border: 0.001px solid black;
font-size: 5px;
display: flex;
justify-content: center;
align-items: center;
}
.wrapper div:hover {
background: white;
}
function set() {
var squares = document.getElementById('square');
for (var i = 0; i < squares.length; i++) {
squares[i].style.backgroundColor = "none";
}
if (squares[i].style.backgroundColor === "none") {
squares[i].style.backgroundColor = "white";
} else {
squares[i].style.backgroundColor = "none";
}
}
When I click the div it doesn't do anything. My javascript code isn't working, how should I change it so it makes the div background white when clicked and then none when clicked again.
You can put an event listener on the parent element that listens for the click event. When it gets a click event, if it is from one of the squares, toggle a class to keep the background color on it. If it already has that class, it will be removed.
document.querySelector('.squares').addEventListener('click', e => {
if (e.target.classList.contains('square')) {
e.target.classList.toggle('selected');
}
});
.wrapper {
display: grid;
grid-template-columns: repeat(107, 1fr);
grid-template-rows: repeat(59, 1fr);
grid-gap: 0px;
}
.wrapper div {
padding: 5px;
background-color: none;
text-align: center;
border: 0.001px solid black;
font-size: 24px;
display: flex;
justify-content: center;
align-items: center;
}
.wrapper .square:hover, .square.selected {
background: white;
}
body { background-color: #888; }
<div class="wrapper squares">
<div class="square">A</div>
<div class="square">B</div>
<div class="square">C</div>
<div class="square">D</div>
<div class="square">E</div>
<div class="square">F</div>
<div class="square">G</div>
</div>
Your primary issue is this:
<div onclick="set()" id="square"></div>
<div onclick="set()" id="square"></div>
<div onclick="set()" id="square"></div>
<div onclick="set()" id="square"></div>
<div onclick="set()" id="square"></div>
<div onclick="set()" id="square"></div>
<div onclick="set()" id="square"></div>
It's invalid to have the same id on more than one element. An id must be unique. So this line:
var squares = document.getElementById('square');
just selects the first div and then later, when you try to loop over all the cells, you don't because you never had all of the cells in the first place.
You just need to set one click handler on the parent of all the div cells. Then, in that handler, you can apply a CSS class to the div that triggered the event. This is called event delegation and works because events bubble up through the DOM.
// Get a reference to all the cells
let squares = document.querySelectorAll("div.wrapper > div");
// Set up you event handlers in JavaScipt, not with inline HTML
// event attributes like onclick
document.querySelector(".wrapper").addEventListener("click", function(event) {
// Remove all the background colors from all the cells
squares.forEach(function(square){
square.classList.remove("activeCell");
});
// Apply backgroun to clicked cell
event.target.classList.add("activeCell");
});
.wrapper {
display: grid;
grid-template-columns: repeat(107, 1fr);
grid-template-rows: repeat(59, 1fr);
grid-gap: 0px;
}
.wrapper > div {
padding: 5px;
background-color: none;
text-align: center;
border: 0.001px solid black;
font-size: 5px;
display: flex;
justify-content: center;
align-items: center;
}
.wrapper div:hover {
background: green;
}
.activeCell {
background-color:blue;
}
<div class="wrapper">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
So I've been trying to make a grid for the past 30 minutes and I can't seem to get it to work. I've tried the piece of code on a sandbox and it worked there. I don't understand why it wont work on my page. What happens is all the divs get placed under each other and I want them to be next to each other instead.
What happens:
div1
div2
div3
What I want to happen:
div1 div2 div3
<div class="jar-lists-wrapper slide-in">
#foreach($folders as $folder)
<div class="jar-lists hidden" data-name="{{$folder}}">
<div class="jar-list box" data-name="{{$folder}}">
<div class="box-header with-border">
<h1 class="box-title">{{$folder}}</h1>
</div>
<div class="box-body">
<div class="jar-children">
#foreach($jars as $jar)
#if(strpos($jar, strtolower($folder)) !== false)
<div>
<h3 class="jar-title">Version:
{{str_replace(array(strtolower($folder) . '-', '.jar'), '', $jar)}}
</h3>
<form action="{{ route('server.settings.jar.switch', $server->uuidShort) }}" method="POST">
#if(str_replace('.jar', '', $jar) == $currentJar)
<br><button class="btn btn-success" type="submit">Installed</button>
#else
<br><button class="btn btn-primary" type="submit">Install</button>
#endif
</form>
<br>
</div>
#endif
#endforeach
</div>
</div>
<div class="box-footer">
View More<i class="fa fa-caret-down"></i>
</div>
</div>
</div>
#endforeach
</div>
And this is my css:
.main {
width: 90%;
max-width: 1300px;
margin: 0 auto;
padding: 2em
}
.jar-lists-wrapper {
position: relative;
display: block
}
.jar-lists {
position: relative;
margin-bottom: 60px;
margin-top: 30px;
width: 100%;
display: grid;
grid-template-columns: repeat(3, 32.5%);
justify-content: space-between;
z-index: 1
}
.jar-lists.hidden {
display: none
}
.jar-list {
text-align: center;
}
.jar-title {
font-size: 16px;
color: #5e5e5e
}
.jars-more {
display: block;
width: 100%;
text-decoration: none;
text-align: center
}
.jars-more {
padding: 10px 0;
font-size: 18px;
color: gray;
cursor: pointer
}
.jars-more i {
margin-left: 10px
}
#media screen and (max-width:1250px) {
.jar-lists {
grid-template-columns: repeat(2, 47%)
}
.jar-list {
margin-bottom: 30px
}
}
#media screen and (max-width:900px) {
.jar-lists {
grid-template-columns: repeat(1, 100%)
}
}
div are block level element so they appears horizontally. So use display:inline-block and width
.child {
display: inline-block;
width: 100px;
height: 100px;
border: 1px solid red;
}
<div class='parent'>
<div class='child'>1</div>
<div class='child'>1</div>
<div class='child'>1</div>
</div>
You can also use flex
.parent {
display: flex;
flex-direction: row;
}
.child {
border: 2px solid green;
width: 150px;
}
<div class='parent'>
<div class='child'>1</div>
<div class='child'>1</div>
<div class='child'>1</div>
</div>
You can also use grid
.parent {
display: grid;
grid-template-columns: repeat(3, 1fr)
}
.child {
border: 1px solid red;
}
<div class='parent'>
<div class='child'>1</div>
<div class='child'>1</div>
<div class='child'>1</div>
</div
Try specifying gird-template-spacing from 32.5% to 1fr.
This question already has an answer here:
How to add components to css max-width, height calculation?
(1 answer)
Closed 3 years ago.
I need two div. A left and a right one. Left has a fix aspect ratio (i.e. 2/3), the right one's height is the same as the left one but the width has a fix value i.e. 200px. How can I compose it? Goal is to use as much space of the browser as possible.
The left fix aspect ratio div is ok:
body {
padding: 0;
margin: 0;
}
.r-4by3-wrap {
max-width: calc(100vmin * 2 / 3);
margin: auto;
}
.r-4by3 {
height: 0;
padding-top: 150%;
display: flex;
}
<div class="r-4by3-wrap">
<div style="border: 10px solid red">
<div class="r-4by3" style="background: pink">
</div>
</div>
</div>
but how can put the right one next to the left?
I'm not a big fan of lots of nested elements, but you can solve this by wrapping the left and right divs in a parent flex container. Make sure you do the width calculation on the parent and add the 200px you want for the right div:
body {
padding: 0;
margin: 0;
}
.parent {
display: flex;
margin: 0 auto;
max-width: calc(calc(100vmin * 2 / 3) + 200px);
}
.r-4by3-wrap {
width: calc(100vmin * 2 / 3);
margin: auto;
}
.r-4by3 {
height: 0;
padding-top: 150%;
}
.right {
border: 10px solid blue;
background: lightblue;
width: 200px;
}
<div class="parent">
<div class="r-4by3-wrap">
<div style="border: 10px solid red">
<div class="r-4by3" style="background: pink">
</div>
</div>
</div>
<div class="right"></div>
</div>
CSS-Grid can help here:
body {
padding: 0;
margin: 0;
}
.inner {
border: 10px solid red;
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
.r-4by3-wrap {
//max-width: calc(100vmin * 2 / 3);
margin: auto;
}
.r-4by3 {
height: 0;
padding-top: 150%;
grid-column: 2;
}
.right {
max-width: 100px;
/* for demo only */
background: lightblue;
}
<div class="r-4by3-wrap">
<div class="inner">
<div class="r-4by3" style="background: pink">
</div>
<div class="right">Right</div>
</div>
</div>