Responsive image flexbox with React and styled components - css

I'm a complete begginer, already desperate for a solution. I know it's basic stuff, but I've been through so many tutorials, tried grid templates, basically tried everything. Now it's all mixing up in my head and I will be grateful for any help.
I have six images in a flexbox, which are meant to be counters. They are styled.divs, containing an styled.img, styled.p and another styled.div wrapping the React CountUp. Everything is wrapped in a styled.div with display: flex. I have six ImgWraps and six p tags, since there will be different numbers and texts on it - this is the only way to make it adjustable (I think).
I also have the buttons, but they are not the problem here (at least for now).
Here's what I want to achieve:
Responsive, shrunk flexbox
Full-size flexbox
And here's what I have:
Div's flipping out of the containter
Huge row gap between
Some images go beyond the container as well as the p tag.
The full-size grid is almost as intended. The row gap is too big and I don't know what's the reason for that. I don't need the images to be "sticked" to each other, I wanted to have a small gaps between them. I've also tried centering the texts on the image, but nothing worked except the solution I'm using now. Also, the texts will have different length as well as the numbers, so I'm not sure how to do that automatically.
AboutWrapper (the main container) code:
export const AboutWrapper = styled.div`
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin: 20 auto;
object-fit: cover;
align-content: space-evenly;
z-index: 1;
height: 770px;
width: 100%;
max-width: 1200px;
margin-right: auto;
margin-left: auto;
padding: 0 24px;
row-gap: 0;
justify-content: center;
`;
The Img1Wrap (one of six):
export const Img1Wrap = styled.div`
max-width: 343px;
justify-self: center;
align-self: center;
justify-content: center;
text-align: center;
align-content: center;
position: relative;
height: 30%;
`;
ImgDesc, the p tag on the ImgWrap divs.
export const Img1Desc = styled.p`
font-size: 18px;
position: absolute;
height: 100%;
color: yellow;
z-index: 4;
top: 50%;
left: 30%;
`;
And the styled.img:
export const Img1 = styled.img`
width: 90%;
z-index: -1;
align-self: center;
justify-self: center;
margin: 0 0 5px 0;
padding-right: 0;
`;

This is just the basic styling you need to get the same distribution of items of that grid:
<body id='root'>
<div class='flex-box'>
<div class="templatecontent" style="background-image: url('https://www.zoomiami.org/assets/2440/air-boat.jpg');">
</div>
<div class="templatecontent" style="background-image: url('https://www.zoomiami.org/assets/2440/air-boat.jpg');">
</div>
<div class="templatecontent" style="background-image: url('https://www.zoomiami.org/assets/2440/air-boat.jpg');">
</div>
<div class="templatecontent stat bg-image" style="background-image: url('https://www.zoomiami.org/assets/2440/air-boat.jpg');">
</div>
<div class="templatecontent stat bg-image" style="background-image: url('https://www.zoomiami.org/assets/2440/air-boat.jpg');">
</div>
</div>
</body>
And the css:
#root {
height: 100vh;
width: 100vw;
}
.flex-box {
display: flex;
flex-wrap: wrap;
height: 100%;
}
.templatecontent {
flex-basis: 33%;
flex-grow: 1;
background-position: center;
background-size: cover;
}
#media (max-width: 600px) {
.templatecontent {
flex-basis: 100%;
}
}
Code example

Related

Flexbox items is overlapping the wrapper. How can I change this?

Hello I am making a cards type of component in React, I have a problem with styling this particular part as the flexbox items is overlapping the wrapper.
The JSX
const OtherProjects = () => {
return (
<div className='opWrapper'>
<div className="containerWrapper">
<div className="item"></div>
<div className="item"></div>
<div className="item"></div>
<div className="item"></div>
<div className="item"></div>
<div className="item"></div>
</div>
</div>
)
The CSS
.opWrapper{
width: 100%;
height: 100vh;
margin: 0 auto;
background-color: #232A4E;
}
.containerWrapper{
display: flex;
gap: 1em;
height: 100%;
justify-content: center;
align-items: center;
flex-wrap: wrap;
margin: 0 5em;
}
.item{
width: 20em;
height: 20em;
border-radius: 10px;
border: 2px black solid;
background-color: #CCF6F6;
}
It shows it like this when viewed on this dimension and other dimensions, I am not sure why the items are overlapping and now its showing the white thing
Usual browser view:
Just remove height: 100vh; from your .opWrapper selector:
.opWrapper{
width: 100%;
margin: 0 auto;
background-color: #232A4E;
}
The reason is that your are setting height to be the height of the view port.
You can find a working example here: https://codesandbox.io/s/thirsty-wind-1ci7ei?file=/src/styles.css

How do I use the width limit and use gap at the same time?

I have a problem, I need a form that will be limited in width and use the gap.
CodePen
body {
margin: 0;
padding: 0;
}
.container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 18px;
min-height: 100vh;
}
.container--example {
background-color: #000;
width: 100%;
height: 100px;
}
<div class="container">
<div class="container--example"></div>
<div class="container--example"></div>
<div class="container--example"></div>
<div class="container--example"></div>
</div>
Here the div is stretched to 100%, the whole screen, I can set the width settings on the element in the container, but then gap will not work.
Thank you so much in advance for your answer
Unfortunately, I do not know how to fix this problem, I hope to find the answer here.
UPD: Also, it is possible to put widths on the text and so on, but it's too much of a pain.
Set a padding to the parent of .container, in the example that would be body.
CSS body { padding: 0 2rem } would create a space of 2rem on either side of .container, which would be true for every child of body.
With a little math you can even make that space responsive:
16px space on a 320px viewport
256px space on a 1920px viewport
would yield equation y = 0.15x + 32 using Linear Equation y=mx+b for points p1(320,16) and p2(1920,256).
body {
margin: 0;
/* Using y=mx+b => y = 0.15x + 32 for points p1(320,16) and p2(1920,256) */
padding: 0 calc(15vw - 2rem);
}
.container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 18px;
max-width: ;
min-height: 100vh;
}
.container--example {
background-color: #000;
width: 100%;
height: 100px;
}
<div class="container">
<div class="container--example"></div>
<div class="container--example"></div>
</div>

