Reputation: 34177
I am trying to create two buttons that each toggle a specific column when using CSS grid
.
I have a simply grid that toggles the width of first and last columns. (See snippet)
I want to be able to toggle the column widths independantly (Without further javascript).
Because the active
class is applied to the container each column cannot infer the active state of the other.
With flex the active class would be applied to the column (e.g item1
) directly making this a non issue.
QUESTION
Is there a CSS grid column width property that can be applied to a column (e.g item1
) overiding the settings in grid-template-columns
?
OR
Is there a CSS grid property like grid-template-columns
that can target individual columns rather than all columns in one property?
$("#js-btn-left").on("click", function () {
$(".grid-container").toggleClass("active");
});
$("#js-btn-right").on("click", function () {
$(".grid-container").toggleClass("active");
});
.grid-container {
display: grid;
grid-template-columns: 50px auto 50px;
grid-gap: 10px;
}
.grid-container > div {
background-color: #b00;
border:2px solid #000;
text-align: center;
padding: 20px 0;
font-size: 30px;
}
.grid-container.active{
grid-template-columns: 100px auto 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="js-btn-left" type="button" value="TOGGLE COLUMN 1"/>
<input id="js-btn-right" type="button" value="TOGGLE COLUMN 3"/>
<div class="grid-container">
<div class="item1">1</div>
<div class="item2">2</div>
<div class="item3">3</div>
</div>
Upvotes: 4
Views: 2370
Reputation: 272723
Define the columns using CSS variables and then simply adjust the variable:
$("#js-btn-left").on("click", function () {
$(".grid-container").toggleClass("active1");
});
$("#js-btn-right").on("click", function () {
$(".grid-container").toggleClass("active3");
});
.grid-container {
display: grid;
grid-template-columns: var(--c1,50px) auto var(--c3,50px);
grid-gap: 10px;
}
.grid-container > div {
background-color: #b00;
border:2px solid #000;
text-align: center;
padding: 20px 0;
font-size: 30px;
}
.grid-container.active1{
--c1:100px;
}
.grid-container.active3{
--c3:100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="js-btn-left" type="button" value="TOGGLE COLUMN 1"/>
<input id="js-btn-right" type="button" value="TOGGLE COLUMN 3"/>
<div class="grid-container">
<div class="item1">1</div>
<div class="item2">2</div>
<div class="item3">3</div>
</div>
Another hacky way is to rely on the implicit grid and adjust grid-auto-column
$("#js-btn-right").on("click", function () {
$(".grid-container").toggleClass("active");
});
.grid-container {
display: grid;
grid-template-columns: auto ; /* only one column on the explicit grid */
grid-auto-flow:column; /*Make the flow column*/
grid-auto-columns:50px;
grid-gap: 10px;
}
.item1 {
/* Make the item1 at the left of the explicit grid
to undestand how it works:
https://stackoverflow.com/a/57750033/8620333 */
grid-column: random -1;
}
.grid-container.active{
grid-auto-columns:100px;
}
.grid-container > div {
background-color: #b00;
border:2px solid #000;
text-align: center;
padding: 20px 0;
font-size: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="js-btn-right" type="button" value="TOGGLE COLUMN"/>
<div class="grid-container">
<div class="item1">1</div>
<div class="item2">2</div>
<div class="item3">3</div>
</div>
If you want to target only one column:
$("#js-btn-right").on("click", function () {
$(".grid-container").toggleClass("active");
});
.grid-container {
display: grid;
grid-template-columns: 50px auto ;
grid-auto-flow:column;
grid-auto-columns:50px;
grid-gap: 10px;
}
.grid-container.active{
grid-auto-columns:100px;
}
.grid-container > div {
background-color: #b00;
border:2px solid #000;
text-align: center;
padding: 20px 0;
font-size: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="js-btn-right" type="button" value="TOGGLE COLUMN"/>
<div class="grid-container">
<div class="item1">1</div>
<div class="item2">2</div>
<div class="item3">3</div>
</div>
Or instead of changing the column width you can simply change the number of column each item should take:
$("#js-btn-left").on("click", function () {
$(".grid-container").toggleClass("active1");
});
$("#js-btn-right").on("click", function () {
$(".grid-container").toggleClass("active3");
});
.grid-container {
display: grid;
grid-template-columns: 50px 40px auto 40px 50px; /* 40px because we have 10px of gap so the total will be 100px */
grid-gap: 10px;
}
.grid-container > div {
background-color: #b00;
border:2px solid #000;
text-align: center;
padding: 20px 0;
font-size: 30px;
}
.item2 {
grid-column:span 3;
}
.grid-container.active3 .item3,
.grid-container.active3 .item2,
.grid-container.active1 .item1,
.grid-container.active1 .item2{
grid-column:span 2;
}
.grid-container.active1.active3 .item2{
grid-column:initial;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input id="js-btn-left" type="button" value="TOGGLE COLUMN 1"/>
<input id="js-btn-right" type="button" value="TOGGLE COLUMN 3"/>
<div class="grid-container">
<div class="item1">1</div>
<div class="item2">2</div>
<div class="item3">3</div>
</div>
Upvotes: 5