I'm trying to use grid-areas to have a 30%/70% split in a box with an image on the left and text on the right, but they keep overlapping and I don't know how to fix it. Image isn't showing up in snippet but it should be on the left.
.gridcart {
display: grid;
width: 100%;
/* height: 250px; */
grid-template-areas: "cartimg carttext";
/* grid-template-rows: 30% 70%; */
/* grid-template-columns: 30% 70%; */
}
#cartimg {
grid-area: cartimg;
background-color: #82241F;
}
#carttext {
grid-area: carttext;
}
#topbox {
background-color: white;
padding: 1em;
margin-top: 1%;
margin-bottom: 1%;
border: 3px solid #82241F;
display: grid;
/* grid-template-rows: 500px 500px; */
/*grid-template-areas:
"left right";*/
}
<div class="container">
<h1>My Cart</h1>
<div id="topbox" class="gridcart">
<div class="" id="cartimg">
<img src="images/glove.jpg" alt="" height="200px">
</div>
<div class="" id="carttext">
<h2>Single Latex Glove</h2>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Laudantium deleniti eos ducimus error, adipisci doloremque beatae? Optio, culpa harum! Accusantium modi aut sint numquam eius amet facilis rem quaerat consequuntur.</p>
</div>
</div>
</div>
I'm not sure why you say you need grid-template-areas.
For what you are explaining, you may use just:
#topbox {
display: grid;
grid-template-columns: 30% 70%;
}
Here you can see a codepen
I hope that helps!!
If you set columns up like this…
grid-template-columns: 30% 70%;
…you will eventually have issues with overlapping at smaller screen dimensions, as the OP discovered.
I think what you actually want is for the second column to take up whatever space the first column did not fill. Using fr (or auto), you don't need to guess at layout proportions using hard-coded percentages.
grid-template-columns: max-content 1fr;
Demo:
#topbox {
background-color: white;
padding: 1em;
margin-top: 1%;
margin-bottom: 1%;
border: 3px solid #82241F;
display: grid;
grid-template-columns: max-content 1fr;
grid-gap: 10px;
}
#cartimg {
margin: auto;
}
img {
height: 200px;
}
<div class="container">
<h1>My Cart</h1>
<div id="topbox" class="gridcart">
<div class="" id="cartimg">
<img src="data:image/webp;base64,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" alt="">
</div>
<div class="" id="carttext">
<h2>Single Latex Glove</h2>
<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Laudantium deleniti eos ducimus error, adipisci doloremque beatae? Optio, culpa harum! Accusantium modi aut sint numquam eius amet facilis rem quaerat consequuntur.</p>
</div>
</div>
</div>
Related
I'm trying to replicate a website that claimed it was only made with the basic Html, CSS and JavaScript. Annoyingly I can't seem to make the images responsive and relatively the same
Can someone explain to me what I’m doing wrong? I'm using flexbox to make the site responsive but the alignments are off and I cant get them to sit next to each other with all the correct padding as well
This is my work:
https://codepen.io/Hitmonchan98/pen/PoQLRPy
This is what I want my site to look like:
https://i.stack.imgur.com/jsdxo.jpg
//html
<body>
<div class="main">
<div class="main-img"><img class="firstImage"src="https://www.amazingonly.com/wp-content/uploads/2013/04/images4-1728x1080.jpg" alt=""></div>
<div class="text">
<h2>Discover innovative ways to decorate</h2>
<p class="para">Lorem, ipsum dolor sit amet consectetur adipisicing elit. Quia repudiandae dolore iure laudantium fugiat fuga sunt unde voluptates et, quasi exercitationem eum consectetur. Doloremque, ab?</p>
<div class="shop">Shop Now</div>
</div>
</div>
<div class="lower">
<div class="dark image">
<img class="dark-img" src="https://www.pixelstalk.net/wp-content/uploads/2016/07/Download-Free-Pictures-4k.jpg" alt="">
</div>
<div class="text2">
<h3>About furniture</h3><p class="para">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Natus ipsa, adipisci perspiciatis debitis magni sed possimus pariatur qui exercitationem fugiat iusto error ducimus, quos quis, eius earum tempore quibusdam laboriosam!</p></p></div>
<div class="light image">
<img class="light-img"src="https://www.pixelstalk.net/wp-content/uploads/2016/07/Download-Free-Pictures-4k.jpg" alt="">
</div>
</div>
</body>
//css
body{
margin: 0;
padding: 0;
line-height: 2rem;
}
/*Body*/
.firstImage,.light-img,.dark-img
{
width: 100%;
}
.text2{
padding: 2rem;
}
.text h2
{
font-size:3rem;
}
#media screen and (min-width: 768px) {
.main{
display: flex;
}
.text{
padding: 1rem 3rem 3.5rem 3rem;
}
.lower{
display: flex;
align-content:center;
}
.text2{
padding:0;
width: 40%;
}
.dark, .light
{
width: 30%;
}
.dark-img, .light-img {
width: 100%;
}
}
#media screen and (min-width: 786px) {
}
Add display: block; to your img elements and this should get rid of the white spacing underneath them. Images are weird in HTML since they have properties of both display inline and block, and I usually set them to block to have maximum styling control over them.
i've been trying to make the text div to take the entire width of the grid layout but have it's content in line with the rest of the layout itself
I've used width: 100vw, tried padding the corners yet it doesn't work properly and is a bit clunky.
I've uploaded it to the codepen for better understanding
https://codepen.io/Aegtar/pen/PoObBdG
what is needed is that the green part will take the entire width yet the text inside will stay within the lightsalmon div.
the HTML :
<div class='main-layout'>
<div class='weather-page'>
<div class='top-side'>
<div>WeatherPage</div>
<div class='text-container'>
<div class='ha'>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Repellat expedita molestiae nisi dolorum est,
tempore dolore! Itaque quidem nobis deleniti! Lorem ipsum dolor sit amet.
</div>
</div>
<button>
2
</button>
<button>
2
</button>
</div>
</div>
</div>
<section class='footer'>Footer</section>
</div>
the scss :
.main-layout {
display: grid;
grid-template-columns: minmax(10px, 1fr) minmax(auto, 1300px) minmax(10px, 1fr);
> * {
grid-column: 2;
}
> *.full {
grid-column: 1 / -1;
}
}
.home-page {
margin: 0 auto;
display: flex;
flex-direction: column;
width: 50%;
justify-content: center;
align-items: center;
gap: 40px;
}
.weather-page {
gap: 10px;
grid-auto-flow: column;
background-color: lightsalmon;
.top-side {
gap: 20px;
align-items: center;
flex-direction: column;
display: flex;
margin-bottom: 30px;
.text-container {
background-color: lightgreen;
.ha {
text-align: center;
}
}
}
.footer {
background-color: rgb(25, 118, 210);
}
any help is appreciated!
Just remove the grid-template-columns:minmax(10px, 1fr) minmax(auto, 1300px) minmax(10px, 1fr);
from the .main-layout and then add
body{
padding:0;
margin:0;
}
so that it can strech all the way.
Also, if you want the grid-template-columns , then comment on this post and I will (probably) find another solution.
Code Pen: https://codepen.io/576031/pen/rNYWqbz
It seems like you're not really using your grid. You're creating 2 empty columns on the sides for styling and putting all the content in the center column. Why not use the default layout with a simple container and recreate what you want just by using the basic stylings with width, margin and padding.
* { margin: 0 auto; }
.width-90 { width: 90%; }
.width-100 { width: 100%; }
article {
text-align: center;
max-width: 1300px;
border: solid 1px black;
}
article > * { padding: 10px 0 30px 0; }
article header, article section { background-color: lightsalmon; }
article main { background-color: lightgreen; }
article footer { background-color: lightblue; }
/*SCSS was not supported in this snippet but you could remove the word article in the lines above and then just place them in article if you want it to be specific with SCSS*/
<div class='main-layout'>
<article class='weather-page'>
<header class="header width-90">
<h2>WeatherPage</h2>
</header>
<main class='main width-100'>
<p class="width-90"> Lorem ipsum dolor sit amet consectetur adipisicing elit. Repellat expedita molestiae nisi dolorum est, tempore dolore! Itaque quidem nobis deleniti! Lorem ipsum dolor sit amet consectetur adipisicing elit. Iste, at. Atque alias modi nam provident quam, consectetur unde sunt exercitationem corrupti veritatis ea, itaque sint vero voluptatibus in fugit delectus recusandae eos enim deleniti doloribus magni. Repudiandae obcaecati blanditiis temporibus, vitae numquam illum ducimus voluptates sed in repellat quis esse! Cupiditate facilis magni velit molestias iure enim optio ratione. Ad? </p>
</main>
<section class="section-buttons width-90">
<p><button>2</button></p>
<p><button>2</button></p>
</section>
<footer class='footer width-100'>
<p class="width-90">Footer</p>
</footer>
</article>
</div>
If you really want to keep your html structure the way it is then you could probably use a variable since you're working with SCSS. You could try this for example:
$grid-sides: 10px;
.main-layout {
display: grid;
grid-template-columns: minmax($grid-sides, 1fr) minmax(auto, 1300px) minmax($grid-sides, 1fr);
/* ... everything else ...*/
}
/* at the right place in your SCSS*/
.text-container {
margin-left: -$grid-sides;
margin-right: -$grid-sides;
padding-left: $grid-sides;
padding-right: $grid-sides;
background-color: lightgreen;
/* ... everything else ...*/
}
I'm creating an 'About' section for a website, which is a table with three equal-width columns: a headshot, a paragraph, and another paragraph (see screenshots below).
I'd like to have the image automatically resize (keeping its aspect ratio) to be the height of the largest text- aligned left within the cell- without hardcoding any height/width values. However, I've played around a bunch and nothing seems to make the image resize.
/* an element that's one-third the width of its container */
.third-width {
width: 33%;
}
/* the headshot photo */
#headshot {
border-radius: 5px;
max-width: 100%;
max-height: 100%;
display: inline-block;
}
#about-table td {
background-color: pink;
padding: 1vw;
text-align: justify;
vertical-align: top;
font-family: var(--body-font);
font-weight: lighter;
}
<table id="about-table">
<tr>
<td class="third-width">
<img id="headshot" src="https://via.placeholder.com/80" alt="None">
</td>
<td class="third-width">
<p>[... SOME TEXT ...]</p>
</td>
<td class="third-width">
<p>[... SOME TEXT ...]</p>
</td>
</tr>
Current state:
What I would like:
Thank you!
Use CSS Flex instead of table
Make the cells flex: 1; position: relative;
Make the image position: absolute; with 100% W/H and object-fit: cover to not distort the image
/* QuickReset */
* { margin:0; box-sizing: border-box; }
/* About component */
.About {
display: flex;
}
.About > div {
position: relative;
flex: 1;
outline: 1px solid #000;
padding: 20px;
}
.About > div img {
position: absolute;
top:0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
object-fit: cover;
}
<div class="About">
<div><img src="https://placekitten.com/408/287" alt="Catz!"></div>
<div>Lorem ipsum</div>
<div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Molestiae sunt nisi nostrum sed, assumenda sequi doloribus excepturi quibusdam obcaecati tenetur tempora voluptatibus eligendi dolorem. Excepturi perspiciatis ipsa porro, minus ea.</div>
</div>
<div class="About">
<div>Lorem ipsum</div>
<div>Molestiae sunt nisi nostrum sed, ipsa porro, minus ea.</div>
<div><img src="https://placekitten.com/500/300" alt="Catz!"></div>
</div>
<div class="About">
<div><img src="https://placekitten.com/310/290" alt="Catz!"></div>
<div>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Molestiae sunt nisi nostrum sed, assumenda sequi doloribus excepturi quibusdam obcaecati tenetur</div>
<div>Lorem ipsum</div>
</div>
I'm working on a css grid where the template is as follows:
grid-template-columns: 70% 30%;
grid-template-areas:
"hero info"
"hero map"
"home home";
Within the hero, there is an image and when moving the window to check responsiveness, the image gets to the point where it has a shorter height than the grid allows. Is there any way I can have the "info" and "map" section shrink along with the image? I imaging I would need to have the div resize rather than the image, but nothing has worked so far.
Here is the space that I'm referring to, where as the browser window shrinks, this white space appears.
Here is the codepen
And the snippet is below. I do have a media query in place so that the layout changes as the browser goes smaller, but currently this is happening before the breaking point. I'm wondering if it can be done without changing up the breaking point of the media query.
body,
html {
margin: 0;
padding: 0;
}
/*navbar for window viewing purposes */
nav {
height: 41px;
background-color: rgba(200, 200, 200, 0.5);
}
.home-wrapper {
background-color: #e6e6e6;
width: 100%;
grid-area: home;
}
.home-container {
width: 80%;
margin: auto;
padding-bottom: 40px;
}
#main-map {
grid-area: map;
max-width: 96%;
max-height: 100%;
position: relative;
overflow: hidden;
padding-top: 56.25%;
}
#main-map iframe {
display: block;
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
border: 0;
padding: 0px 5px 0px 5px;
}
#info {
margin: 10px;
grid-area: info;
}
.hero {
margin: auto;
max-width: 1940px;
position: relative;
grid-area: hero;
}
.hero img {
display: block;
height: auto;
width: 100%;
object-fit: cover;
object-position: center;
}
.home {
display: grid;
grid-template-columns: 70% 30%;
grid-template-areas:
"hero info"
"hero map"
"home home";
}
/* Query */
#media (max-width: 1040px){
.home {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-areas:
"hero hero"
"home home"
"info map";
}
<nav>
</nav>
<div class="home">
<div class="hero" >
<img src="https://picsum.photos/1164/560">
<span></span>
</div>
<div id="info">
<p>
Location address <br><br>
1111 Main Street <br />
Salt Lake City, UT 11111 <br /><br />
P.O. Box 111 <br />
Sale Lake City, UT 11111 <br /><br />
111.111.1111 <br />
Fax 111.111.1111 <br />
</p>
</div>
<div id="main-map">
<iframe src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d3007.5980492403837!2d-112.45179968409789!3d41.077778023093046!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x0%3A0x0!2zNDHCsDA0JzQwLjAiTiAxMTLCsDI2JzU4LjYiVw!5e0!3m2!1sen!2sus!4v1574099632743!5m2!1sen!2sus" frameborder="0" style="border:0;"></iframe>
</div>
<div class="home-wrapper">
<div class="home-container">
<div id="home-about">
<h3>Our Business</h3>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Voluptatem, necessitatibus.
states. <br /><br />
Lorem ipsum dolor sit amet consectetur adipisicing elit. Sunt atque, facilis deleniti eius non culpa delectus? Eos placeat sit alias!
<br /><br />
orem ipsum dolor sit amet consectetur adipisicing elit. Sunt atque, facilis deleniti eius non culpa delectus? Eos placeat sit alias!
<br /><br />
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officiis repudiandae temporibus ut! Esse asperiores libero eum quia, optio nostrum commodi similique consequuntur ad sapiente saepe suscipit provident, molestias est quisquam qui culpa nihil totam earum. Officia aliquam praesentium rerum beatae.
<br /><br />
Our Business <br /><br />
Salt Lake City Utah
</p>
<form action="contact.html">
<button class="btn btn3">Contact Us</button>
</form>
</div>
</div>
</div>
</div>
Using object-fit:fill or object-fit:cover seemed to help for me. Although I was getting weird inconsistencies with codepen. Please let me know if that helps.
.hero {
max-width: 1940px;
position: relative;
grid-area: hero;
}
.hero img {
display: block;
height: 100%;
width:100%;
object-fit: fill;
object-position: center;
}
I'm picking up website building after a long vacation (~5 years). CSS standards have changed, and I'm still trying to catch up.
Anyway, I'm still very strict on the quality of my html and will not compromise on that for layouting.
Here's my HTML. It can't change, except for the image-right and image-left classes. Those can be replaced by class="right" or class="left" on the corresponding images.
<div class="text-block image-left">
<h2>A block of text with image on the left</h2>
<img src="https://picsum.photos/300/200" alt="A nice picture" />
<p>
This is one paragraph.
</p>
<p>
This is the second paragraph.
</p>
</div>
<div class="text-block image-right">
<h2>A block of text with image on the right</h2>
<img src="https://picsum.photos/300/200" alt="A nice picture" />
<p>
This is one paragraph.
</p>
<p>
This is the second paragraph.
</p>
</div>
The HTML above reflects how I want it to display on a mobile browser: one column with header, image, and then text.
However, on a desktop browser, I want to make it look like this (well, roughly anyway):
What's the appropriate CSS to achieve that layout without altering the HTML, and having a responsive layout?
CSS Grid is awesome, but for this your best bet would be to use Flexbox and it would be good for accessibility to use some semantic HTML5 too.
For your HTML:
<figure class="image-left">
<img src="https://picsum.photos/300/200" alt="A nice picture" />
<figcaption>
<h2>A block of text with image on the left</h2>
<p>This is one paragraph.</p>
<p>This is the second paragraph.</p>
</figcaption>
</figure>
<figure class="image-right">
<img src="https://picsum.photos/300/200" alt="A nice picture" />
<figcaption>
<h2>A block of text with image on the right</h2>
<p>This is one paragraph.</p>
<p>This is the second paragraph.</p>
</figcaption>
</figure>
And for your CSS:
/* Add styling here you wish to add for screens with a width less than 600px */
#media screen and (min-width: 600px) {
/* Add styling here you wish to add for screens with a width of 600px and wider */
figure {
display: flex;
}
figcaption {
width: 100%;
}
.image-left {
flex-direction: row-reverse;
}
.image-right {
/* This is set to flex-direction: row; by default so doesn't need to be added */
}
}
Any problems or need extra help feel free to comment below :)
Here is a way to do it with grid.I only modified the html by adding a class mobile in your text-block divs to get equal specificity for the #media rules (and avoid duplicate CSS).
/* here I define a 4x3 grid */
/* rows are set to auto so the ones not used will collapse */
div.text-block {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows : repeat(4, auto); }
/* here I tell the h2 for .image-left to start a col2 and use 2 columns */
/* each column is 1fr, so 2 columns is 2/3 of the available space */
div.text-block.image-left h2 {
grid-column: 2 / span 2;
}
/* I don't need to position each "p" on rows, just tell them which
column to go to */
/* no need to put them in a div */
div.text-block.image-right p {
grid-column: 1 / span 2; }
/* I use this code to make your image resize automatically,
but there is plenty of choice to make it look the way you want.
You can also check out the "object-fit" property */
div.text-block.image-left img {
display: block;
height: auto;
max-height: 100%;
max-width: 100%; }
/* for the #media rules I needed a .mobile class to have the same specificity
as the first rule (edit : though removing ".text-block" for "p" and "h2"
declarations would have the same effect) */
/* also needed to re-use "justify-self" on images
as it has priority over justify-items */
#media screen and (max-width: 900px) {
/* all blocks */
div.text-block.mobile h2 {
grid-column: 1 / span 3;
}
You can play with grid-template-columns, grid-template-rows to find the "right" proportions for what you need (for example : grid-template-rows: .2fr repeat(2, 1fr) auto;).
If you have questions, I'll be happy to answer them (or try to at least) ;)
html {
-webkit-box-sizing: border-box;
box-sizing: border-box;
font-size: 16px;
}
*,
*::after,
*::before {
-webkit-box-sizing: inherit;
box-sizing: inherit;
}
img,
p,
h2,
div {
margin: 0;
padding: 0;
}
body {
margin: 0;
padding: 0;
min-height: 100vh;
}
div.text-block {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(4, auto);
/*grid-template-rows: .2fr repeat(2, 1fr) auto;*/
align-items: start;
justify-items: left;
}
/* first block */
div.text-block.image-left h2 {
grid-column: 2 / span 2;
}
div.text-block.image-left p {
grid-column: 2 / span 2;
width: 100%;
}
div.text-block.image-left img {
display: block;
height: auto;
max-width: 100%;
grid-column: 1 / span 1;
grid-row: 1 / span 3;
}
/* 2nd block */
div.text-block.image-right h2 {
grid-column: 1 / span 2;
}
div.text-block.image-right p {
grid-column: 1 / span 2;
width: 100%;
}
div.text-block.image-right img {
display: block;
height: auto;
max-width: 100%;
grid-column: 3 / span 1;
grid-row: 1 / span 3;
justify-self: right;
}
/* just to show what's going on */
h2 {
background: blue;
}
p {
padding: 5px;
border: white 1px solid;
background: black;
color: white;
}
div.text-block {
background: white;
border: 2px solid green;
}
/* media query */
#media screen and (max-width: 900px) {
/* all blocks */
div.text-block {
justify-items: center;
}
div.text-block.mobile h2,
div.text-block.mobile p {
grid-column: 1 / span 3;
}
div.text-block.mobile img {
grid-column: 1 / span 3;
grid-row: 2 / span 1;
justify-self: center;
}
}
<div class="text-block mobile image-left">
<h2>A block of text with image on the left</h2>
<img src="https://picsum.photos/600/400" alt="A nice picture" />
<p>
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Quaerat quas eius, ab corporis architecto quam? Soluta, reprehenderit eveniet porro fugiat ratione voluptatum harum ea fuga facilis ad incidunt cumque maiores. Lorem ipsum, dolor sit amet consectetur
adipisicing elit. Eos libero illo repellat sint in culpa itaque est modi, eum officia a laborum iure alias cupiditate tenetur, cumque dolorem deleniti? Eum!
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nisi amet quaerat facere maiores sequi velit totam praesentium adipisci provident aspernatur at commodi, nostrum voluptates esse reiciendis optio rem et impedit!Eveniet ipsa delectus voluptate suscipit
possimus totam qui iusto consectetur sapiente maiores culpa alias, unde enim laudantium libero, consequatur explicabo adipisci non! Non quis optio fugiat, ullam dolorem iure debitis?
</p>
</div>
<div class="text-block mobile image-right">
<h2>A block of text with image on the right</h2>
<img src="https://picsum.photos/600/400" alt="A nice picture" />
<p>
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Quaerat quas eius, ab corporis architecto quam? Soluta, reprehenderit eveniet porro fugiat ratione voluptatum harum ea fuga facilis ad incidunt cumque maiores. Lorem ipsum, dolor sit amet consectetur
adipisicing elit. Eos libero illo repellat sint in culpa itaque est modi, eum officia a laborum iure alias cupiditate tenetur, cumque dolorem deleniti? Eum!
</p>
<p>
Lorem ipsum dolor sit amet consectetur adipisicing elit. Nisi amet quaerat facere maiores sequi velit totam praesentium adipisci provident aspernatur at commodi, nostrum voluptates esse reiciendis optio rem et impedit!Eveniet ipsa delectus voluptate suscipit
possimus totam qui iusto consectetur sapiente maiores culpa alias, unde enim laudantium libero, consequatur explicabo adipisci non! Non quis optio fugiat, ullam dolorem iure debitis?
</p>
</div>
Edit :
grid-template-rows: repeat(auto-fit, minmax(50px, 1fr));
This is a way to create rows automaticaly if you want to add paragraph and not change the template.
But there are 2 drawbacks :
A height which do not adjust to the content must be defined (not auto, max-content ...etc)
For now I don't know how to make the image "span" all the "not collapsed rows" automatically. So you will need to increment the span for 'grid-row: 1 / span 3;' for the image each time you add a 'p'