How can I center this iframe inside of its parent after using transform: scale, and transform: origin?

I'm trying to shrink down an iframe that contains one of my other websites, but I want to maintain the scale and center it. Right now I have the scaling part figured out, but I can't seem to get it centered.
I've tried flex with justify-items: center & align-items: center on its parent, but it stays glued to the top left. I've also tried margin: auto which does nothing, but when I add margin-left it moves over a bit. If the parent has 100% width, and there is margin available, why wouldn't margin: auto center it? I'm confused.
Here's the html/jsx:
import './Desktop.css';
import desktopMockup from '../../assets/desktop.png';
const Desktop = ({ site }) => {
const
return (
<div className="desktop">
<div className="iframeDesktop">
<iframe src={site} scrolling="no" title="desktop" width="1920" height="1080"></iframe>
</div>
{/* <img src={desktopMockup} alt="desktop mockup" /> */}
</div>
);
};
export default Desktop;
And here's the css:
.desktop {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-items: center;
align-items: center;
}
.iframeDesktop {
position: relative;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-items:center;
}
iframe {
position: absolute;
top: 0;
right: 0;
left: 0;
bottom: 0;
transform: scale(0.17);
transform-origin: top left;
min-width: 1920px;
min-height: 1080px;
}
I wonder if you could use transform-origin: top center; instead of transform-origin: top left;. Could you give that a try?

Image in flexbox column not rendering properly in Chrome

I have a div with one image and one paragraph in it.
<div id="container">
<img src="..." />
<p>
This is my text
</p>
</div>
I use flex-box and flex-direction: column to align them.
#container {
display: flex;
flex-direction: column;
height: 300px;
width: 400px;
}
img {
max-width: 80%;
flex-basis: 50%;
}
p {
flex-basis: 50%;
}
Since both img and p have flex-basis 50% I would expect each of them to take up 50% of the space. In Firefox it works, but in Chrome the image is bigger (in height) than the container itself.
I have made a jsfiddle to demonstrate this: https://jsfiddle.net/q2esvro9/1/
How can I get the behaviour from Firefox in Chrome?
(Another interesting fact: In Internet Explorer 11 the image and text take up the same space, but the image is stretched in width. Which means 3 different behaviours for a very short and simple CSS code)
#container {
display: flex;
align-items: center;
align-content: center;
text-align: center;
flex-direction: column;
border: solid 2px red;
height: 300px;
width: 400px;
}
img {
max-width: 80%;
flex-basis: 50%;
}
p {
flex-basis: 50%;
border: solid 2px green;
}
<div id="container">
<img src="https://image.freepik.com/free-icon/apple-logo_318-40184.jpg" />
<p>
This is my text
</p>
</div>
There are flexbox rendering variations between the major browsers.
When dealing with images, the number of variations grows.
What I've found to work consistently across browsers is to not use img elements in a flex formatting context (i.e., don't make them flex items).
Instead, wrap an img in a div element, making the div the flex item and keeping the image in a block formatting context.
#container {
display: flex;
align-items: center;
align-content: center;
text-align: center;
flex-direction: column;
border: solid 2px red;
height: 300px;
width: 400px;
}
#container > div {
flex: 0 0 50%; /* 1 */
min-height: 0; /* 2 */
}
img {
height: 100%;
}
p {
flex-basis: 50%;
border: solid 2px green;
}
<div id="container">
<div>
<img src="https://image.freepik.com/free-icon/apple-logo_318-40184.jpg" />
</div>
<p>
This is my text
</p>
</div>
Notes:
The meaning and benefits of flex: 1
Why don't flex items shrink past content size?

Aligning flex items horizontally in a vertical flex container

