image goes out from grid and sizing issue - css

I'm pretty new to coding, and I'm trying to use a grid.
But I got stuck a little bit.
I have the following codePan project:
* {
box-sizing:border-box
}
body {
height:100vh;
width: 100%;
background-color: red;
padding:0;
margin:0;
}
#wrapper {
background-color:blue;
height:100%;
width:100%;
margin:0;
padding:0;
display: grid;
grid-template-areas:
"nav"
"content"
"footer" ;
grid-template-columns: 1fr;
grid-template-rows: .8fr 1fr .8fr ;
}
#nav {
background-color: yellow;
grid-area: "nav";
position: sticky;
top: 0;
}
#content {
background-color: pink;
grid-area: "nav";
display:flex;
flex-direction: column;
}
footer {
background-color: brown;
grid-area: "nav";
}
#box1 {
background-color:purple;
height:50%;
}
#box2 {
background-color: blue;
height:60%;
display:flex;
flex-direction: column;
}
.image {
height: auto;
width: 400px;
position: relative;
top:-150px;
}
button {
height: 90px;
width: 400px;
background-color: #262A58;
color: white;
font-size: 1.5em;
font-family: 'EightOne';
border-radius: 10px;
border-style: none;
cursor: pointer;
}
<div id="wrapper">
<div id="nav"> nav </div>
<div id="content">
<div id="box1">
<h1>flower</h1>
</div>
<div id="box2">
<img class="image" src="https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.goldpetal.net%2Fmedia%2Fimages%2Fproduct_gallery%2FGerbera_Flower_12.jpg&f=1&nofb=1" alt="">
<button> buy flower </button>
</div>
</div>
<footer>
footer
</footer>
</div>
what i want is the similar like on this picture:
picture
unfortunatly i can not postitioning, the contents in the Box2, becuase the button goes out completly out from grid.
I tried several options, but at the end it was always some issue with the content in the Box2.
if someone could give me an advice. Probably I'm using wrong way Grid...
Thank you!

Let your grid define the size of the areas, and use Flexbox to lay out your content.
You can absolutely achieve this layout with CSS Grid. The button was overflowing its content area because #box2 has a fixed height of 60% of the content grid area, but your .image and the button are taller than that. Basically your image pushes down the button.
You don’t need to set explicit heights on your content, because that’s taken care of the grid.
The white-blue background is a bit tricky, because it doesn’t align exactly with the edges of your image. But you can achieve this affect with a background gradient on your content container.
Check out this working solution as inspiration:
body {
height: 100vh;
padding: 0;
margin: 0;
}
#wrapper {
height: 100%;
width: 100%;
display: grid;
grid-template-areas:
'nav'
'content'
'footer';
grid-template-columns: 1fr;
grid-template-rows: 64px 1fr 96px;
}
#nav {
grid-area: nav;
position: sticky;
top: 0;
background-color: white;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
}
#content {
grid-area: content;
display: flex;
flex-direction: column;
justify-content: center;
background: linear-gradient(to bottom, transparent 60%, #aad 60%);
align-items: center;
padding: 32px;
}
#content .wrapper {
display: flex;
flex-direction: column;
width: 400px;
}
footer {
grid-area: footer;
}
.image {
border: solid 16px #aad;
margin: 16px;
}
button {
padding: 8px 16px;
background-color: #262a58;
color: white;
font-size: 1.5em;
font-family: 'EightOne';
border-radius: 10px;
border-style: none;
cursor: pointer;
margin-top: 32px;
align-self: center;
}
<div id="wrapper">
<div id="nav">nav</div>
<div id="content">
<div class="wrapper">
<h1>flower</h1>
<img
class="image"
src="https://external-content.duckduckgo.com/iu/?u=https%3A%2F%2Fwww.goldpetal.net%2Fmedia%2Fimages%2Fproduct_gallery%2FGerbera_Flower_12.jpg&f=1&nofb=1"
alt="Flower"
/>
<button>buy flower</button>
</div>
</div>
<footer>footer</footer>
</div>

Grid is not really used to make a full webpage. Everything is automatically stacked on top of eachother and should not have a fixed height. The height should changed based on the content.

