How to stack CSS elements horizontally for websites - html

I'm building my first real webpage and I'm trying to figure out how to stack the elements on the home screen correctly. I've read and tried similar posts but they don't seem to do what I need. Currently my homepage looks like this (ignore the list at the bottom of the page and subscribe/ login buttons. They are just part of the default theme):
This was achieved using the following code:
HTML:
<div class="desc-pic-parent">
<div class="homepage-description">
<div class="homepage-description-header">
Hi! I'm Lewis Cooper
</div>
<div class="homepage-description-text">
This is a description of me. I will put quite a bit of text here so that I can get a rough idea of what it's going to look like in the final edit of the webpage
</div>
</div>
<div class="square-pretend-img"></div>
</div>
CSS:
#media (min-width: 1001px) {
.disc-pic-parent {
grid-column: 1 / span 3;
display: grid;
grid-gap: 4vmin;
grid-template-columns: 1fr 1fr 1fr;
min-height: 280px;
border-top: 0;
}
.homepage-description{
text-align: left;
display: grid;
grid-gap: 4vmin;
grid-template-columns: 1fr 1fr;
min-height: 280px;
border-top: 0;
}
.homepage-description-header{
font-size: 3rem;
margin-top: 0;
}
.square-pretend-img{
position: relative;
height: 20rem;
width: 20rem;
background-color: #555;
grid-column: 2 / span 2;
}
}
My goal is to try and get it to look something like this sketch:

The idea of using a grid for the main layout is fine and will keep your text at a constant width even if it is too long, but you also have put a grid in your left hand box which isn't the layout your desired image shows. You have also given the img defined dimensions and yet defined column spans for the grid.
This snippet just takes it that you want the img to have the given dimensions so removes the extra grid information.
#media (min-width: 1001px) {
.desc-pic-parent {
display: grid;
grid-gap: 4vmin;
grid-template-columns: 1fr 1fr;
min-height: 280px;
border-top: 0;
}
.homepage-description {
text-align: left;
min-height: 280px;
border-top: 0;
}
.homepage-description-header {
font-size: 3rem;
margin-top: 0;
}
.square-pretend-img {
position: relative;
height: 20rem;
width: 20rem;
background-color: #555;
}
}
<div class="desc-pic-parent">
<div class="homepage-description">
<div class="homepage-description-header">
Hi! I'm Lewis Cooper
</div>
<div class="homepage-description-text">
This is a description of me. I will put quite a bit of text here so that I can get a rough idea of what it's going to look like in the final edit of the webpage
</div>
</div>
<div class="square-pretend-img"></div>
</div>
NOTE: you probably want to take some of the styling out of the media query and have it there for all viewport dimensions.

This can be simply achieved using flexbox.
Just wrap those two div's inside another div and give display: flex to that div.

Related

Sticky sidebar on desktop and within content on mobile

Im having issues trying to create a sticky sidebar. On mobile the content just needs to flow within its container, then on desktop that div needs to break out into a sticky sidebar on the right, while the content flows on the left side as normal:
http://jsfiddle.net/sace510n/
Think its causing issues because the div for the sidebar is in the middle of each block.
.a {
position: sticky;
top: 0;
right: 0;
}
}
Any ideas would be greatly appreciated, thanks
Grid is the way to go here imho. Just create a new grid with 2 columns for your desktop inside your media query then set grid-column for the grey items to the left and the red one to the right. Then use position: sticky to, er, make it sticky.
The code should be self-explanatory but if not just drop me a comment on and I'll explain.
Edited: If each element is a different size, and the right-hand element is bigger than the first left-hand element then the gaps may look uneven. To solve this use a grid-row span on the .b class rule and choose a span that's big enough to keep the gaps even. Unfortunately grid-row: 1/-1 doesn't work on implicit grids.
body {
background: #20262e;
padding: 20px;
font-family: Helvetica;
}
.content {
display: grid;
gap: 1rem;
width: 100%;
max-width: 800px;
margin: 0 auto;
outline: 1px solid lime;
}
.a,
.b {
padding: 15px;
width: 200px;
height: 100px;
margin: 0 auto;
display: block;
}
.a {
background: grey;
}
.b {
background: red;
height: fit-content; /* added this during edit */
}
#media (min-width: 768px) {
.content {
grid-template-columns: repeat(2, 1fr);
}
.a {
grid-column: 1/2;
}
.b {
position: sticky;
top: 0;
grid-column: 2/3;
grid-row: 1/ span 3; /* <- choose a number to give the RHS grid enough space so the gaps of the LHS items don't grow */
}
}
.h0 {
height: 2.5rem;
}
.h1 {
height: 10rem;
}
.h2 {
height: 13rem;
}
.h3 {
height: 4rem;
}
<div class="content">
<div class="a h0">title1</div>
<div class="a">title2</div>
<div class="a">title3</div>
<div class="a">title4</div>
<div class="a h1">title5</div>
<div class="a h1">title6</div>
<div class="a">title7</div>
<div class="a h2">title8</div>
<div class="b">here on mobile, sticky sidebar on desktop <br/>title<br />title<br />title<br />title<br />title<br />title<br /></div>
<div class="a h1">title9</div>
<div class="a h3">title10</div>
</div>

