How to make square divs shrink instead of hide when resizing screen? - css

I have a collection of a couple of divs (called buttons) inside a div container.
When attempting to resize the screen to check for responsiveness, (trying to keep them centered in the middle of the screen) instead of shrinking, the buttons FIRST get clipped from (or hide behind) both sides of the screen.
here is my code:
.button {
outline: 1px solid black;
min-width: 0;
min-height: 0;
width: 10rem;
height: 10rem;
flex: 1 0 1rem;
}
.container {
display: flex;
align-items: center;
justify-content: center;
}
.parentContainer {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
Below are the global styles:
html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
display: flex;
justify-content: center;
}
The html is made using components:
<div className={parentContainer}>
<div className={container}>
<HeaderButton />
<HeaderButton />
<HeaderButton />
<HeaderButton />
<HeaderButton />
<HeaderButton />
</div>
</div>
The header button component:
const Button = () => {
return (
<div className={button}>
<h1>{props.text}</h1>
</div>
)
}
export default Button;
Any idea how I might achieve what I'm aiming for?
Thank you for the help.

That's most probably due to the buttons having fixed width.
I'd suggest adding a responsive variant for the .container
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
#media only screen and (min-width: 600px) {
.container {
flex-direction: row;
}
}
This will make the buttons fall one below the other.