Related

How to line up the top of two centered divs in a flex container?

Here is an example of my code :
.flex-container {
height: 300px;
width: 300px;
display: flex;
align-items: center;
justify-content: center;
background-color: #ffeeee
}
#item1 {
width: 100px;
height: 100px;
background-color: blue;
}
#item2 {
width: 120px;
height: 120px;
background-color: red;
}
<div class="flex-container">
<div id="item1"></div>
<div id="item2"></div>
</div>
https://jsfiddle.net/vL508wax/
I want the blue square to be centered and the top of the red square to be flush with the top of the blue square.
I know I can do this with margin-top for example but I don't think that's a good way to go. Can I do this with flexbox directly ?
A CSS grid solution since it would be difficult with flexbox:
.flex-container{
height:300px;
width:300px;
display:grid;
grid-auto-flow:column; /* side by side */
grid-template-rows:100px; /* the blue height here */
/* center everything*/
align-content:center;
justify-content:center;
/**/
background:
linear-gradient(green 0 0) center/100% 1px no-repeat,
#ffeeee
}
#item1{
width:100px;
height:100%;
background-color:blue;
}
#item2{
width:120px;
height:120px;
background-color:red;
transition:1s all;
}
#item2:hover {
height:160px;
}
<div class="flex-container">
<div id="item1">
</div>
<div id="item2">
</div>
</div>
I'm not sure about your use case nor have I done enough testing with this, But if there will always be 2 elements, you can make use of flex wrap alongside align-content: center;
.flex-container {
height: 300px;
width: 300px;
display: flex;
align-content: center;
flex-wrap: wrap;
justify-content: center;
background-color: #ffeeee
}
#item1 {
width: 100px;
height: 100px;
background-color: blue;
}
#item2 {
width: 120px;
height: 160px;
background-color: red;
}
<div class="flex-container">
<div id="item1"></div>
<div id="item2"></div>
</div>

limiting a child element to parent height, when parent height is not fixed

Is it possible to prevent the overflow of a child in a css grid container set to height: 80% ?
When a css grid row is set to 1fr, it is easily overflown by its children.
My main goal is to limit the height of .bottom & .side,
and have the ul element fill the .side element, while having overflow-y: scroll
.side should always be full height of .bottom.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body,
html {
height: 100%;
}
.container {
height: 80%;
max-height: 300px;
width: 500px;
margin: 0 auto;
border: 1px solid #000;
display: grid;
grid-template-rows: 72px 1fr;
}
.top {
background-color: cyan;
}
.bottom {
background-color: #e9eaf4;
display: grid;
grid-template-columns: 224px 1fr;
grid-column-gap: 24px;
}
.bottom .side,
.bottom .main {
background-color: #fff;
}
ul {
list-style: none;
border: 1px dashed red;
}
ul span {
padding: 10px;
font-size: 20px;
}
<div class="container">
<div class="top">top</div>
<div class="bottom">
<div class="side">side
<ul>
<li><span>1</span></li>
<li><span>2</span></li>
<li><span>3</span></li>
<li><span>4</span></li>
<li><span>5</span></li>
<li><span>6</span></li>
<li><span>7</span></li>
<li><span>8</span></li>
<li><span>9</span></li>
<li><span>10</span></li>
</ul>
</div>
<div class="main">main</div>
</div>
</div>
Adjust the code like below (check the comments). Related question to understand the min-height trick Prevent content from expanding grid items
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body,
html {
height: 100%;
}
.container {
height: 80%;
max-height: 300px;
width: 500px;
margin: 0 auto;
border: 1px solid #000;
display: grid;
grid-template-rows: 72px 1fr;
}
.top {
background-color: cyan;
}
.bottom {
background-color: #e9eaf4;
display: grid;
grid-template-columns: 224px 1fr;
grid-column-gap: 24px;
min-height:0; /* added */
}
.bottom .side,
.bottom .main {
background-color: #fff;
display:flex; /* added */
flex-direction:column; /* added */
min-height: 0; /* added */
}
ul {
list-style: none;
border: 1px dashed red;
overflow:auto; /* added */
}
ul span {
padding: 10px;
font-size: 20px;
}
<div class="container">
<div class="top">top</div>
<div class="bottom">
<div class="side">side
<ul>
<li><span>1</span></li>
<li><span>2</span></li>
<li><span>3</span></li>
<li><span>4</span></li>
<li><span>5</span></li>
<li><span>6</span></li>
<li><span>7</span></li>
<li><span>8</span></li>
<li><span>9</span></li>
<li><span>10</span></li>
</ul>
</div>
<div class="main">main</div>
</div>
</div>

