Styling DIV's using CSS techniques - html

I am trying to create a table that looks like this
<div class="style" id="1"></div>
<div class="style" id="2"></div>
<div class="style" id="3"></div>
<div class="style" id="4"></div>
<div class="style" id="5"></div>
<div class="style" id="6"></div>
<div class="style" id="7"></div>
<div class="style" id="8"></div>
<div class="style" id="9"></div>
I am struggling with the css part

For positioning items like show in your image, you can use display: grid;. I made the grid to have 4 columns and 3 rows.
Lastly, one item is bigger than the others. You can change the space the item uses by adjusting the grid-column and grid-row:
* {
margin: 0;
padding: 0;
}
body {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3,1fr);
max-width: 400px;
}
div {
min-width: 100px;
min-height: 100px;
border: 1.5px solid black;
}
#one {
grid-column: 1 / 3;
grid-row: 1 / 3;
}
#one,
#three,
#four,
#six,
#eight {
background-color: red;
}
#two,
#five,
#seven,
#nine {
background-color: blue;
}
<div id="one"></div>
<div id="two"></div>
<div id="three"></div>
<div id="four"></div>
<div id="five"></div>
<div id="six"></div>
<div id="seven"></div>
<div id="eight"></div>
<div id="nine"></div>

Not using the html you gave but this is a approach with display: flex . I did not optimize the styling so you can see what is happening.
* {
box-sizing: border-box;
}
.row-full {
display: flex;
flex-wrap: wrap;
width: 240px;
}
.row-half {
display: flex;
flex-wrap: wrap;
width: 120px;
}
.block-big {
width: 120px;
height: 120px;
border: 1px solid black;
}
.block {
width: 60px;
height: 60px;
border: 1px solid black;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
<div class="row-full">
<div class="block-big red"></div>
<div class="row-half">
<div class="block blue"></div>
<div class="block red"></div>
<div class="block red"></div>
<div class="block blue"></div>
</div>
</div>
<div class="row-full">
<div class="block red"></div>
<div class="block blue"></div>
<div class="block red"></div>
<div class="block blue"></div>
</div>

I would use css grid for this. css grid makes it able for you to make a more complex css layout. I made this quick example that shows how you can use it.
.grid{
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(3, 1fr);
width: 100vw;
height: 100vh;
background-color: red;
}
.style1{
grid-column: 1/3;
grid-row: 1/3;
background-color: blue;
}
.style2{
grid-column: 3/4;
grid-row: 1/2;
background-color: green;
}
.style3{
grid-column: 3/4;
grid-row: 2/3;
background-color: yellow;
}
.style4{
grid-column: 4/5;
grid-row: 1/3;
background-color: pink;
}
.style5{
grid-column: 1/4;
grid-row: 3/4;
background-color: orange;
}
.style6{
grid-column: 4/5;
grid-row: 3/4;
background-color: purple;
}
<div class="grid">
<div class="style1" id="1"></div>
<div class="style2" id="2"></div>
<div class="style3" id="3"></div>
<div class="style4" id="4"></div>
<div class="style5" id="5"></div>
<div class="style6" id="6"></div>
</div>

This is another answer :
html, body{
font-family: sans-serif;
}
#container{
display:grid;
grid-template-columns: repeat(4, 100px);
grid-template-rows: repeat(4, 100px);
}
#container div{
border:1px solid #000000;
}
#div1{
background-color: red;
grid-column-start: 1;
grid-column-end: 3;
grid-row-start: 1;
grid-row-end: 3;
}
#div2{
background-color: blue;
}
#div3{
background-color: red;
}
#div4{
background-color: red;
}
#div5{
background-color: blue;
}
#div6{
background-color: red;
}
#div7{
background-color: blue;
}
#div8{
background-color: red;
}
#div9{
background-color: blue;
}
<div id="container">
<div id="div1"></div>
<div id="div2"></div>
<div id="div3"></div>
<div id="div4"></div>
<div id="div5"></div>
<div id="div6"></div>
<div id="div7"></div>
<div id="div8"></div>
<div id="div9"></div>

Related

How to force a flex item to nowrap when parent has flex-direction: column

