I'm trying to make a border-bottom after each row using CSS grid with the content aligned to center. I can't get my head around it.
I want .line to fill the width of the entire .wrapper container.
How can I achieve that?
Here is the code:
* {
box-sizing: border-box;
}
.outer {
width: 80%;
margin: 0 auto;
}
.wrapper {
border: 2px solid #f76707;
border-radius: 5px;
background-color: #fff4e6;
display: grid;
grid-template-columns: repeat(3, auto) max-content;
justify-content: center;
}
.wrapper>div:not(.line) {
border: 2px solid #ffa94d;
border-radius: 5px;
background-color: #ffd8a8;
padding: 1em;
color: #d9480f;
}
.line {
grid-column-start: 1;
grid-column-end: 6;
height: 2px;
border-bottom: 1px solid black;
width: 100%;
}
<div class="outer">
<div class="wrapper">
<div>1111111</div>
<div>222</div>
<div>3333333333</div>
<div class="line"></div>
<div>4444</div>
<div>555555555</div>
<div>99999999999</div>
</div>
</div>
Instead of justify-content to center content you could add additional columns before and after your content, both with 1fr.
Then position the first div and the div after .line to the start at the second column.
Fiddle
* {
box-sizing: border-box;
}
.outer {
width: 80%;
margin: 0 auto;
}
.wrapper {
border: 2px solid #f76707;
border-radius: 5px;
background-color: #fff4e6;
display: grid;
grid-template-columns: 1fr repeat(3, auto) 1fr;
}
.wrapper>div:not(.line) {
border: 2px solid #ffa94d;
border-radius: 5px;
background-color: #ffd8a8;
padding: 1em;
color: #d9480f;
}
.wrapper > div:first-of-type,
.line + div {
grid-column: 2;
}
.line {
grid-column: 1 / -1;
height: 1px;
background: black;
}
<div class="outer">
<div class="wrapper">
<div>1111111</div>
<div>222</div>
<div>3333333333</div>
<div class="line"></div>
<div>4444</div>
<div>555555555</div>
<div>99999999999</div>
</div>
</div>
Here's a responsive solution that works with a variable number of items and without adding silly hard coded divs. Basically every item has a line below, the complicated part is determining the last row items which must not have a line. The example uses flex-box (and LESS) but that's not relevant here, it would also work with grid.
.grid {
display: flex;
}
.grid-item{
position: relative;
.one-col{
flex-basis: 100%/1;
&:nth-last-child(1){
&:after{ border-bottom: 0; }
}
}
.two-cols{
flex-basis: 100%/2;
&:nth-last-child(1),
&:nth-last-child(2):nth-child(odd){
&:after{ border-bottom: 0; }
}
}
.three-cols{
flex-basis: 100%/3;
&:nth-last-child(1),
&:nth-last-child(2):nth-child(3n+1),
&:nth-last-child(2):nth-child(3n+2),
&:nth-last-child(3):nth-child(3n+1){
&:after{ border-bottom: 0; }
}
}
.four-cols{
flex-basis: 100%/4;
&:nth-last-child(1),
&:nth-last-child(2):nth-child(4n+1),
&:nth-last-child(2):nth-child(4n+2),
&:nth-last-child(2):nth-child(4n+3),
&:nth-last-child(3):nth-child(4n+1),
&:nth-last-child(3):nth-child(4n+2),
&:nth-last-child(4):nth-child(4n+1){
&:after{ border-bottom: 0; }
}
}
#media screen and (max-width: #screen__sm) {
.grid-item .one-col;
}
#media screen and (min-width: #screen__sm) and (max-width: (#screen__md - 1)) {
.grid-item .two-cols;
}
#media screen and (min-width: #screen__md) and (max-width: (#screen__lg - 1)) {
.grid-item .three-cols;
}
#media screen and (min-width: #screen__lg) {
.grid-item .four-cols;
}
&:after{
content: "";
display: block;
position: absolute;
left: 0;
right: 0;
bottom: 0;
border-bottom: solid 1px black;
}
I had some success by using nth-of-type and switching the line to a different type (<span>).
I also added a first and sixth column for the line to span,
while the other items only occupy column 2-5.
* {
box-sizing: border-box;
}
.outer {
width: 80%;
margin: 0 auto;
}
.wrapper {
border: 2px solid #f76707;
border-radius: 5px;
background-color: #fff4e6;
display: grid;
grid-template-columns: 1fr repeat(3, auto) 1fr;
justify-content: center;
}
.wrapper>div {
border: 2px solid #ffa94d;
border-radius: 5px;
background-color: #ffd8a8;
padding: 1em;
color: #d9480f;
}
.wrapper>div:nth-of-type(3n+1) {
grid-column: 2;
}
.line {
grid-column: 1/6;
height: 2px;
border-bottom: 1px solid black;
}
<div class="outer">
<div class="wrapper">
<div>1111111</div>
<div>222</div>
<div>3333333333</div>
<span class="line"></span>
<div>4444</div>
<div>555555555</div>
<div>6666666</div>
<span class="line"></span>
<div>77777</div>
<div>888888888</div>
<div>99</div>
</div>
</div>
Related
I have two inputs on form in one row. First one should be stretching on form resize, second is of fixed width. But when form is narrowed to a particular breakpont, second input should wrap to second line and stretch as well as first one.
Is it possible to achieve using CSS?
Tried using grid, but it won't wrap at all.
When using flexbox the result is better, but still have to set flex-grow for second input and it's width is not fixed, while inputs are in one row
.box {
background: grey;
padding: 20px 20px 20px 20px;
}
.wrapper {
display: grid;
grid-column-gap: 6px;
grid-row-gap: 6px;
grid-template-columns: minmax(320px, 1fr) 200px;
}
.flexWrapper {
display: flex;
flex-wrap: wrap;
}
.flex1 {
flex-basis: 320px;
flex-grow: 10;
flex-shrink: 0;
}
.flex2 {
flex-basis: 200px;
flex-shrink: 0;
flex-grow: 1;
}
<div class="wrapper">
<div class="box">One</div>
<div class="box">Two</div>
</div>
<div class="flexWrapper">
<div class="flex1 box">One</div>
<div class="flex2 box">Two</div>
</div>
https://codepen.io/C4off/pen/WNKjJaK
The easiest way to do this is to use a media query. At 600px I've reset the wrapper to be display: block with the children at 100% width which forces them to stack on top of each other. I've set the width of flex2 to 200px to fix it at that.
.box {
background: grey;
padding: 20px 20px 20px 20px;
}
.flexWrapper {
display: flex;
padding-top: 12px;
column-gap: 6px;
row-gap:6px;
}
.flex1 {
flex: 1;
}
.flex2 {
width: 200px;
}
#media only screen and (max-width: 600px) {
.flexWrapper {
display: block;
}
.flex1, .flex2 {
width: 100%;
}
}
<div class="container">
<div class="flexWrapper">
<div class="flex1 box">One</div>
<div class="flex2 box">Two</div>
</div>
</div>
Using flexbox only and the min-width proprty. Note .flex2 will overflow at container widths less than 200px
.container {
width: 60%;
outline: 1px solid red;
}
.box {
background: grey;
padding: 20px 20px 20px 20px;
}
.flex-wrapper {
display: flex;
padding-top: 12px;
column-gap: 6px;
row-gap:6px;
flex-wrap: wrap;
}
.flex1 {
flex: 2 0;
}
.flex2 {
min-width: 200px;
flex-grow: 1;
}
<div class="container">
<div class="flex-wrapper">
<div class="flex1 box">One</div>
<div class="flex2 box">Two</div>
</div>
</div>
The final way this can be done is using container queries which are quite well supported now. The max size is applied to the container and not the screen as the example below
* {
box-sizing:border-box;
}
.container {
container-type: inline-size;
container-name: my-container;
width: 60%;
}
.box {
background: grey;
padding: 20px 20px 20px 20px;
}
.flex-wrapper {
display: flex;
padding-top: 12px;
column-gap: 6px;
row-gap:6px;
}
.flex1 {
flex: 1;
}
.flex2 {
width: 200px;
}
#container my-container (max-width: 600px) {
.container {outline: 1px solid red;}
.flex-wrapper {
display: block;
}
.flex1, .flex2 {
width: 100%;
}
}
<div class="container">
<div class="flex-wrapper">
<div class="flex1 box">One</div>
<div class="flex2 box">Two</div>
</div>
</div>
I created blazor calendar component which consists of two parts Header and weekview components. The component flex lines go beyond the component itself and I could not figure out Why? I have attached a screenshot of the issue.
Header (Calendar Component) code
<div class="maincontainer">
<div class="viewtitle">Augest 2022</div>
<div class="lbuttons">
<button class="button"><</button>
<button class="button">></button>
<button class="button">Today</button>
</div>
<div class="mbuttons">
<label class="datelabel">Monady, Augest 21, 2022</label>
<input class="dateinput" type="datetime-local" id="schedule-time"
name="schedule-time" value="2022-06-12T19:30"
min="2022-06-07T00:00" max="2022-06-14T00:00">
<input class="button" type="button" id="btnsubmit" value="Submit">
</div>
<div class="rbuttons">
<button class="button" #onclick="#(() => DayView_Click())" #onclick:stopPropagation="true">Day</button>
<button class="button" #onclick="#(() => WeekView_Click())" #onclick:stopPropagation="true">Week</button>
<button class="button" #onclick="#(() => MonthView_Click())" #onclick:stopPropagation="true">Month</button>
</div>
</div>
#switch (CurrentView)
{
case CalendarViewOption.MonthView:
<MonthViewComponent></MonthViewComponent>
break;
case CalendarViewOption.DayView:
<DayViewComponent></DayViewComponent>
break;
case CalendarViewOption.WeekView:
<WeekViewComponent></WeekViewComponent>
break;
}
CSS
body {
margin: 0;
padding: 0;
}
.maincontainer {
background: #E7EAF6;
display: grid;
grid-template-columns: minmax(100px, 1fr) auto minmax(100px, 1fr);
grid-template-rows: auto
}
.viewtitle {
grid-column: 1/4;
grid-row: 1;
justify-self: center;
padding: 5px 5px 5px 5px;
color: darkblue;
font-weight: bold;
font-size: 16px;
}
.lbuttons {
grid-column: 1/2;
grid-row: 2;
justify-self: start;
}
.mbuttons {
grid-column: 2/3;
grid-row: 2;
justify-self: center;
}
.rbuttons {
grid-column: 3/4;
grid-row: 2;
justify-self: end;
}
.button {
background-color: black;
color: white;
border: 2px solid #555555;
padding: 3px;
margin: 0;
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);
border-radius: 5px;
cursor: pointer;
}
.button:hover {
background-color: white;
color: black;
}
.datelabel {
color: black;
font-weight: bold;
}
.dateinput {
padding: 3px 3px;
margin: 2px 0;
border: 1px solid rgb(130, 128, 128);
border-radius: 4px;
box-sizing: border-box;
cursor: pointer;
}
WeekView
<div class="calendar-container">
<div class="header">
<ul class="weekdays">
<li>Sun</li>
<li>Mon</li>
<li>Tue</li>
<li>Wed</li>
<li>Thu</li>
<li>Fri</li>
<li>Sat</li>
</ul>
<ul class="daynumbers">
<li>20</li>
<li>21</li>
<li>22</li>
<li>23</li>
<li>24</li>
<li>25</li>
<li>26</li>
</ul>
</div>
<div class="timeslots-container">
<ul class="timeslots">
<li>8<sup>am</sup></li>
<li>9<sup>am</sup></li>
<li>10<sup>am</sup></li>
<li>11<sup>am</sup></li>
<li>12<sup>pm</sup></li>
<li>4<sup>pm</sup></li>
<li>5<sup>pm</sup></li>
<li>6<sup>pm</sup></li>
<li>7<sup>pm</sup></li>
<li>8<sup>pm</sup></li>
<li>9<sup>pm</sup></li>
<li>10<sup>pm</sup></li>
</ul>
</div>
<div class="event-container">
<div class="slot slot-1">
<div class="event-staus"></div>
<span>Event A</span>
</div>
<div class="slot slot-2" style="height: 60px; grid-row: 1; grid-column: 1;">
<div class="event-staus"></div>
<span>Event A</span>
</div>
</div>
CSS
body {
margin: 0;
padding: 0;
}
li {
list-style: none;
}
ul {
padding: 0;
margin: 0;
}
.calendar-container {
display: grid;
grid-template-columns: 50px auto;
grid-template-rows: auto;
gap: 1px 1px;
grid-template-areas:
". header"
"timeslots-container main";
background: #325288;
}
.weekdays,
.daynumbers {
display: grid;
grid-template-columns: repeat(7, 1fr);
}
.daynumbers {
min-height: 1em;
}
.weekdays {
background: #19456B;
color: white
}
.header {
background-color: gainsboro;
grid-area: header;
}
.timeslots-container {
background-color: lightgray;
grid-area: timeslots-container;
align-items: center;
}
.timeslots {
display: flex;
flex-direction: column;
align-items: center;
}
.timeslots li {
min-height: 60px;
}
.timeslots li::after {
content: "";
position: absolute;
left: 10px;
width: 100%;
height: 1px;
background: lightgray;
z-index: 1;
}
.event-container {
display: grid;
grid-template-columns: repeat(7, auto);
grid-template-rows: repeat(48, auto);
grid-area: main;
position: relative;
}
.slot {
position: absolute;
background: darkcyan;
border-radius: 5px;
z-index: 5;
color: white;
font-size: 12px;
}
.slot-1 {
height: 30px;
grid-row: 106;
grid-column: 3;
}
Screenshot
Your issue is with:
.timeslots li::after {
content: "";
position: absolute;
left: 10px;
width: 100%;
height: 1px;
background: lightgray;
z-index: 1;
}
setting it to left: 10px is a mistake and why its causing your code to look like this, because technically it is taking left: 10px on the entire page. You need to set it so that it does not overlap the li element by setting it to relative so it stays inside.
So I have done a few changes to your css.
First I added this css:
.calendar-container {
overflow: hidden;
}
Then I set the li elements to relative:
.timeslots li {
position: relative;
}
then I adjusted your li::after css:
.timeslots li::after {
left: 0px;
width: 3000px;
}
this should solve your problem since the ::after now stays inside the li and not the entire page, and the overflow: hidden hides any overflow that causes side-scroll.
I have a question, I have this page right here:
And I have all boxes set up as a grid. But I want all black borders touching each other. So that all space is fully filled up with the grid only. The whole page needs to be the grid. See the code below:
DEMO:
* {
margin: 0 auto;
}
body {
width: 100%;
height: 100%;
min-width: 100%;
overflow: hidden;
}
.grid-container {
display: grid;
grid-template-columns: 0.8fr 2fr 0.8fr;
grid-template-rows: 1fr 1fr 1fr 1fr;
gap: 0px 0px;
grid-template-areas:
"logo nav time"
"computer-menu terminal computer-anim"
"missions terminal notebook"
"missions terminal notebook";
}
.missions {
grid-area: missions;
border: 3px solid black;
}
.terminal {
grid-area: terminal;
border: 3px solid black;
}
.notebook {
grid-area: notebook;
border: 3px solid black;
}
.computer-menu {
grid-area: computer-menu;
border: 3px solid black;
}
.logo {
grid-area: logo;
border: 3px solid black;
}
.nav {
grid-area: nav;
border: 3px solid black;
}
.time {
grid-area: time;
border: 3px solid black;
}
.computer-anim {
grid-area: computer-anim;
border: 3px solid black;
}
<div class="grid-container">
<div class="missions"><h1>MISSIONS</h1></div>
<div class="terminal"><h1>TERMINAL</h1></div>
<div class="notebook"><h1>NOTEBOOK</h1></div>
<div class="computer-menu"><h1>COMPUTER-MENU</h1></div>
<div class="logo"><h1>LOGO</h1></div>
<div class="nav"><h1>NAV</h1></div>
<div class="time"><h1>TIME</h1></div>
<div class="computer-anim"><h1>COMPUTER-ANIM</h1></div>
</div>
The problem is this rule in your code:
* {
margin: 0 auto;
}
The auto margins are centering the grid items within the columns.
Remove that rule, or modify the selector, and you're done.
/* * {
margin: 0 auto;
} */
body {
width: 100%;
height: 100%;
min-width: 100%;
overflow: hidden;
}
.grid-container {
display: grid;
grid-template-columns: 0.8fr 2fr 0.8fr;
grid-template-rows: 1fr 1fr 1fr 1fr;
gap: 0px 0px;
grid-template-areas:
"logo nav time"
"computer-menu terminal computer-anim"
"missions terminal notebook"
"missions terminal notebook";
}
.missions {
grid-area: missions;
border: 3px solid black;
}
.terminal {
grid-area: terminal;
border: 3px solid black;
}
.notebook {
grid-area: notebook;
border: 3px solid black;
}
.computer-menu {
grid-area: computer-menu;
border: 3px solid black;
}
.logo {
grid-area: logo;
border: 3px solid black;
}
.nav {
grid-area: nav;
border: 3px solid black;
}
.time {
grid-area: time;
border: 3px solid black;
}
.computer-anim {
grid-area: computer-anim;
border: 3px solid black;
}
<div class="grid-container">
<div class="missions">
<h1>MISSIONS</h1>
</div>
<div class="terminal">
<h1>TERMINAL</h1>
</div>
<div class="notebook">
<h1>NOTEBOOK</h1>
</div>
<div class="computer-menu">
<h1>COMPUTER-MENU</h1>
</div>
<div class="logo">
<h1>LOGO</h1>
</div>
<div class="nav">
<h1>NAV</h1>
</div>
<div class="time">
<h1>TIME</h1>
</div>
<div class="computer-anim">
<h1>COMPUTER-ANIM</h1>
</div>
</div>
Did you try to set CSS:
/* ADDED */
.grid-container > div {
width:calc(100% - 6px);
}
DEMO
* {
margin: 0 auto;
}
body {
width: 100%;
height: 100%;
min-width: 100%;
overflow: hidden;
}
.grid-container {
display: grid;
grid-template-columns: 0.8fr 2fr 0.8fr;
grid-template-rows: 1fr 1fr 1fr 1fr;
gap: 0px 0px;
grid-template-areas:
"logo nav time"
"computer-menu terminal computer-anim"
"missions terminal notebook"
"missions terminal notebook";
}
.missions {
grid-area: missions;
border: 3px solid black;
}
.terminal {
grid-area: terminal;
border: 3px solid black;
}
.notebook {
grid-area: notebook;
border: 3px solid black;
}
.computer-menu {
grid-area: computer-menu;
border: 3px solid black;
}
.logo {
grid-area: logo;
border: 3px solid black;
}
.nav {
grid-area: nav;
border: 3px solid black;
}
.time {
grid-area: time;
border: 3px solid black;
}
.computer-anim {
grid-area: computer-anim;
border: 3px solid black;
}
/* ADDED */
.grid-container > div {
width:calc(100% - 6px);
}
<div class="grid-container">
<div class="missions"><h1>MISSIONS</h1></div>
<div class="terminal"><h1>TERMINAL</h1></div>
<div class="notebook"><h1>NOTEBOOK</h1></div>
<div class="computer-menu"><h1>COMPUTER-MENU</h1></div>
<div class="logo"><h1>LOGO</h1></div>
<div class="nav"><h1>NAV</h1></div>
<div class="time"><h1>TIME</h1></div>
<div class="computer-anim"><h1>COMPUTER-ANIM</h1></div>
</div>
I'm losing my mind here over something that seems to be very simple, but after playing around for several hours I thought it was time to ask for some help.
What I need is a container (see pink colour) that is centered on the page and is 70% of the page it's width. Then there should be two Divs inside of the container.
One of the left for text, and one on the right for a square image that should stay at a fixed size (Let's say 200x200px - I mean, it looks so weird to end up having a 50x50px avatar next to a block of text after scaling your browser down). It's OK if the right Div shifts below the first Div on mobile devices.
I haven't been able to find a useful answer on here, but I've been playing around with the code below (which does the opposite - small (image) block on the left) but for some reason I just can't get it to work.
.wrapper {
border: 2px solid #000;
overflow: hidden;
}
.wrapper div {
min-height: 200px;
padding: 10px;
}
#one {
background-color: gray;
float: left;
margin-right: 20px;
width: 140px;
border-right: 2px solid #000;
}
#two {
background-color: white;
overflow: hidden;
margin: 10px;
border: 2px dashed #ccc;
min-height: 170px;
}
#media screen and (max-width: 400px) {
#one {
float: none;
margin-right: 0;
width: auto;
border: 0;
border-bottom: 2px solid #000;
}
}
<div class="wrapper">
<div id="one">one</div>
<div id="two">two</div>
</div>
Any help would be highly appreciated!
Image with what I mean
You could use flexbox
.wrapper {
display: flex;
width: 70%;
max-width: 1000px; /* added this to limit its width on very wide screens */
margin: 0 auto;
border: 2px solid #000;
overflow: hidden;
}
.wrapper div {
min-height: 200px;
padding: 10px;
}
#one {
flex: 1;
background-color: gray;
border-right: 2px solid #000;
}
#two {
margin: 10px;
border: 2px dashed #ccc;
width: 200px;
}
#media screen and (max-width: 600px) {
.wrapper {
flex-direction: column;
}
#one {
border-right: none;
}
#two {
width: auto;
}
}
<div class="wrapper">
<div id="one">one</div>
<div id="two">two</div>
</div>
Another option for wide screens would be an additional media query
.wrapper {
display: flex;
width: 70%;
margin: 0 auto;
border: 2px solid #000;
overflow: hidden;
}
.wrapper div {
min-height: 200px;
padding: 10px;
}
#one {
flex: 1;
background-color: gray;
border-right: 2px solid #000;
}
#two {
margin: 10px;
border: 2px dashed #ccc;
width: 200px;
}
#media screen and (max-width: 600px) {
.wrapper {
flex-direction: column;
}
#one {
border-right: none;
}
#two {
width: auto;
}
}
#media screen and (min-width: 1200px) {
.wrapper {
width: 50%;
}
}
<div class="wrapper">
<div id="one">one</div>
<div id="two">two</div>
</div>
My content layout consists of three sections: header, content and footer. For small devices I want to keep this order, on desktop I would like to move header and footer to the sidebar.
Implemented using floats: http://codepen.io/anon/pen/jqrZby
Markup
<div class="page">
<div class="top"></div>
<div class="content"></div>
<div class="bottom"></div>
</div>
CSS
.page {
border: 2px solid black;
padding: 1em;
}
.page:after {
content: "";
display: block;
clear: both;
}
.page > * {
margin-bottom: 1em;
}
.top {
border: 2px solid red;
height: 100px;
}
.content {
border: 2px solid blue;
height: 400px;
}
.bottom {
border: 2px solid green;
height: 200px;
}
#media screen and (min-width: 800px) {
.content {
width: 66%;
float: left;
}
.top, .bottom {
width: 33%;
float: right;
}
}
I'm trying to find a solution using flexbox with a fixed spacing between content and sidebar. Anybody got an idea if this is possible?
Without changing the stucture and using flexbox you need to use flex-direction:column.
First we build it "mobile first" because it follows the actual order of the div structure we have already.
Then, at the appropriate media query we need to make the container wrap...often this will require a fixed height (be it viewport or px value)...then we can re-order the elements (using, ahem, order) and impose our required widths.
Codepen Demo
* {
box-sizing: border-box;
}
.page {
border: 2px solid black;
display: flex;
flex-direction: column;
height: 400px;
padding: 1em;
}
.top {
border: 2px solid red;
height: 100px;
width: 100%;
order: 1;
margin-bottom: 1em;
}
.content {
border: 2px solid blue;
height: 400px;
order: 2;
}
.bottom {
border: 2px solid green;
height: 200px;
order: 3;
margin-top: 1em;
}
#media screen and (max-width: 800px) {
.page {
flex-wrap: wrap;
justify-content: space-between;
}
.top {
order: 2;
}
.top,
.bottom {
width: 33%;
}
.content {
order: 1;
flex: 0 0 100%;
width: 66%;
margin-right: 1em;
}
}
<div class="page">
<div class="top">top</div>
<div class="content">content</div>
<div class="bottom">bottom</div>
</div>