CSS full page background height of scrollable div

there is html code:
<div class="container content">
<div class="wrap-container row">
<div class="col-xs-12 col-md-5 text-center text-white left">
<h2 class="mt-5">Contact</h2>
<h1> 987 123 456</h1>
</div>
<div class="col-xs-12 col-md-6 ml-auto right">
<div class="form">
<form>
<!-- form controls -->
</form>
</div>
</div>
</div>
</div>
now in css
.content.container {
height: 80vh;
overflow: hidden;
box-sizing: border-box;
}
.wrap-container {
position: relative;
height: 80%;
border-radius: 5px;
background: rgba(0,0,0,.3);
overflow: hidden;
box-sizing: border-box;
}
.left {
text-shadow: 0px 1px 2px #808080, 2px 2px 1px rgba(47,171,81, 0.8);
font-family: Verdana, Geneva, Tahoma, sans-serif;
}
.right {
background: rgba(0,0,0,.8);
color: #b9b9b9;
margin: 2rem;
height: 86%;
overflow: hidden;
box-sizing: border-box;
}
.form {
overflow: auto;
height:99%;
padding-right: 3rem;
position: relative;
width: 110%;
left: 0;
right: -2rem;
}
#media (max-width: 768px) {
.content.container {
height: 200vh;
display: block;
}
.wrap-container {
display: block;
height: auto;
overflow: auto;
}
.cb-slideshow li div h3 {
line-height: 0;
}
.right, .left {
margin:0;
}
.right {
height: auto;
}
.form {
padding-right: 1.5rem;
/*height: auto;*/
display: block;
}
}
now, when .form div is getting higher than verticah height (100vh) content is cut. In small devices like phone I can scroll .form div content but only vh is visible, there is no visible submit button :/
I added in media query height 200vh of .content.container what solved problem but I think it's not proper way.
How should I extend scrollable div till its content height?
Children adapting to parents height is best resolved using flexbox.
I have set the wrap-container as flex and flex-direction:column as the children are stacked. I would try to avoid setting different heights to all children.
Then just add overflow-y:scroll to the form.
.wrap-container {
display: flex;
flex-direction: column;
}
.form {
overflow-y: scroll;
}
If you want to achive something like: 100vh for the main container and items in overflow:hidden but .form scrollable, for all devices, it should be done like this:
Fiddle

Flexbox body and main min-height