How can I force .item2 to be placed in-line with .item1 by only changing CSS of .item2? (I know that you would usually just change .container to flex-direction: row)
.container {
display: flex;
flex-direction: column;
background: blue;
padding: 1rem;
}
.item1 {
background: yellow;
}
.item2 {
background: red;
}
<div class="container">
<div class="item1">Item 1</div>
<div class="item2">Item 2</div>
</div>
.container {
display: grid;
grid-template-columns: repeat(2, auto);
background: blue;
padding: 1rem;
gap: 0.25em;
}
/* here the class to use for a full row */
.itemNext {
grid-column: 1 / span 2;
background: hotpink;
}
.item1 {
background: yellow;
}
.item2 {
background: red;
}
<div class="container">
<div class="item1">Item 1</div>
<div class="item2">Item 2</div>
<div class="itemNext">next Item </div>
<div class="itemNext">next Item </div>
<div class="item1 itemNext">next Item </div>
<div class="item2 itemNext">next Item </div>
<div class="item1">Item 1</div>
<div class="item2">Item 2</div>
<div class="itemNext">next Item </div>
</div>

Make an element sticky when the parent scrolls

I'm trying to make an element stick to the bottom of the parent div even when there is nothing above it.
As you can see in these two pictures, the element I'm talking about is the div that contains the textarea.
When there are enough messages in the div above the textarea, it sticks to the bottom of the page just fine, however when there aren't that many elements, it doesn't, even though I've set bottom: 0px;.
Here's a part of the code:
* {
padding: 0px;
margin: 0px;
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: 0.8fr 4fr 15fr;
grid-template-rows: 50px calc(100vh - 65px);
overflow-y: hidden;
}
.navbar {
grid-column: 1/4;
background: #223;
}
.main-panel {
display: none;
grid-row: 2/3;
background: #223;
}
.buttons {
grid-column: 1/2;
grid-row: 2/3;
background: #456;
}
.screen {
grid-column: 3/4;
grid-row: 2/3;
background: #223;
}
.left-panel {
grid-column: 2/3;
grid-row: 2/3;
background: #243;
}
/*css for the chat box*/
.messages {
padding: 5px;
padding-right: 35px;
}
.message {
border: 2px solid #dedede;
background-color: #f1f1f1;
border-radius: 5px;
padding: 10px;
margin: 10px 0;
}
.sender {
font-size: 0.8em;
}
.message-mine {
border: 2px solid #dedede;
background-color: #321;
border-radius: 5px;
padding: 10px;
margin: 10px 0;
}
.my-messages {
padding: 5px;
padding-left: 35px;
}
.chat-box {
height: 100%;
overflow-y: scroll;
}
.chat-sending-area {
display: grid;
grid-template-rows: 100%;
grid-template-columns: 4fr 1fr;
border: 5px solid black;
background: gray;
position: sticky;
margin-bottom: 0px;
bottom: 0px;
z-index: 1000;
width: calc(100% - 10px);
height: 6%;
}
.chat-history {
}
.text-area {
grid-row:1/2;
grid-column: 1/2;
width: 95%;
height: calc(100% - 3px);
resize: none;
}
.send-button {
grid-row:1/2;
grid-column: 2/3;
}
.send-message-button {
width: 85%;
height: calc(100% - 6px);
border: 3px outset pink;
background: green;
}
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="wrapper">
<div class="navbar">
STUFF HERE.
</div>
<div class="main-panel">
STUFF HERE.
</div>
<div class="buttons">
STUFF HERE.
</div>
<div class="screen">
STUFF HERE.
</div>
<div class="left-panel">
<div class="chat-box">
<div class="chat-history">
<div class="my-messages">
<div class="message-mine" id="message1">
<span class="sender">
me:
</span><br>
<span class="content">
testing...
</span>
</div>
</div>
<div class="my-messages">
<div class="message-mine" id="message1">
<span class="sender">
me:
</span><br>
<span class="content">
testing...
</span>
</div>
</div>
<div class="messages">
<!-- -->
<div class="message" id="message1">
<span class="sender">
me:
</span><br>
<span class="content">
testing...
</span>
</div>
</div>
<div class="messages">
<!-- -->
<div class="message" id="message1">
<span class="sender">
me:
</span><br>
<span class="content">
testing...
</span>
</div>
</div>
</div>
<div class="chat-sending-area">
<div class="send-button">
<img class="send-message-button" src="chat-dots.svg">
</div>
<div class="text-box">
<textarea class="text-area">Write your message here...</textarea>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
I would like the (chat-sending-area) div to stick to the bottom of the (chat-box) div no matter what.
Any help would be much appreciated.
You can add display: flex and flex-direction: column to .chat-box then add margin-top: auto to .chat-sending-area to solve your problem.
* {
padding: 0px;
margin: 0px;
}
.wrapper {
display: grid;
grid-gap: 10px;
grid-template-columns: 0.8fr 4fr 15fr;
grid-template-rows: 50px calc(100vh - 65px);
overflow-y: hidden;
}
.navbar {
grid-column: 1/4;
background: #223;
}
.main-panel {
display: none;
grid-row: 2/3;
background: #223;
}
.screen {
grid-column: 3/4;
grid-row: 2/3;
background: #223;
}
.left-panel {
grid-column: 2/3;
grid-row: 2/3;
background: #243;
}
/*css for the chat box*/
.messages {
padding: 5px;
padding-right: 35px;
}
.message {
border: 2px solid #dedede;
background-color: #f1f1f1;
border-radius: 5px;
padding: 10px;
margin: 10px 0;
}
.sender {
font-size: 0.8em;
}
.message-mine {
border: 2px solid #dedede;
background-color: #321;
border-radius: 5px;
padding: 10px;
margin: 10px 0;
}
.my-messages {
padding: 5px;
padding-left: 35px;
}
.chat-box {
display: flex;
flex-direction: column;
height: 100%;
overflow-y: scroll;
}
.chat-sending-area {
display: grid;
grid-template-rows: 100%;
grid-template-columns: 4fr 1fr;
border: 5px solid black;
background: gray;
position: sticky;
margin-bottom: 0px;
margin-top: auto;
bottom: 0px;
z-index: 1000;
width: calc(100% - 10px);
height: 6%;
}
.chat-history {}
.text-area {
grid-row: 1/2;
grid-column: 1/2;
width: 95%;
height: calc(100% - 3px);
resize: none;
}
.send-button {
grid-row: 1/2;
grid-column: 2/3;
}
.send-message-button {
width: 85%;
height: calc(100% - 6px);
border: 3px outset pink;
background: green;
}
<!DOCTYPE html>
<html>
<head>
<title></title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="wrapper">
<div class="navbar">
STUFF HERE.
</div>
<div class="main-panel">
STUFF HERE.
</div>
<div class="buttons">
STUFF HERE.
</div>
<div class="screen">
STUFF HERE.
</div>
<div class="left-panel">
<div class="chat-box">
<div class="chat-history">
<div class="my-messages">
<div class="message-mine" id="message1">
<span class="sender">
me:
</span><br>
<span class="content">
testing...
</span>
</div>
</div>
<div class="my-messages">
<div class="message-mine" id="message1">
<span class="sender">
me:
</span><br>
<span class="content">
testing...
</span>
</div>
</div>
<div class="messages">
<!-- -->
<div class="message" id="message1">
<span class="sender">
me:
</span><br>
<span class="content">
testing...
</span>
</div>
</div>
<div class="messages">
<!-- -->
<div class="message" id="message1">
<span class="sender">
me:
</span><br>
<span class="content">
testing...
</span>
</div>
</div>
</div>
<div class="chat-sending-area">
<div class="send-button">
<img class="send-message-button" src="chat-dots.svg">
</div>
<div class="text-box">
<textarea class="text-area">Write your message here...</textarea>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