Please use flex-wrap: wrap
.container {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.item {
width: 100px;
height: 50px;
margin: 5px;
background: #000000;
}
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>

Use display flex for responsiveness and percentages for element widths:
body{
width:100%;
height: 100vh;
display:flex;
justify-content: center;
align-items: center;
}
.container{
width:100%;
height:100px;
display:flex;
justify-content: center;
align-items: center;
flex-direction: row;
flex-wrap: wrap;
}
.d1,.d2,.d3,.d4,.d5{
width:100px;
height:100px;
border:2px solid black;
}
<div class="container">
<div class="d1"></div>
<div class="d2"></div>
<div class="d3"></div>
<div class="d4"></div>
<div class="d5"></div>
</div>

Ok so first I'd like to thank everyone for their responses, but the solution that I needed was in fact aspect-ratio:
.button {
width: 80%;
aspect-ratio: 1 / 1;
}
.container {
display: flex;
align-items: center;
justify-content: center;
margin-top: 5%;
width: 90vw;
gap: 3.5%;
}

Related

How to control the space between flex items

I'm just doing some learning material on Codeacademy and I'm wanting to know how to control the space between the "locations" text and the three divs below. The assignment is asking me to create a 15px space between them but I don't know how to do that. Currently, there is just a default space that I don't know how is calculated.
html {
text-align: center;
}
.location-container {
background-image: url(https://content.codecademy.com/courses/freelance-1/unit-4/img-locations-background.jpg);
height: 700px;
width: 1200px;
display: flex;
justify-content: center;
align-content: center;
flex-wrap: wrap;
}
#local {
background-color: blueviolet;
}
.location-columns {
display: flex;
justify-content: center;
width: 100%;
gap: 30px;
color: white;
}
.locations {
background-color: black;
width: 300px;
}
<div class="location-container">
<h2 id="local">Locations</h2>
<div class="location-columns">
<div class="locations">
<h3>Downtown</h3>
<h5>384 West 4th St</h5>
<h5> Suite 108</h5>
<h5>Portland, Maine</h5>
</div>
<div class="locations">
<h3>East Baysuide</h3>
<h5>3433 Phisermans Avenue</h5>
<h5>(Northwest Corner)</h5>
<h5>Portland, Maine</h5>
</div>
<div class="locations">
<h3>Oakdale</h3>
<h5>515 Crescent Avenue</h5>
<h5> Second Floor</h5>
<h5>Portland, Maine</h5>
</div>
</div>
Thanks for any insights.
Heading elements come with large upper and lower margins right from the default browser styles.
You can remove those for elements inside .locations, make it a flex container and use row-gap to control vertical spacing:
html {
text-align: center;
}
.location-container {
background-image: url(https://content.codecademy.com/courses/freelance-1/unit-4/img-locations-background.jpg);
height: 700px;
width: 1200px;
display: flex;
justify-content: center;
align-content: center;
flex-wrap: wrap;
}
#local {
background-color: blueviolet;
}
.location-columns {
display: flex;
justify-content: center;
width: 100%;
gap: 30px;
color: white;
}
.locations {
background-color: black;
display: flex;
flex-direction: column;
row-gap: 30px;
padding: 30px;
width: 300px;
}
.locations>* { margin: 0; }
<div class="location-container">
<h2 id="local">Locations</h2>
<div class="location-columns">
<div class="locations">
<h3>Downtown</h3>
<h5>384 West 4th St</h5>
<h5> Suite 108</h5>
<h5>Portland, Maine</h5>
</div>
<div class="locations">
<h3>East Baysuide</h3>
<h5>3433 Phisermans Avenue</h5>
<h5>(Northwest Corner)</h5>
<h5>Portland, Maine</h5>
</div>
<div class="locations">
<h3>Oakdale</h3>
<h5>515 Crescent Avenue</h5>
<h5> Second Floor</h5>
<h5>Portland, Maine</h5>
</div>
</div>

i need to change to layout of the buttons and the counter

counter.js
import "./Counter.css";
const Counter = (props) => {
return (
<div className="counter">
<h1>{`Counter ${props.count}`}</h1>
<div className="counter__buttons">
<button onClick={props.incrementCounter}>Increment</button>
<button onClick={props.decrementCounter}>Decrement</button>
</div>
</div>
);
};
Counter.css
.counter {
display: flex;
color: white;
align-items: center;
width: 100%;
height: 100%;
}
.counter > .counter__buttons > button {
color: black;
background-color: grey;
margin: 10px;
padding: 30px;
border: 0;
border-radius: 10px;
}
i want to move the buttons below counter and place the counter and buttons in the center of the page how to change it , display : flex in counter should not be removed
Would something like this work? You can set the flex-direction of a wrapping div to column and set the second div (in your case your buttons) back to flex-direction: row and finally just center it with margin: 0 auto.
<div id="wrap">
<div id="one">1</div>
<div id="two">2
<div id="three">3</div>
<div id="four">4</div>
</div>
</div>
#wrap {
display: flex;
flex-direction: column;
}
#two {
display: flex;
flex-direction: row;
margin: 0 auto;
}
Do you want something like this?
.page {
background: black;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100vh;
}
.counter {
display: flex;
flex-direction: column; /* add this */
color: white;
align-items: center;
/* width: 100%;*/
/* height: 100%;*/
}
.counter > .counter__buttons > button {
color: black;
background-color: grey;
margin: 10px;
padding: 30px;
border: 0;
border-radius: 10px;
}
<div class="page">
<div class="counter">
<h1>Counter 5</h1>
<div class="counter__buttons">
<button onClick={props.incrementCounter}>Increment</button>
<button onClick={props.decrementCounter}>Decrement</button>
</div>
</div>
</div>
If so, you can make your whole page a flex container and use justify-content and align-items just like you did it for the .counter.
(I did HTML instead of JSX so I could add the snippet easier... don't forget to make changes in your own code)

Breaking a line with flexbox centering?

I'm trying to vertically/horizontally center my Title with the Subtitle directly beneath it. Here was my attempt:
html, body, h1 {
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100%;
}
#container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
<div id="container">
<h1>Main Title</h1>
<span>Subtitle</span>
</div>
As you can see, the subtitle is in the same line as the h1, I'm trying to get it to go beneath it. I've tried setting h1 to display: block; but that seems to not work when using display: flex on the container. Any help would be appreciated.
Set flex-direction: column on container
html, body, h1 {
margin: 0;
padding: 0;
}
html, body {
width: 100%;
height: 100%;
}
#container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100vh;
}
<div id="container">
<h1>Main Title</h1>
<span>Subtitle</span>
</div>
Setting flex-direction to column is one solution. It's already provided in another answer.
In some cases, if flex-direction: row is preferred (or a necessity), you can add flex-wrap: wrap to the container and give the first item a 100% width, which forces the second item to the next line.
body, h1 {
margin: 0;
padding: 0;
}
#container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
flex-wrap: wrap; /* NEW */
align-content: center; /* NEW */
text-align: center; /* NEW */
}
h1 { flex: 0 0 100%; } /* NEW */
<div id="container">
<h1>Main Title</h1>
<span>Subtitle</span>
</div>

