I would like to restructure a page on my angularJS website. Currently data is being displayed in a table view; I would like to create a left sidebar with a (tile) list of names. When a name is clicked on, the right sidebar should display additional details about the selected individual. Any guidance on how to efficiently accomplish this using HTML and CSS will be much appreciated.
Here is the simple code I have so far:
body {
margin: 40px;
}
.lft_sidebar {
grid-area: sidebar;
}
.content {
grid-area: content;
}
.header {
grid-area: header;
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: 120px 120px 120px;
grid-template-areas: "....... header header" "sidebar content content" "footer footer footer";
background-color: #fff;
color: #444;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 10px;
font-size: 150%;
}
.header,
.footer {
background-color: #999;
}
<div class="wrapper">
<div class="header">Header</div>
<div class="lft_sidebar">Neme 1</div>
<div class="lft_sidebar">Name 2</div>
<div class="lft_sidebar">Name 3</div>
<div class="lft_sidebar">Name 4</div>
<div class="rght_sidebar"> More details about Selected Name</div>
</div>
You can use the grid-column-start and grid-column-end CSS properties to specify where a grid cell should start / end.
body {
margin: 40px;
}
.lft_sidebar {
grid-area: sidebar;
}
.left {
grid-column-start: 1;
grid-column-end: 2;
}
.rght_sidebar {
grid-column-start: 2;
grid-column-end: 4;
}
.header {
grid-column-start: 1;
grid-column-end: 4;
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: repeat(3, 1fr);
background-color: #fff;
color: #444;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 10px;
font-size: 150%;
}
.header,
.footer {
background-color: #999;
}
<div class="wrapper">
<div class="header">Header</div>
<div class="left">
<div class="lft_sidebar">Neme 1</div>
<div class="lft_sidebar">Name 2</div>
<div class="lft_sidebar">Name 3</div>
<div class="lft_sidebar">Name 4</div>
</div>
<div class="rght_sidebar"> More details about Selected Name</div>
</div>
Related
I have started using Grid CSS and i am stuck in building a Layout using Grid system.
I am looking to build a layout where the column would overlap a row and take full height. I have attached a screenshot of the layout and what i have tried so far.
body {
margin: 40px;
}
.sidebar {
grid-area: sidebar;
}
.content {
grid-area: content;
}
.header {
grid-area: header;
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: 120px 120px 120px;
grid-template-areas:
"header header header"
"sidebar content content";
background-color: #fff;
color: #444;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
.header {
background-color: #999;
}
.overlay {
background-color: red;
z-index: 10;
grid-column: content-start / content-end;
grid-row: header-start / content-end;
}
<div class="wrapper">
<div class="box header">Header</div>
<div class="box sidebar">Sidebar</div>
<div class="overlay">Content</div>
</div>
Depending on how you want to overlap the following code works, but need to be adapted:
There's a lot of other way to do this...
body {
margin: 40px;
}
.sidebar {
grid-area: sidebar;
}
.content {
grid-area: content;
}
.header {
grid-area: header;
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: 120px 120px 120px;
grid-template-rows: 30px 30px auto auto;
grid-template-areas:
"header header header"
"sidebar content content";
background-color: #fff;
color: #444;
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
}
.header {
background-color: #999;
grid-row: 1 / 3;
}
.sidebar {
background-color: red;
z-index: 10;
grid-row: 2 / 4;
height: 300px;
}
.overlay {
background-color: red;
z-index: 10;
grid-column: content-start / content-end;
grid-row: 3 / 4;
}
<div class="wrapper">
<div class="box header">Header</div>
<div class="box sidebar">Sidebar</div>
<div class="overlay">Content</div>
</div>
.main-dev {
display: grid;
grid-template-columns: 50% 50%;
}
I want to arrange my grid into 50% 50% and 100% structures. I have attached the required output image.
Current output :
Expected Output :
.item {
border: 1px solid red;
text-align: center;
padding: 10px;
}
.main-dev {
display: grid;
grid-template-columns: 1fr 1fr;
width: 200px;
border: solid red 1px;
}
.item3 {
grid-column: 1 / 3;
/* or grid-column: 1 / span 2 */
}
<div class="main-dev">
<div class="item">1</div>
<div class="item">2</div>
<div class="item item3">3</div>
You can try this,
.item3 {
grid-column-start: 1;
grid-column-end: 3;
}
.grid-container {
display: grid;
grid-template-columns: auto auto auto;
grid-gap: 10px;
background-color: #2196F3;
padding: 10px;
}
.grid-container > div {
background-color: rgba(255, 255, 255, 0.8);
text-align: center;
padding: 20px 0;
font-size: 30px;
}
<div class="grid-container">
<div class="item1">1</div>
<div class="item2">2</div>
<div class="item3">3</div>
</div>
So. Let's imagine you have 3 items with class names item1, item2, item3.
Here is the style for them:
.item1 { grid-area: item1; }
.item2 { grid-area: item2; }
.item3 { grid-area: item3; }
div{
display: grid;
grid-template-areas:
'item1 item2'
'item3 item3'
grid-gap: 10px;}
First of all, you can use col-. Here is my example:
.red{
border: 1px solid red;
height:200px;
}
.col-6{
float:left;
width:50%;
}
.col-12{
float:left;
width:100%;
}
<body>
<div class="col-6">
<div class="red"></div>
</div>
<div class="col-6">
<div class="red"></div>
</div>
<div class="col-12">
<div class="red"></div>
</div>
</body>
And you can modify the code as you like.
How would my code look for the following layout? How do I create multiple nav and headers in HTML?
Simply use grid-template-areas to set your layout:
body {
display: grid;
grid-template-areas:
"headerA headerB headerB headerB headerB"
"headerA navB navB navB navB"
"navA article article article aside"
"footer footer footer footer footer";
}
.header-1 {
grid-area: headerA;
}
.header-2 {
grid-area: headerB;
}
.nav-1 {
grid-area: navA;
}
.nav-2 {
grid-area: navB;
}
.article {
grid-area: article;
}
.aside {
grid-area: aside;
}
.footer {
grid-area: footer;
}
/* for styling puropse only */
body {
grid-gap: 2px;
}
body > div {
display: flex;
justify-content: center;
align-items: center;
min-height: 50px;
box-shadow: 0 0 0 2px lightgrey;
}
.article {
min-height: 102px;
}
<div class="header-1">Header 1</div>
<div class="header-2">Header 2</div>
<div class="nav-1">Navigation Bar 1</div>
<div class="nav-2">Navigation Bar 1</div>
<div class="article">Article</div>
<div class="aside">Aside</div>
<div class="footer">Footer</div>
Essentially what I need to happen is to set up a grid, but if one of the elements is missing, another element stretches to fill the space.
This is an example Pen of where I'm currently at:
https://codepen.io/Rockster160/pen/JMLaXY
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
div {
box-sizing: border-box;
}
.grid {
height: 100%;
width: 100%;
background: white;
border: 2px solid red;
display: grid;
grid-template-columns: 250px auto;
grid-template-rows: 100px auto 50px;
grid-template-areas: "sidebar header"
"sidebar content"
"sidebar footer";
}
.sidebar {
grid-area: sidebar;
background: green;
}
.header {
grid-area: header;
background: lightblue;
}
.content {
grid-area: content;
background: blue;
border: 5px solid black;
}
.footer {
grid-area: footer;
background: orange;
}
<div class="grid">
<div class="sidebar"></div>
<div class="header"></div>
<div class="content"></div>
<!-- <div class="footer"></div> -->
</div>
footer is an optional element, so when it doesn't exist (commented out as in the code) then content should stretch and line up with the bottom of sidebar.
I've tried a variety of different combinations using min/max content and different auto placements, but no luck. I thought if I had multiple elements named content it might work as well, but no luck there either.
Any help is greatly appreciated!
You are forcing the 3rd row to be 50px in the grid style.
Change it to be adapted to the content, and set the 50px as height in the footer itself:
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
div {
box-sizing: border-box;
}
.grid {
height: 100%;
width: 100%;
background: white;
border: 2px solid red;
display: grid;
grid-template-columns: 250px auto;
grid-template-rows: 100px auto max-content; /* changed last 50px to max-content*/
grid-template-areas: "sidebar header"
"sidebar content"
"sidebar footer";
}
.sidebar {
grid-area: sidebar;
background: green;
}
.header {
grid-area: header;
background: lightblue;
}
.content {
grid-area: content;
background: blue;
border: 5px solid black;
}
.footer {
grid-area: footer;
background: orange;
height: 50px; /* added */
}
<div class="grid">
<div class="sidebar"></div>
<div class="header"></div>
<div class="content"></div>
<!-- <div class="footer"></div> -->
</div>
And another posibility, thanks to Michael_B. The sintax of grid-template-rows is clearer:
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
div {
box-sizing: border-box;
}
.grid {
height: 100%;
width: 100%;
background: white;
border: 2px solid red;
display: grid;
grid-template-columns: 250px auto;
grid-template-rows: 100px 1fr auto;
grid-template-areas: "sidebar header"
"sidebar content"
"sidebar footer";
}
.sidebar {
grid-area: sidebar;
background: green;
}
.header {
grid-area: header;
background: lightblue;
}
.content {
grid-area: content;
background: blue;
border: 5px solid black;
}
.footer {
grid-area: footer;
background: orange;
height: 50px; /* added */
}
<div class="grid">
<div class="sidebar"></div>
<div class="header"></div>
<div class="content"></div>
<div class="footer"></div>
</div>
The easiest way to do this is to use the :last-child selector:
.content:last-child {
grid-row: content / footer;
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
div {
box-sizing: border-box;
}
.grid {
height: 100%;
width: 100%;
background: white;
border: 2px solid red;
display: grid;
grid-template-columns: 250px auto;
grid-template-rows: 100px auto 50px;
grid-template-areas: "sidebar header" "sidebar content" "sidebar footer";
margin-bottom: 2rem;
}
.sidebar {
grid-area: sidebar;
background: green;
}
.header {
grid-area: header;
background: lightblue;
}
.content {
grid-area: content;
background: blue;
border: 5px solid black;
}
.content:last-child {
grid-row: content / footer;
}
.footer {
grid-area: footer;
background: orange;
}
<div class="grid">
<div class="sidebar"></div>
<div class="header"></div>
<div class="content"></div>
<!-- <div class="footer"></div> -->
</div>
<div class="grid">
<div class="sidebar"></div>
<div class="header"></div>
<div class="content"></div>
<div class="footer"></div>
</div>
Or, alternatively, we could reverse the order of the .content and .footer elements in the HTML (as below) and use the CSS negation operator (:not()) to determine that the .content element should take up extra space if it is not preceded by a .footer element:
:not(.footer) + .content {
grid-row: content/footer;
}
which styles a .content element that is not immediately preceded by a .footer sibling in such a way that it starts in the grid-row identified by content and ends in the grid-row identified by footer:
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
div {
box-sizing: border-box;
}
.grid {
height: 100%;
width: 100%;
background: white;
border: 2px solid red;
display: grid;
grid-template-columns: 250px auto;
grid-template-rows: 100px auto 50px;
grid-template-areas: "sidebar header" "sidebar content" "sidebar footer";
}
.sidebar {
grid-area: sidebar;
background: green;
}
.header {
grid-area: header;
background: lightblue;
}
.content {
grid-area: content;
background: blue;
border: 5px solid black;
}
:not(.footer)+.content {
grid-row: content/footer;
}
.footer {
grid-area: footer;
background: orange;
}
<div class="grid">
<div class="sidebar"></div>
<div class="header"></div>
<div class="content"></div>
<!-- <div class="footer"></div> -->
</div>
<div class="grid">
<div class="sidebar"></div>
<div class="header"></div>
<div class="content"></div>
<div class="footer"></div>
</div>
References:
grid-row.
:last-child.
Negation pseudo-class:not().
Sometimes things are simpler with flexbox.
Since your container has a defined height (the viewport), you can use flex-flow: column wrap to create both columns.
Then use flex: 1 on the content item, which tells it to consume free space.
When the footer is present, the content makes space for it. When the footer is not present, the content consumes all space.
.grid {
display: flex;
flex-flow: column wrap;
height: 100vh;
background: white;
border: 2px solid red;
}
.sidebar {
flex: 0 0 100%;
width: 250px;
background: green;
}
.header {
flex: 0 0 100px;
width: calc(100% - 250px);
background: lightblue;
}
.content {
flex: 1;
width: calc(100% - 250px);
border: 5px solid black;
background: blue;
}
.footer {
flex: 0 0 50px;
width: calc(100% - 250px);
background: orange;
}
body { margin: 0; }
div { box-sizing: border-box; }
<!-- WITH FOOTER -->
<div class="grid">
<div class="sidebar"></div>
<div class="header"></div>
<div class="content"></div>
<div class="footer"></div>
</div>
<hr>
<!-- WITHOUT FOOTER -->
<div class="grid">
<div class="sidebar"></div>
<div class="header"></div>
<div class="content"></div>
</div>
Change your .grid class to
.grid {
display: grid;
grid-template-columns: 250px auto;
grid-template-rows: 100px auto 50px;
grid-template-areas:
"sidebar header"
"sidebar content"
"sidebar content";
}
when you comment your footer tag as in your pen, grid is still waiting to have a footer element there, so it's kinda "saving space" for this element there
Disclaimer: I'm not an experienced web designer.
I've been playing around with grid and have this mock up for different screen sizes but I cannot understand why the div content area grows so much taller than the nested panelwrap grid inside it? (Im testing on Chrome).
According to chrome inspector the size only grows when the content area is over 647px wide.
I just want to understand why the space occurs?
body {
margin: 1em;
}
.sidebar {
grid-area: sidebar;
}
.sidebar2 {
grid-area: sidebar2;
}
.content {
grid-area: content;
}
.header {
grid-area: header;
}
.footer {
grid-area: footer;
}
.wrapper {
background-color: #fff;
color: #444;
}
.wrapper {
margin: auto;
display: grid;
grid-gap: 1em;
grid-template-areas: "header" "sidebar" "content" "sidebar2" "footer"
}
#media only screen and (min-width: 500px) {
.wrapper {
grid-template-columns: 20% auto;
grid-template-areas: "header header" "sidebar content" "sidebar2 sidebar2" "footer footer";
}
}
#media only screen and (min-width: 600px) {
.wrapper {
grid-gap: 20px;
grid-template-columns: 120px auto 120px;
grid-template-areas: "header header header" "sidebar content sidebar2" "footer footer footer";
max-width: auto;
}
}
.box {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 0.5em;
font-size: 150%;
}
.header,
.footer {
background-color: #999;
}
.sidebar2 {
background-color: #ccc;
color: #444;
}
.panelwrap {
display: grid;
padding: 0.5em;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
grid-auto-rows: minmax(auto, auto);
grid-gap: 0.5em;
}
.panel {
background-color: #fff;
color: #555;
border-radius: 5px;
padding: 0.5em;
}
.tall-panel {
grid-row-end: span 2;
}
.wide-panel {
grid-column-end: span 2;
}
<div class="wrapper">
<div class="box header">Header</div>
<div class="box sidebar">Sidebar</div>
<div class="box sidebar2">Sidebar 2</div>
<div class="box content">Content
<div class="panelwrap">
<div class="panel">Panel A</div>
<div class="panel">Panel B</div>
<div class="panel tall-panel">Panel C</div>
<div class="panel">Panel D</div>
<div class="panel">Panel E</div>
<div class="panel">Panel F</div>
<div class="panel tall-panel">Panel G</div>
<div class="panel tall-panel">Panel H</div>
<div class="panel">Panel I</div>
<div class="panel">Panel J</div>
<div class="panel wide-panel">Panel K</div>
</div>
</div>
<div class="box footer">Footer</div>
</div>
I believe this may have been an issue with the Chrome browser at the time (not sure of version I used but I am now on Version 63.0.3239.84).
I've just tested the same identical code and the content area now matches the items within it. Previously when the display was > 647px wide the content area was much longer than the panels within.