How to display 2 columns per row using flexbox

I'm trying to display 2 columns every row but I can't seem to get it right at the moment.
What i'm trying to replicate is this:
but i'm not sure on how to handle this with using flexbox
.flex {
display: flex;
flex-direction: row;
flex-basis: 100%;
flex: 1;
}
.box {
padding: 20px;
border: 1px solid black;
width: 100px;
height: 100px;
margin: 10px;
}
.red {
background-color: red;
}
.yellow {
background-color: yellow;
}
.blue {
background-color: blue;
}
.green {
background-color: green;
}
<div class="flex">
<div class="box green">positive 1</div>
<div class="box yellow">positive 2</div>
<div class="box blue">positive 3</div>
<div class="box red">negative 1</div>
</div>
https://jsfiddle.net/1a9qLx5w/
The best way to achieve this layout would be with Grid CSS:
.flex {
display: grid;
grid-auto-flow: column;
grid-gap: 20px;
grid-template-rows: 100px 100px;
grid-template-columns: 100px 100px;
padding: 10px;
}
.box {
padding: 20px;
border: 1px solid black;
}
.red {
background-color: red;
}
.yellow {
background-color: yellow;
}
.blue {
background-color: blue;
}
.green {
background-color: green;
}
* {
box-sizing: border-box;
}
<div class="flex">
<div class="box green">positive 1</div>
<div class="box yellow">positive 2</div>
<div class="box blue">positive 3</div>
<div class="box red">negative 1</div>
</div>
But since you're asking for a flexbox solution, here you go:
.flex {
display: flex;
flex-direction: column;
flex-wrap: wrap;
height: 240px;
align-content: flex-start;
}
.box {
flex: 0 0 100px;
width: 100px;
padding: 20px;
border: 1px solid black;
margin: 10px;
}
.red {
background-color: red;
}
.yellow {
background-color: yellow;
}
.blue {
background-color: blue;
}
.green {
background-color: green;
}
* {
box-sizing: border-box;
}
<div class="flex">
<div class="box green">positive 1</div>
<div class="box yellow">positive 2</div>
<div class="box blue">positive 3</div>
<div class="box red">negative 1</div>
</div>
Working demo :
.flex {
display: flex;
flex-direction: row;
flex-basis: 100%;
flex: 1;
}
.box {
padding: 20px;
border: 1px solid black;
width: 100px;
height: 100px;
margin: 10px;
}
.red {
background-color: red;
}
.yellow {
background-color: yellow;
}
.blue {
background-color: blue;
}
.green {
background-color: green;
}
.row {
display: flex;
flex-direction: row;
}
<div class="row">
<div class="box green">positive 1</div>
<div class="box yellow">positive 2</div>
</div>
<div class="row">
<div class="box blue">positive 3</div>
<div class="box red">negative 1</div>
</div>
I just copied your example:
.row{
display: flex;
flex-direction: row;
justify-content: center;
}
.green{
padding: 15px;
border: solid 1px green;
}
.red{
padding: 15px;
border: solid 1px red;
}
.col{
margin-right: 15px;
}
<div class="row">
<div class="col">
<p class="green">Positive 1</p>
<p class="green">Positive 2</p>
</div>
<div class="col">
<p class="red">No Thanks</p>
</div>
</div>