Line height or vertical align in flexbox child

Minimal working example: http://jsfiddle.net/3qxfknd7/
You can see that the A and B are both centered horizontally within their respective divs, but not vertically. The height is dynamic, and thus I cannot set the line-height to the font-size, because a button with larger font-size will have to determine the line-height. Next to that, the class large may or may not be present: I cannot assume it is present!
How am I going to do this?
<div class="button-group">
<div class="button"><span>A</span></div>
<div class="button"><span class="large">B</span></div>
</div>
.button-group {
display: flex;
flex-flow: row nowrap;
align-content: flex-start;
justify-content: flex-start;
}
.button {
flex: 1 0 auto;
text-align: center;
outline: 1px solid red;
}
.button span {
font-size: 20px;
}
.button span.large {
font-size: 40px;
}
Not sure if this is what you are after:
.button-group {
display: flex;
flex-flow: row nowrap;
}
.button {
display:flex;
align-items: center;
flex: 1 0 auto;
align-content: center;
justify-content: center;
outline: 1px solid red;
}
.button span {
font-size: 20px;
}
.button span.large {
font-size: 40px;
}
<div class="button-group">
<div class="button"><span>A</span></div>
<div class="button"><span class="large">B</span></div>
</div>

Stacked flexbox vertical centering not working in chrome

The following situation doesn't work in Google Chrome;
<div class="flex-container">
<div class="flex-item">
<div>
<div>
<h2>This is a test</h2>
</div>
</div>
</div>
<div class="flex-item">
<div>
<div>
<h2>This is a test</h2>
</div>
</div>
</div>
<div class="flex-item">
<div>
<div>
<h2>This is a test</h2>
</div>
</div>
</div>
</div>
SCSS
body,html {
height:100%;
background:#1D1F20;
font-family:sans-serif;
color:#fff;
}
.flex-container {
display: flex;
flex-direction: column;
align-items: center;
height:100%;
.flex-item {
flex: 1 1 auto;
align-self: center;
background:#87BEB7;
padding:0 10px;
&:nth-child(2) {
background:#ADBEBC;
}
&:nth-child(3) {
background:#BE8A74;
}
> div {
display: flex;
justify-content: center;
align-items: flex-start;
height:100%; // This seems to be the issue
div {
flex: 0 1 auto;
align-self: center;
background:#5C726F;
padding:10px
}
}
}
}
I would expect the second flexbox-container (.flex-item > div) to be the full height of the flex-child (.flex-item) but it doesn't seem to work. (chrome only)
The workaround I have involves using position absolute, but i'd rather not use it.
Codepen: http://codepen.io/anon/pen/QwpzLX
Open in Firefox to see the desired result and in Chrome to see the current situation.
Any help or suggestions would be appreciated.
Here is the working scss:
.flex-container {
display: flex;
flex-direction: column;
align-items: center;
height:100%;
.flex-item {
flex: 1 1 auto;
align-self: center;
background:#87BEB7;
padding:0 10px;
display: flex;
&:nth-child(2) {
background:#ADBEBC;
}
&:nth-child(3) {
background:#BE8A74;
}
> div {
display: flex;
justify-content: center;
align-items: flex-start;
div {
flex: 0 1 auto;
align-self: center;
background:#5C726F;
padding:10px
}
}
}
}
You have to set display:flex; to .flex-item and remove the height: 100%.
Here is the demo: http://jsfiddle.net/omgL91r8/1/

Resources