I can't figure out for the life of me how to make this page work.
I'm trying to have the "Top" be a header, the "Bottom" be the footer, and "table" and "section" be two separate columns in between.
Although I can't figure it out. Thanks.
html {
height: 100%;
}
body {
display: flex;
height: 100%;
justify-content: flex-start;
align-content: flex-start;
flex-direction: column;
flex-wrap: wrap;
margin: 0;
}
#pageTop {
background-color: lightgrey;
padding-left: 1em;
padding-top: .5em;
flex-grow: 1;
}
#table {
background-color: blue;
width: 50%;
flex-grow: 8;
flex-shrink: 1;
}
#pageSection {
background-color: lightpink;
width: 50%;
flex-flow: 8;
flex-shrink: 1;
}
#pageBot {
flex-grow: 1;
background-color: grey;
}
<body>
<div id="pageTop">Top</div>
<nav id="table">table</nav>
<div id="pageSection">section</div>
<div id="pagebot">Bottom</div>
</body>
Like Micheal_B stated:
Wrap the #table and the #section in one container. That container becomes the second flex item in the parent flex container. Then add display: flex to the new container.
Changes
Added main#pageContent to body and wrapped it around nav#table and section#pageSection
Added display: flex, justify-content: center, and flex: 2 0 auto
Changed all flex-grow and flex-shrink to flex shorthand.
ex. flex: 0 1 auto = flex-grow: 0 flex-shrink: 1 flex-basis: auto
note. The ruleset above is default for all flex children.
Removed align-content and justify-content; and changed the value of flex-wrap from wrap to nowrap; and added overflow:hidden and width: 100% to normalize a little.
Added width: 100% to everything with the exception of #pageSection and #table.
Added height: 2em to #pageTop and #pageBot(BTW, corrected typo)
Changed all of the tags to it's semantic equivalents.
main#pageContent
Height is set up to take up the freespace that the footer and header leave by height: calc(100% - 4em). This probably overkill since it also has flex: 2 0 auto.
It is a flex container (flex: display) and a flex child (flex: 2 0 auto)
section#pageSection
overflow-x: hidden will prevent any content from busting out of the borders sideways. overflow-y:auto will accommodate any content that extends the bottom border by adding a scrollbar. I have added content (a few <p>) to demonstrate.
SNIPPET
html {
height: 100%;
width: 100%;
}
body {
display: flex;
height: 100%;
width: 100%;
flex-direction: column;
flex-wrap: nowrap;
margin: 0;
overflow: hidden;
}
#pageContent {
width: 100%;
height: calc(100% - 4em);
display: flex;
justify-content: center;
flex: 2 0 auto;
}
#pageTop {
width: 100%;
height: 2em;
background-color: violet;
padding-left: 1em;
padding-top: .5em;
flex: 0 0 auto;
}
#table {
background-color: cornflowerblue;
width: 50%;
flex: 0 0 auto;
}
#pageSection {
background-color: darksalmon;
width: 50%;
flex: 1 0 auto;
overflow-x: hidden;
overflow-y: auto;
}
#pageBot {
width: 100%;
height: 2em;
flex: 0 0 auto;
background-color: gold;
}
<body>
<header id="pageTop">Top</header>
<main id='pageContent'>
<nav id="table">table</nav>
<section id="pageSection">
<p>One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin.</p>
<p>He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections. The bedding was hardly able to cover it and seemed ready to slide off any moment.</p>
<p>His many legs, pitifully thin compared with the size of the rest of him, waved about helplessly as he looked. "What's happened to me? " he thought. It wasn't a dream.</p>
<p>His room, a proper human room although a little too small, lay peacefully between its four familiar walls.</p>
<p>A collection of textile samples lay spread out on the table - Samsa was a travelling salesman - and above it there hung a picture that he had recently cut out of an illustrated magazine and housed in a nice, gilded frame. It showed a lady fitted
out with a fur hat and fur boa who sat upright, raising a heavy fur muff that covered the whole of her lower arm towards the viewer. Gregor then turned to look out the window at the dull weather. Drops</p>
</section>
</main>
<footer id="pageBot">Bottom</footer>
</body>
Add a div with flex row, as it (adjust cols width with width attribute):
html {
height: 100%;
}
body {
display: flex;
height: 100%;
justify-content: flex-start;
align-content: flex-start;
flex-direction: column;
flex-wrap: wrap;
margin: 0;
}
#pageTop {
background-color: lightgrey;
padding-left: 1em;
padding-top: .5em;
}
#mainContainer {
display: flex;
flex-direction: row;
}
#table {
background-color: blue;
width: 50%;
}
#pageSection {
background-color: lightpink;
width: 50%;
}
#pagebot {
background-color: grey;
}
<body>
<div id="pageTop">Top</div>
<div id="mainContainer">
<nav id="table">table</nav>
<div id="pageSection">section</div>
</div>
<div id="pagebot">Bottom</div>
</body>
PS: I also fixed a pagebot/pageBot variant. Be aware, CSS is case-sensitive.

Resources