flexbox wrapping with items of varying size

Can I achieve this layout with flexbox with the below document structure?
I want the big <img> on the left with two smaller images on the right and wrapping.
This is what I did, with display: flex on gallery-container and flex-wrap.
.container {
height: 100%;
}
.container .gallery-container {
background-color: #f6f6f6;
display: flex;
flex-wrap: wrap;
width: 300px;
align-items: flex-start;
}
.container .gallery-container .gallery-big-image {
display: block;
width: 200px;
height: 200px;
background: lavender;
}
.container .gallery-container .gallery-small-img {
display: block;
width: 100px;
height: 100px;
background-color: purple;
}
<div class="container">
<div class="gallery-container">
<div class="gallery-big-image">big</div>
<div class="gallery-small-img">small</div>
<div class="gallery-small-img">small</div>
<div class="gallery-small-img">small</div>
<div class="gallery-small-img">small</div>
<div class="gallery-small-img">small</div>
</div>
</div>
(codepen)
The layout is clunky and inefficient with flexbox, for reasons explained here: CSS-only masonry layout
However, the layout is relatively simple and easy with CSS Grid.
No changes to HTML.
.gallery-container {
display: grid;
grid-template-columns: repeat(auto-fill, 100px);
grid-auto-rows: 100px;
width: 300px;
background-color: #f6f6f6;
}
.gallery-big-image {
grid-column: span 2;
grid-row: span 2;
background: lavender;
}
.gallery-small-img {
background-color: purple;
color: white;
}
<div class="container">
<div class="gallery-container">
<div class="gallery-big-image">big</div>
<div class="gallery-small-img">small 1</div>
<div class="gallery-small-img">small 2</div>
<div class="gallery-small-img">small 3</div>
<div class="gallery-small-img">small 4</div>
<div class="gallery-small-img">small 5</div>
<div class="gallery-small-img">small 6 (continues wrapping)</div>
<div class="gallery-small-img">small 7 (continues wrapping)</div>
</div>
</div>
How about using grid layout instead?
.container {
height: 100%;
}
.gallery-container {
background-color: #f6f6f6;
width: 300px;
height: 100px;
display: grid;
grid-template-rows: repeat(3, 1fr);
grid-template-columns: repeat(3, 1fr);
}
.gallery-img {
background: purple;
width: 100px;
height: 100px;
}
.gallery-img-large {
background: lavender;
width: 200px;
height: 200px;
grid-column-start: 0;
grid-column-end: span 2;
grid-row-start: 0;
grid-row-end: span 2;
}
<div class="container">
<div class="gallery-container">
<div class="gallery-img-large">big</div>
<div class="gallery-img">small</div>
<div class="gallery-img">small</div>
<div class="gallery-img">small</div>
<div class="gallery-img">small</div>
<div class="gallery-img">small</div>
</div>
</div>