https://jsfiddle.net/vz7cLmxy/
I'm trying to have the body to expand but the min-height does not work. I've read other related topics but can't get my head around it.
CSS and html
body,
html {
padding: 0;
margin: 0;
min-height: 100%;
}
body {
display: flex;
background: #eee;
flex-direction: column;
}
.menu {
background: red;
color: #fff;
padding: 10px;
}
.wrap {
display: flex;
}
.sidebar {
background: #ddd;
width: 300px;
}
.main {
background: #ccc;
flex: 1;
}
.footer {
background: #000;
color: #fff;
padding: 10px;
}
<div class="menu">Menu</div>
<div class="wrap">
<div class="sidebar">Sidebar</div>
<div class="main">Main</div>
</div>
<div class="footer">Footer</div>
Expected result is that main is streched to fill the height if it's less than 100%.
Use flex: 1 on the centered element:
.Site {
display: flex;
min-height: 100vh;
flex-direction: column;
}
.Site-content {
flex: 1;
background-color:#bbb;
}
<body class="Site">
<header>This is the header text ☺</header>
<main class="Site-content">…</main>
<footer>This is the footer text ☻</footer>
</body>
To get min-height with relative units working even in IE11 it needs just a tiny trick.
The nature of min-height is to overwrite the height when height is smaller then min-height. Very clear! But the pitfall is when min-height has a realitve unit (% or vh) and height is not set. Since it is relative it has no basis to relay on.
For all major browsers except Internet Explorer one possibility is to change the unit from % to vh:
body {
min-height: 100vh;
}
For Internet Explorer it needs a height (will be overwritten from min-height):
body {
height: 1px;
min-height: 100vh;
}
or to keep % the rules has to be applied to html too:
html, body {
height: 1px;
min-height: 100%;
}
A cross browser solution for the OP needs height: 1px on body and of course flex-grow: 1 for .wrap to let it grow faster then menu and footer:
body,
html {
padding: 0;
margin: 0;
height: 1px; /* added */
min-height: 100%;
}
body {
display: flex;
background: #eee;
flex-direction: column;
}
.menu {
background: red;
color: #fff;
padding: 10px;
}
.wrap {
display: flex;
flex-grow: 1; /* added */
}
.sidebar {
background: #ddd;
width: 300px;
}
.main {
background: #ccc;
flex: 1;
}
.footer {
background: #000;
color: #fff;
padding: 10px;
}
<div class="menu">Menu</div>
<div class="wrap">
<div class="sidebar">Sidebar</div>
<div class="main">Main</div>
</div>
<div class="footer">Footer</div>

How to make equal space between boxes in one row via CSS

I have a requirement that there are 4 boxes in one row.
the boxes have fixed width and height
but the width of the row will change by screen size.
the first box should be aligned to the left border of the row
last box aligned to right border.
Also the space between any two boxes should be equal.
Is there a pure CSS way to make that happen? Here is the jsfiddle code.
HTML:
<div class="row">
<div class ="col">
<div class="box"></div>
</div>
<div class ="col">
<div class="box"></div>
</div>
<div class ="col">
<div class="box"></div>
</div>
<div class ="col">
<div class="box"></div>
</div>
</div>
CSS:
.row {
display: table;
border: 1px solid green;
width: 400px; /* it changes by screen size actually */
padding: 5px;
}
.row:before, .row:after {
content: "";
}
.row:after {
clear: both;
}
.col {
float: left;
width: 25%;
}
.box {
border: 1px solid #DDD;
width: 80px;
height: 80px;
margin: 0 auto;
}
.col:first-child .box {
margin-left: 0;
}
.col:last-child .box {
margin-right: 0;
}
Use text-align:justify on the container, this way it will work no matter how many elements you have in your div (you don't have to work out % widths for each list item
Updated CSS
.row {
text-align: justify;
min-width: 412px;
border: 1px solid green;
width: 80%; /* it changes by screen size actually */
height: 90px;
padding: 5px;
}
.row:after {
content: '';
display: inline-block;
width: 100%;
}
.col {
display: inline-block;
}
.box {
border: 1px solid #DDD;
width: 80px;
height: 80px;
margin: 0 auto;
}
FIDDLE
You can make use of css3 flex boxes which is supported in modern browsers.
.row {
display: flex;
justify-content: space-between;
border: 1px solid green;
}
.box {
border: 1px solid #DDD;
width: 80px;
height: 80px;
}
<div class="row">
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
jsfiddle demo
more about flex boxes # css tricks
Why not use flexbox ?
Demo
css
.flex-container {
padding: 5px;
margin: 0;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
justify-content: space-between; /* this make the end divs at sides and equal space between other divs */
}
.flex-item {
background: tomato;
padding: 5px;
width: 200px;
height: 150px;
margin-top: 10px;
line-height: 150px;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
}
html
<div class="flex-container">
<div class="flex-item">1</div>
<div class="flex-item">2</div>
<div class="flex-item">3</div>
<div class="flex-item">4</div>
</div>
Read here for more detail on flexbox
you simply have to remove the padding attribute from the following
.row {
display: table;
border: 1px solid green;
width: 400px; /* it changes by screen size actually */
/*padding: 5px;*/
}
here is the demo.
Let me know if this was helpful or if you have anymore queries.

Resources