admin管理员组文章数量:1124648
I created a side navigation bar and a main content area. I arranged these in a grid layout using display: grid with columns set to 200px. I also wrote a JavaScript script to toggle the class list. When I click the toggle button, the side navigation shrinks, but the main content area maintains the same width. How can I make the main content area fill the full width?
function toggleSidebar() {
const sidebar = document.querySelector('.sidebar');
sidebar.classList.toggle('shrink');
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
height: 100vh;
}
.container {
display: grid;
grid-template-columns: 200px minmax(0,1fr); /* Sidebar takes 200px, main content takes remaining space */
height: 100%;
grid-template-rows: 1fr; /* Only one row for this layout */
}
.sidebar {
background-color: #333;
color: white;
padding: 15px;
overflow: hidden;
transition: width 0.3s ease-in-out; /* Transition effect for shrinking */
}
.sidebar ul {
list-style-type: none;
}
.sidebar ul li {
margin-bottom: 10px;
}
.sidebar ul li a {
color: white;
text-decoration: none;
}
.main-content {
background-color: red;
padding: 20px;
overflow: auto;
}
.sidebar.shrink {
width: 50px; /* Shrinks the sidebar width to 50px */
}
.sidebar.shrink ul {
display: none; /* Hide the links when the sidebar is shrunk */
}
.main-content {
transition: margin-left 0.3s ease-in-out; /* Adjust content area when sidebar shrinks */
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Responsive Grid Layout</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<button onclick="toggleSidebar()">Toggle Sidebar</button>
<div class="container">
<nav class="sidebar">
<!-- Side Navigation Content -->
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Services</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
<main class="main-content">
<!-- Main Content Area -->
<h1>Welcome to the main content area</h1>
<p>This area should adjust its size based on the sidebar.</p>
</main>
</div>
</body>
</html>
I created a side navigation bar and a main content area. I arranged these in a grid layout using display: grid with columns set to 200px. I also wrote a JavaScript script to toggle the class list. When I click the toggle button, the side navigation shrinks, but the main content area maintains the same width. How can I make the main content area fill the full width?
function toggleSidebar() {
const sidebar = document.querySelector('.sidebar');
sidebar.classList.toggle('shrink');
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
height: 100vh;
}
.container {
display: grid;
grid-template-columns: 200px minmax(0,1fr); /* Sidebar takes 200px, main content takes remaining space */
height: 100%;
grid-template-rows: 1fr; /* Only one row for this layout */
}
.sidebar {
background-color: #333;
color: white;
padding: 15px;
overflow: hidden;
transition: width 0.3s ease-in-out; /* Transition effect for shrinking */
}
.sidebar ul {
list-style-type: none;
}
.sidebar ul li {
margin-bottom: 10px;
}
.sidebar ul li a {
color: white;
text-decoration: none;
}
.main-content {
background-color: red;
padding: 20px;
overflow: auto;
}
.sidebar.shrink {
width: 50px; /* Shrinks the sidebar width to 50px */
}
.sidebar.shrink ul {
display: none; /* Hide the links when the sidebar is shrunk */
}
.main-content {
transition: margin-left 0.3s ease-in-out; /* Adjust content area when sidebar shrinks */
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Responsive Grid Layout</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<button onclick="toggleSidebar()">Toggle Sidebar</button>
<div class="container">
<nav class="sidebar">
<!-- Side Navigation Content -->
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Services</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
<main class="main-content">
<!-- Main Content Area -->
<h1>Welcome to the main content area</h1>
<p>This area should adjust its size based on the sidebar.</p>
</main>
</div>
</body>
</html>
Share
Improve this question
asked 2 days ago
Velugoti VenkateswarluVelugoti Venkateswarlu
2133 silver badges6 bronze badges
3 Answers
Reset to default 1You have to modify the grid container, not the container elements, to show/hide the sidebar.
The only CSS property you need to modify is grid-template-columns
inside the .container
CSS selector:
.container {
display: grid;
grid-template-columns: 0 1fr;
}
.container.sidebar-opened {
grid-template-columns: 200px 1fr;
}
I leave you an example below with a smooth transition:
function toggleSidebar() {
const container = document.querySelector(".container");
container.classList.toggle("sidebar-opened");
}
.container {
display: grid;
grid-template-columns: 0 1fr;
transition: grid-template-columns 300ms;
height: 100svh;
}
.container.sidebar-opened {
grid-template-columns: 200px 1fr;
}
/* Other non-related styles */
html {
box-sizing: border-box;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
margin: 0;
}
aside {
height: 100%;
padding: 10px;
background-color: wheat;
}
main {
height: 100%;
padding: 10px;
background-color: lightblue;
}
button {
position: fixed;
top: 10px;
right: 10px;
}
<div class="container">
<aside>Sidebar</aside>
<main>Main content</main>
</div>
<button onclick="toggleSidebar()">Toggle sidebar</button>
You need a new shrink
class to make sure it's being injected via JavaScript when you close the sidebar.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Responsive Sidebar Layout</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<button class="toggle-button" onclick="toggleSidebar()">Toggle Sidebar</button>
<div class="container">
<nav class="sidebar">
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Services</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
<main class="main-content">
<h1>Welcome to the main content area</h1>
<p>This area should adjust its size based on the sidebar state.</p>
</main>
</div>
<script src="script.js"></script>
</body>
</html>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
height: 100vh;
}
.toggle-button {
position: absolute;
top: 10px;
left: 10px;
z-index: 1000;
padding: 10px 20px;
background-color: #333;
color: white;
border: none;
cursor: pointer;
border-radius: 5px;
transition: background-color 0.3s ease-in-out;
}
.toggle-button:hover {
background-color: #555;
}
/* Container Grid Layout */
.container {
display: grid;
grid-template-columns: 200px minmax(0, 1fr); /* Sidebar width and main content fill */
height: 100%;
transition: grid-template-columns 0.3s ease-in-out;
}
/* Sidebar Styling */
.sidebar {
background-color: #333;
color: white;
padding: 15px;
overflow: hidden;
transition: transform 0.3s ease-in-out;
}
.sidebar ul {
list-style-type: none;
}
.sidebar ul li {
margin-bottom: 10px;
}
.sidebar ul li a {
color: white;
text-decoration: none;
}
/* Main Content Styling */
.main-content {
background-color: red;
padding: 20px;
overflow: auto;
}
/* Hidden Sidebar State */
.container.shrink {
grid-template-columns: 0 minmax(0, 1fr); /* Sidebar is hidden, main content takes full width as 0 column is stated here */
}
.sidebar.shrink {
transform: translateX(-200px); /* Completely hide sidebar */
}
function toggleSidebar() {
const container = document.querySelector('.container');
const sidebar = document.querySelector('.sidebar');
// Toggle classes to shrink/hide the sidebar
container.classList.toggle('shrink');
sidebar.classList.toggle('shrink');
}
While you've already accepted an answer, I wanted to share an alternative that doesn't require JavaScript. It's worth pointing out that while the following answer works in contemporary browsers and is newly-available in Baseline (thanks to Firefox catching up somewhat recently), this is only true for versions:
- Chrome 85
- Edge 85
- Firefox 128
- Opera 71
- Safari 16.4
If you have users with older browsers you could either rely on JavaScript, or potentially use a shim for those browsers that this can't work with, or even use an @supports()
declaration to progressively enhance your project only for those browsers that can't use @property
or, potentially, even the :has()
pseudo-class.
With all that said, the possible approach is below with explanatory comments in the code:
/* here we've set up some layers for the CSS in order to establish multiple different rules,
fundamentally priority increases from left to right (there are caveats around !important
and so on, but check the references), so the first layer (reset) is least important but
normalises the layout, the next layer is your posted CSS, and the demo layer is
where I've written mine: */
@layer reset, from-question, demo;
/* using an @import to bring in the reset from a CDN, and using the layer() function to
assigne a layer name to the imported stylesheet: */
@import url(https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.css) layer(reset);
@layer from-question {
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Arial, sans-serif;
height: 100vh;
}
.container {
display: grid;
grid-template-columns: 200px minmax(0, 1fr);
/* Sidebar takes 200px, main content takes remaining space */
height: 100%;
grid-template-rows: 1fr;
/* Only one row for this layout */
}
.sidebar {
background-color: #333;
color: white;
padding: 15px;
overflow: hidden;
transition: width 0.3s ease-in-out;
/* Transition effect for shrinking */
}
.sidebar ul {
list-style-type: none;
}
.sidebar ul li {
margin-bottom: 10px;
}
.sidebar ul li a {
color: white;
text-decoration: none;
}
.main-content {
background-color: red;
padding: 20px;
overflow: auto;
}
.sidebar.shrink {
width: 50px;
/* Shrinks the sidebar width to 50px */
}
.sidebar.shrink ul {
display: none;
/* Hide the links when the sidebar is shrunk */
}
.main-content {
transition: margin-left 0.3s ease-in-out;
/* Adjust content area when sidebar shrinks */
}
}
/* effectively, this is where my answer starts: */
@layer demo {
/* declaring and initialising a new property, which is accessible as a variable within the
CSS; we're doing this so that we can use a transition using this property. Each of the
shown properties are required, though obviously the property-values should be changed
as appropriate (see the references for a full explanation): */
@property --sidebarWidth {
syntax: "<length>";
inherits: false;
initial-value: 0px;
}
/* ensuring that the <main> element takes the full space on the block-axis, the axis
on which blocks are laid out relative to one another; in English, this is vertical
equivalent to "height," other languages vary: */
main {
block-size: 100%;
}
/* my naming convention for <label> elements used as switches is to end their id
with the suffix of "-toggle" to assign a meaningful name, here we select all
elements with a "for" attribute that ends with ($=) the string "toggle":*/
[for$="toggle"] {
border: 1px solid;
border-radius: 0.3em;
cursor: pointer;
display: inline-block;
margin-block: 0.4em;
margin-inline: 0.4em;
padding-block: 0.2em;
padding-inline: 0.4em;
}
/* visually hiding the <input> element: */
input[type=checkbox][id$=toggle] {
aspect-ratio: 1;
block-size: 1px;
overflow: clip;
position: absolute;
}
.container {
display: grid;
/* I prefer to use named grid-columns, here we have:
all: full-width, spans all columns,
sidebar: 0px (from the definition (above) of the custom property),
main-content: 1fr (taking all remaining space)
*/
grid-template-columns: [all-start sidebar-start] var(--sidebarWidth) [sidebar-end main-content-start] 1fr [main-content-end all-end];
/* here we specify the transition on the grid-template-columns property, which will take 350 milliseconds, and progress linearly: */
transition: grid-template-columns 350ms linear;
/* Using CSS nesting to select, and style, the current element (.container) that has a #sidebar-toggle
element which is :checked: */
&:has(#sidebar-toggle:checked) {
/* here we update the property-value of the --sidebarWidth custom property, this value is then used in the
grid-template-columns declaration, and the animation starts: */
--sidebarWidth: 200px;
}
}
}
<!-- the <main> element is used to wrap all page content simply to make
writing the answer - in terms of copy/pasting from the DOM easier
in the event I use JavaScript to modify HTML, other than that it's
not necessary: -->
<main>
<!-- removed this element because this is possible without JavaScript
<button onclick="toggleSidebar()">Toggle Sidebar</button>
-->
<!-- instead of the <button>, I'm using a <label> element, simply because
it allows us to use a state-change (on an <input> associated with this
<label> via the identical attribute-value for this element's "for"
attribute, the <input> element's "id") -->
<label for="sidebar-toggle">
<span class="labelText">Toggle sidebar</span>
</label>
<div class="container">
<!-- here's the <input> assocuated with the previous <label>
which affects the state visibility of the sidebar, if
the <input> is checked (:checked) the sidebar is shown,
otherwise it's hidden: -->
<input type="checkbox" id="sidebar-toggle" />
<nav class="sidebar">
<!-- Side Navigation Content -->
<ul>
<li><a href="#">Home</a></li>
<li><a href="#">About</a></li>
<li><a href="#">Services</a></li>
<li><a href="#">Contact</a></li>
</ul>
</nav>
<main class="main-content">
<!-- Main Content Area -->
<h1>Welcome to the main content area</h1>
<p>This area should adjust its size based on the sidebar.</p>
</main>
</div>
</main>
JS Fiddle demo.
References:
@import
.@layer
.@property
aspect-ratio
.background-color
.block-size
.border
.border-radius
.box-sizing
.color
.cursor
.display
.font-family
.grid-template-columns
.grid-template-rows
.height
.layer()
, discussed on the same page as previous@layer
reference.list-style-type
.margin
.margin-block
.margin-bottom
.margin-inline
.padding
.padding-block
.padding-inline
.position
.text-decoration
.transition
.url()
.width
.
Bibliography:
- Baseline.
本文标签: javascriptHow to expand one column width while other column shrinks in css grid layoutStack Overflow
版权声明:本文标题:javascript - How to expand one column width while other column shrinks in css grid layout? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736646289a1946114.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论