Can you make a nested column flexbox as small but as wide as possible

In the code snippet below, I have two flexbox containers: A primary one, wrapped row, and a second one, nested in the first one, that has a column direction.
I'd like to have the red, green & blue containers displayed like this:
--------------
red | black
--------------
green | gray
--------------
blue |
--------------
instead of simply stacked like this:
--------
red
--------
green
--------
blue
--------
black
--------
gray
--------
Is this a possible behaviour? Thanks!
.flexbox {
display: flex;
flex-wrap: wrap;
}
.flexbox-element {
flex: 1 1 auto;
}
.flexbox-column {
flex-direction: column;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
.green {
background-color: green;
}
.yellow {
background-color: yellow;
}
.orange {
background-color: orange;
}
.violet {
background-color: violet;
}
.black {
background-color: black;
}
.gray {
background-color: gray;
}
.flexbox-element {
width: 200px;
min-height: 200px;
}
<div class="flexbox" style="flex: 1; width: 500px">
<div class="flexbox flexbox-element flexbox-column" style="flex: 1 1 100%">
<div class="flexbox-element red"></div>
<div class="flexbox-element green"></div>
<div class="flexbox-element blue"></div>
<div class="flexbox-element black"></div>
<div class="flexbox-element gray"></div>
</div>
<div class="flexbox-element yellow"></div>
<div class="flexbox-element orange"></div>
<div class="flexbox-element violet"></div>
</div>
If you remove the flex-direction: column and the flex: 1 to the first group, you should get what you want.
.flexbox {
display: flex;
flex-wrap: wrap;
}
.flexbox-column {
flex-direction: column;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
.black {
background-color: black;
}
.gray {
background-color: gray;
}
.green {
background-color: green;
}
.yellow {
background-color: yellow;
}
.orange {
background-color: orange;
}
.violet {
background-color: violet;
}
.flexbox-element {
width: 200px;
min-height: 200px;
}
.flexbox-group {
width: 400px;
height: 600px;
flex-direction: column;
}
<div class="flexbox" style="flex: 1; width: 500px">
<div class="flexbox flexbox-element flexbox-group">
<div class="flexbox-element red"></div>
<div class="flexbox-element green"></div>
<div class="flexbox-element blue"></div>
<div class="flexbox-element black"></div>
<div class="flexbox-element gray"></div>
</div>
<div class="flexbox-element yellow"></div>
<div class="flexbox-element orange"></div>
<div class="flexbox-element violet"></div>
</div>
CSS3 Multicolumns solution
CSS3 Grid layout solution
Due to the limitations of Flexbox when direction is column (you need to limit the height somehow or else it won't wrap in a second column), it's a simpler job for CSS3 Multicolumns:
.col-2 {
columns: 2;
}
.flexbox {
display: flex;
flex-wrap: wrap;
}
.flexbox-element {
flex: 1 1 auto;
}
.col-2 {
columns: 2;
width: 100%;
outline: 1px dashed blue;
}
.col-2 > * {
width: 50%;
min-height: 200px;
outline: 1px dotted red;
}
.red {
background-color: red;
}
.blue {
background-color: blue;
}
.green {
background-color: green;
}
.yellow {
background-color: yellow;
}
.orange {
background-color: orange;
}
.violet {
background-color: violet;
}
.black {
background-color: black;
}
.gray {
background-color: gray;
}
.flexbox-element {
width: 200px;
min-height: 200px;
}
<div class="flexbox" style="flex: 1; width: 500px">
<div class="flexbox flexbox-element col-2" style="flex: 1 1 100%">
<div class="red">A</div>
<div class="green">B</div>
<div class="blue">C</div>
<div class="black">D</div>
<div class="gray">E</div>
</div>
<div class="flexbox-element yellow"></div>
<div class="flexbox-element orange"></div>
<div class="flexbox-element violet"></div>
</div>
You could also use CSS3 Grid layout but you'll need to position manually each grid item in IE10-11 and Edge 12-15 (current Edge 16 supports the same newer recommendation that other modern browsers)
Grid layout (compat Edge 16+ and other modern browsers. IE11 needs explicit positioning of both row and column of each grid item)
➡️ https://codepen.io/PhilippeVay/pen/GdBpJa?editors=0100
.col-2 {
display: grid;
grid-auto-flow: column;
grid-template-columns: repeat(2, minmax(0, 1fr)); /* 2 columns with strict equal width */
}
.col-2 > :nth-child(odd) {
grid-column: 1; /* even items can now only occupy the 2nd column */
}