fill the gap between the main and the footer for responsive

When i use the responsive tool of Chrome(<699pw) it create a huge gap between the footer and the div base but i want the footer a the bottom of the page. I don't know if it is the grid of the parent . I want to extend the base and make it closed to the footer so even if we extend the responsive tool. So it'has to follow the footer
header {
display: grid;
grid-template: auto;
grid-template-columns: 1fr 5fr 6fr 4fr;
align-items: center;
font-size: 30px;
position: relative;
top: 50%;
}
.parent {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(3, 1fr);
grid-column-gap: 0px;
grid-row-gap: 0px;
}
.div1 { grid-area: 1 / 1 / 2 / 2; }
.div2 { grid-area: 1 / 2 / 2 / 3; }
.div3 { grid-area: 2 / 1 / 3 / 2; }
.div4 { grid-area: 2 / 2 / 3 / 3; }
.div5 { grid-area: 3 / 1 / 4 / 3; }
#bases{
display: grid;
grid-template: auto;
grid-template-columns: 2fr 4fr;
}
html,body{
margin: 0;
padding: 0;
}
/* Responsive */
#media (max-width: 699px){
#Titre {
display: none;
}
header {
background-color: #aa1010;
font-family: 'LexendTera';
color: white;
display: grid;
grid-template: auto;
grid-template-columns: 1fr 5fr 6fr 4fr;
align-items: center;
font-size: 10px;
position: relative;
top: 50%;
}
aside{
display: none;
}
#bases{
display: grid;
grid-template-columns: 1fr;
}
.parent{
display: grid;
align-items: center;
}
/* Mettre footer en bas de page */
footer {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
}
}
<!DOCTYPE html>
<html lang="fr">
<body>
<header>
<img src="img/logo.png" alt="logo" id="logo">
<h1 id="Titre">O'kebab</h1>
Composition
Connexion
</header>
<div id="bases">
<main>
<h1>"La maison du sandwich"</h1>
<div class="parent">
<div class="div1"><h1>Promotion</h1><p>Kebab Végetarien -50%</p> </div>
<div class="div2"><img src="img/vege.png" alt="vege"></div>
<div class="div3"><h1>Kebab du mois</h1><br><p> Kebab spicy</p></div>
<div class="div4"><img src="img/spicy.webp" alt="spicy"></div>
<div class="div5"><button>Commandez</button></div>
</div>
</main>
</div>
<footer>
<h2 id="contact">Contact</h2>
<h2 id="mention">Mentions légales</h2>
<img src="img/facebook.png" alt="facebook" id="face">
<img src="img/instagram.png" alt="instagram" id="insta">
<img src="img/iutly.png" alt="twitter" id="ly1">
<h3 id="tkt">© 2022 O'kebab</h3>
</footer>
</body>
</html>
I tried to use position:relative for the body but nothing change
The grid is fine,
In the screen size less than 699px width:
You made the header smaller by reducing its font size. And since a div is a block element by default, it would be positioned in a new line after the last element. So your "bases" div would be on top and attached beneath the header.
You forced the footer to be positioned fixed and go to the bottom of the page.
So naturally, there would be a gap between your "bases" and your "footer".
Now since the element positioned fixed is removed from the normal document flow, and no space is created for it on the page, you can't position the "bases" div relative to the "footer".
But, for fixing the gap between your divs there are many ways...
For example, you can add a height to your "bases" div and make it fill the gap.
If you want it to be responsive, instead of an absolute height you can give it a relative height, like using "%" or "vh":
#bases {
/* Relative to % of the height of the viewport */
height: 80vh;
}
And you can adjust the position of contents by "display flex" and "align-items" or maybe using padding and margins.
You can also make it "position absolute" as well and position it somewhere in the middle of the page. as I said there are many ways to fill that gap.
And a quick tip for using media queries, If you want to change an attribute of an element, you don't need to write all of its attributes again.
for example, if you have this code and you want to change its font size:
.header {
display: grid;
grid-template: auto;
grid-template-columns: 1fr 5fr 6fr 4fr;
align-items: center;
font-size: 30px;
position: relative;
top: 50%;
}
You can just change the font size, and there is no need to duplicate all of that code:
#media (max-width: 699px) {
.header {
font-size: 10px;
}
}

Image positioning with CSS grid and flexbox

what my image gallery is like at the moment
As you see I have 2 images in the grid system taking up 50% of the width. the problem I have is I want to have a third image below taking up 100% of the width below these two but still in the grid so it downsizes along with the other two images so how can I do this?
the HTML code I have is:
<div class="images">
<img
src="protest_2.jpg"
alt="a protest for black lives matter with their faces blurred"
/>
<img src="protest_1.jpg" alt="a climate strike with their faces blurred" />
</div>
the css code I have is:
.images img {
object-fit: cover;
height: 300px;
width: 100%;
border-radius: 3px;
box-shadow: 0 2px 20px rgba(0, 0, 0, .25);
display: flex;
justify-content: space-between;
margin-bottom: 20px;
}
.images {
/* CHANGE TO GRID */
display: grid;
grid-template-columns: repeat(2, 1fr);
justify-content: space-between;
grid-gap: 20px;
width: 940px;
max-width: 100%;
margin: auto;
}
#media (max-width: 1000px) {
.images {
grid-template-columns: 1fr;
}
}
set grid-row: of the first two images to 2 and set it to 3 for the last image. Elements in the same row will align.
You're looking for the image to span 2 columns, so use nth-child to select the third image and use grid-column-end:
.images img:nth-child(3) {
grid-column-end: span 2;
}
Or if you don't want to use nth-child, you can add a class to it and select it that way instead.

CSS Grid auto-wrap aside when it gets to a certain size

So I am creating a layout where I have a
<div id="structure-content">
<main>content goes here</main>
<aside>aside content</aside>
</div>
I want the aside to be a quarter of the width and to automatically wrap to below the main once it hits a certain size and the main to take the full width. I know I can do this with media queries but people are saying that it can be done with grid and no media queries. I have been experimenting and researching for hours and cannot work it out. Any ideas? If it cannot be done then that is fine and I can try it with flexbox or media queries.
Props in advance.
The below code the div reach certain size will goes down automatically. If you want to drop the div particular size we have to use media query only.
#structure-content {
margin-bottom: 1em;
background: #fff;
color: #fff;
padding: 1.5em 1em;
display: flex;
flex-wrap: wrap;
flex-direction: row;
}
main {
background: green;
}
aside {
background: blue;
}
main,
aside {
flex: 1 0 15em;
margin-left: 0.5em;
margin-right: 0.5em;
}
<div id="structure-content">
<main>content goes here</main>
<aside>aside content</aside>
</div>
With CSS Grid, you can make the main and aside to take half of the available width and auto-wrap when either of the grid item hit a minimum width using grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)) - see demo below:
body {
margin: 0;
}
#structure-content {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
main {
background: aliceblue;
}
aside {
background: cadetblue;
}
<div id="structure-content">
<main>content goes here</main>
<aside>aside content</aside>
</div>
Solution
With CSS Grid, I'd say you can go with media queries. Anyway a flexbox will work here nice:
use a wrapping flexbox
keep a min-width for each of aside and main and add flex: 1 to flex it to the remaining space if available - see demo below:
body {
margin: 0;
}
#structure-content {
display: flex;
flex-wrap: wrap; /* a wrapping flexbox */
}
main {
background: aliceblue;
min-width: 75vw; /* forces aside to take one-fourth space */
flex: 1;
}
aside {
background: cadetblue;
min-width: 250px; /* minimum width of aside */
flex: 1;
}
<div id="structure-content">
<main>content goes here</main>
<aside>aside content</aside>
</div>

Prevent grid area from expanding causing whole page to scroll

I'm using the following grid layout:
grid-template-columns: 10em 1fr 10em;
grid-template-rows: 2em 1fr 2em;
To create a centered area that fills most of the screen while leaving some padding around it. Inside this 1fr x 1fr grid area is a pane div which contains an editor div which contains a content div.
The content div can be any height, and the editor div has overflow: scroll set. My problem is that instead of pane staying the same size and editor handling the overflow, pane grows and causes the whole page to scroll.
I can keep pane from growing by setting its overflow: scroll, but this causes the editor itself to scroll, rather than its content. This is unacceptable because the editor has buttons which must always be on screen.
Is there a way, within grid layout, to allow this functionality? I originally had it working with a flex layout, where the pane div was a single item within a 100% x 100% flexbox. I switched to grid to allow me to easily resize side-menus, so implementing this without grid is not preferable.
Also, multi-browser support would be amazing, but my target browser is Chrome.
Here's a jsfiddle with my reproducing my problem.
body, html {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#site {
width: 100%;
height: 100%;
background-color: #000;
display: grid;
grid-template-rows: 10em 1fr 10em;
grid-template-columns: 2em 1fr 2em;
grid-template-areas:
'top top top'
'lpn mid rpn'
'bot bot bot';
}
#pane {
grid-area: mid;
height: 100%;
width: 100%;
background-color: #f0f;
}
#editor {
display: relative;
overflow: scroll;
}
#content {
height: 2000px;
}
<div id='site'>
<div id='pane'>
<div id='editor'>
<div id='content'>
</div>
</div>
</div>
</div>
min-width: auto / min-height: auto
Generally speaking, a grid item cannot be smaller than its content. The default minimum size of grid items is min-width: auto and min-height: auto.
This often causes grid items to overflow their grid areas or grid containers. It also prevents scrollbars from rendering on the items, since an overflow condition can't be triggered (the grid item just keeps expanding).
To override this default (and allow grid items to shrink past their content size) you can use min-width: 0, min-height: 0 or overflow with any value other than visible.
This behavior, with references to official documentation, is explained in this post:
Prevent content from expanding grid items
1fr
Another thing to note is that 1fr means minmax(auto, 1fr). This means, again, that the track to which it is applied cannot shrink below the content size (i.e., the min value in the minmax() function is auto, meaning content-based).
Therefore, to override this setting, use minmax(0, 1fr) instead of 1fr.
More details here: https://github.com/w3c/csswg-drafts/issues/1777
revised demo (tested in Chrome, Firefox and Edge)
body, html {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
#site {
width: 100%;
height: 100%;
background-color: #000;
display: grid;
/* grid-template-rows: 10em 1fr 10em; */
grid-template-rows: 10em minmax(0, 1fr) 10em; /* new */
grid-template-columns: 2em 1fr 2em;
grid-template-areas:
'top top top'
'lpn mid rpn'
'bot bot bot';
}
#pane {
grid-area: mid;
height: 100%;
width: 100%;
background-color: #f0f;
overflow: auto; /* new */
}
#editor {
/* display: relative; */
/* overflow: scroll; */
}
#content {
height: 2000px;
}
<div id='site'>
<div id='pane'>
<div id='editor'>
<div id='content'></div>
</div>
</div>
</div>
jsFiddle demo
Not 100% sure if this is what you're asking. I added a wrapper to content to make it scrollable, and set a vh height on it, which you could adjust.
#content-scroll {
height: 40vh;
overflow: scroll;
}
#content {
height: 2000px;
}
<div id='site'>
<div id='pane'>
<div id='editor'>
<div id='content-scroll'>
<div id='content'>
</div>
</div>
</div>
</div>
</div>
https://jsfiddle.net/16owL8x0/