flexbox space-evenly not spacing evenly - css

I have the following snippet and am wondering why the spacing between the first three elements is not the same as the spacing between the the 3rd and 4th
.textFMT2 {
display: flex;
flex-direction: column;
justify-content: space-evenly;
align-items: center;
height: 100vh;
font-size: 1.5vw;
}
.links4 {
width: 100%;
}
.links4 span {
display: block;
background-color: #538231;
text-align: center;
width: 50%;
border-radius: 10vw;
padding: 1vw 0;
margin: 0 auto;
}
span {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
vertical-align: baseline;
}
.textFMT2 .arrowsForScroll {
position: relative;
}
.arrowsForScroll {
position: absolute;
bottom: 2vw;
}
.arrowsForScroll {
display: flex;
justify-content: space-evenly;
align-items: center;
width: 100%;
}
a.left, a.right {
text-decoration: none;
font-weight: bolder;
font-size: 32px;
}
.left, .right {
display: none;
}
.sections {
background-color: #b3d7f7;
/* width: 32vw; */
color: #538231;
font-size: 16px;
text-align: center;
position: relative;
height: 100%;
}
.links4 a {
text-decoration: none;
color: white;
}
<div class="textFMT2">
<div class="links4">
<span>Sign up for our<br>Quarterly Newsletter</span>
</div>
<div class="links4">
<span>Attend an<br>Event</span>
</div>
<div class="links4">
<span>Volunteer with<br>SWAG</span>
</div>
<div class="arrowsForScroll">
<a class="left" href="#section2"><!--↑--> </a>
<div class="links4">
<span>Donate to help<br>our work</span>
</div>
<a class="right" href="#"> </a>
</div>
</div>

The different gap size is created because you are setting the position to relative here:
.textFMT2 .arrowsForScroll {
position: relative;
}
An element with position: relative; is positioned relative to its normal position.
Setting the top, right, bottom, and left properties of a relatively-positioned element will cause it to be adjusted away from its normal position. Other content will not be adjusted to fit into any gap left by the element.
So you need to explictly set it to static
.textFMT2 .arrowsForScroll {
position: static;
}
Static positioned elements are not affected by the top, bottom, left, and right properties.
An element with position: static; is not positioned in any special way; it is always positioned according to the normal flow of the page
EDIT: The entire issue stems from having a flex item set to position: absolute in .arrowsForScroll (which is defined twice by the way), I assume you wrote the selector .textFMT2 .arrowsForScroll to compensate for that. So the layout could also be fixed by simply removing these two selectors entirely:
.textFMT2 .arrowsForScroll {
position: relative;
}
.arrowsForScroll {
position: absolute;
bottom: 2vw;
}

Related

Making an element sticky at both the top and center

I have a page that overflows the viewport both horizontally and vertically, and I'd like to sticky a nav so that it is always at the top and horizontally centered.
Right now, I can get sticky top working, but the centering does not work. Can anyone help?
body {
text-align: center;
}
#header {
background-color: yellow;
width: max-content;
position: sticky;
top: 0;
left: 50%;
translate: -50%
}
#container {
background-color: black;
color: white;
width: 200vw;
height: 200vh;
display: flex;
justify-content: center;
align-content: center;
flex-direction: column;
}
<div id="header">
I should always be at the top and centered
</div>
<div id="container">
<span>
I am extremely large and wide
</span>
</div>
CodePen: https://codepen.io/hbchin/pen/bGjpQLJ
After doing some digging I found this:
Why is my element not sticking to the left when using position sticky in css?
Essentially, it's not sticking because the body is automatically expanding to the width of the size of the very big box.
Putting it in an inline-block container will make the width not auto-expand to children, and thus allow sticking behavior.
So this works:
body {
text-align: center;
}
#header {
background-color: yellow;
width: max-content;
position: sticky;
top: 0;
left: 50%;
translate: -50%
}
#container {
background-color: black;
color: white;
width: 200vw;
height: 200vh;
display: flex;
justify-content: center;
align-content: center;
flex-direction: column;
}
#whole-thing {
display: inline-block;
}
<div id="whole-thing">
<div id="header">
I should always be at the top and centered
</div>
<div id="container">
<span>
I am extremely large and wide
</span>
</div>
</div>
Unlike position: sticky and vertical positioning, left: 50% isn't a dynamic positioning option; it just sets the initial position. A horizontal scrollbar will still cause it to move, so that it remains "50% from the left edge".
To achieve a fixed left-right position, add a header container with position: fixed around your header, and within that, your header div can get auto margins:
body {
text-align: center;
max-width:100vw;
overflow:scroll;
}
/*added*/
#headercontainer{
position:fixed;
width:100vw;
left:0;
top:0;
}
#header {
background-color: yellow;
width: max-content;
/*left: 50%;*/ /*Removed*/
margin:auto;/*added*/
}
#container {
background-color: black;
color: white;
width: 200vw;
height: 200vh;
display: flex;
justify-content: center;
align-content: center;
flex-direction: column;
}
<div id="headercontainer"> <!-- added -->
<div id="header">
I should always be at the top and centered
</div>
</div>
<div id="container">
<span>
I am extremely large and wide
</span>
</div>
You mean something like this?:
<div id="header-container">
<div id="header">
I should always be at the top and centered
</div>
</div>
<div id="container">
<span>
I am extremely large and wide
</span>
</div>
body {
text-align: center;
}
#header-container {
position: fixed;
top: 0;
left: 0;
right: 0;
height: 20px;
overflow: auto;
background-color: yellow;
}
#header {
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: max-content;
}
#container {
background-color: black;
color: white;
width: 200vw;
height: 200vh;
display: flex;
justify-content: center;
align-content: center;
flex-direction: column;
}

Overlay for a grid item

I am using React and I am trying to have an overlay over each grid item in a grid. But, what all I try, the overlay seems to come below each grid item and not over the grid item. Even if I use the position: absolute it is not working !
Here's the code I am using for the grid (React):
<div className="home__itemSection">
<div className="item">
<div className="item__container">
<div className="container__imageDiv">
<img
src={""}
alt=""
/>
</div>
<div className="container__detailSection">
<p>{""}</p>
<h6>{""}</h6>
</div>
</div>
<div className="item__overlay">
<h1>{""}</h1>
<h1>{""}</h1>
</div>
</div>
</div>
css:
.home__itemSection {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
margin: 30px 170px 0 170px;
transition: ease all 0.5s;
}
.item {
background-color: #f1f1f1;
height: 350px;
width: 212px;
margin: 0 3rem 1rem 3rem;
height: fit-content;
font-family: "Poppins", sans-serif;
display: flex;
align-items: flex-start;
}
.container__imageDiv {
height: 318px;
width: 212px;
}
.container__imageDiv > img {
height: 318px;
width: 212px;
}
.container__detailSection {
height: 44px;
width: 212px;
display: flex;
flex-direction: column;
align-items: flex-start;
padding-top: 5px;
}
.container__detailSection > p {
color: black;
font-size: 13px;
font-weight: 300;
line-height: initial;
}
.container__detailSection > h6 {
padding-left: 1.8rem;
font-weight: 500;
font-size: 1rem;
}
.item__overlay {
height: 252px;
width: 212px;
background-color: black;
}
Any help is greatly appreciated !
Thank You !
Please add position: relative; on item(parent tag of overlay)
.item{
position: relative;
}
.item .item__overlay{
position: absolute;
left: 0;
top: 0;
}
An element with position absolute is relative to the next parent element with relative (or absolute) positioning.
Add position relative to home__itemSection. Also use height and with to cover all the container:
.home__itemSection {
...
position: relative;
}
.item__overlay {
...
position: absolute;
height: 100%;
width: 100%;
}

img "glued" to the division on hover. How to make it appear elsewhere while maintaining the relation

I'm awfully new to the whole game and approach problems pretty much everyday. Most of the time I solve them with google, learning a lot, but this time I can't find anything.
So, I've got this lovely header that moves to the right and makes some space for another element. I'd like this element (the bonobo head) to appear when I hover over the header.
So, I set the display of the image to none, and block on header:hover, but the image seems glued to the header.
I would like it to appear next to it, in any given location. What do ?
.header {
position: relative;
display: block;
left: 0%;
padding: 15px;
background-color: #54e954;
text-align: center;
width: 100%;
height: auto;
transition: 2s;
border-radius: 8px;
}
.header:hover {
left: 15%;
background-color: #d0f307;
}
.photo {
position: relative;
display: none;
}
.header:hover .photo {
display: block;
}
<div class="header">
<h1 class="h1header">Lorem Ipsum</h1>
<div>
<img src="https://upload.wikimedia.org/wikipedia/commons/4/4b/Bonobo-Head.jpg" class="photo">
</div>
</div>
Is that what you want it to look like ? If you want this, I did it using the display flex structure.
.header {
position: relative;
display: flex; /* added */
justify-content: center;
align-items: center;
left: 0%;
padding: 15px;
background-color: #54e954;
text-align: center;
width: 100%;
height: auto;
transition: 2s;
border-radius: 8px;
}
.header:hover {
left: 15%;
background-color: #d0f307;
}
.photo {
position: relative;
display: none;
}
.header:hover .photo {
display: block;
}
<div class="header">
<h1 class="h1header">Lorem Ipsum</h1>
<div class="img-container">
<img src="https://upload.wikimedia.org/wikipedia/commons/4/4b/Bonobo-Head.jpg" class="photo">
</div>
</div>
Updated : With Javascript, you can better control hover and hoverout operations. Here's an example I've prepared for you. By the way, I had to get the img tag out of the header tag. You can see the additions I've made.
let header = document.querySelector(".header");
let imageContainer = document.querySelector(".img-container");
header.onmouseover = function() {
imageContainer.classList.add("showImage");
}
header.onmouseout = function() {
imageContainer.classList.remove("showImage");
}
.header {
position: relative;
display: flex;
/* added */
justify-content: center;
align-items: center;
left: 0%;
padding: 15px;
background-color: #54e954;
text-align: center;
width: 100%;
height: 80px;
transition: 1s;
border-radius: 8px;
}
.header:hover {
transform: translateX(15%);
/* added*/
background-color: #d0f307;
}
.img-container {
position: relative;
display: none;
}
.img-container.showImage {
position: relative;
display: block;
}
.container {
display: flex;
justify-content: space-between;
}
<div class="container">
<div class="img-container">
<img src="https://upload.wikimedia.org/wikipedia/commons/4/4b/Bonobo-Head.jpg" class="photo">
</div>
<div class="header">
<h1 class="h1header">Lorem Ipsum</h1>
</div>
</div>

Why does ::after appear for all divs?

I want to have a top arrow for a drawer and to do so used ::after for the menu div. However it appears for all div inside menu div.
I have a div with class drawer and for that added top arrow. within drawer div have details div which contains svg, span and div element.
Now this css in ::after applies to div within details div as well.
How can I fix it? I don't want it to appear anywhere else apart for the menu div.
Below is the code:
.drawer {
display: flex;
flex-direction: column;
position: absolute;
width: 392px;
top: 55px;
right: 8px;
min-height: 40%;
max-height: 450px;
margin-left: 16px;
::after {
content: " ";
position: absolute;
bottom: 100%;
left: 83%;
margin-left: -5px;
border-width: 14px;
border-style: solid;
}
}
.item {
display: flex;
flex-direction: row;
font-size: 12px;
padding: 8px;
min-height: 49px;
li {
list-style: none;
}
.details {
display: flex;
flex-grow: 1;
color: #333;
margin-right: 4px;
}
}
<div class="drawer">
<ul>
<li class="item">
<div class="details">
<svg/>
<span>sometext</span>
<div>
<div/><img/>
</div>
</div>
</li>
</ul>
</div>

Auto vertical align any auto sized image

I can't find an answer that is not on a fixed image size so I'm going to ask it.
I have a div with an image in it and that picture could be any size. I need it to auto scale AND auto align. I can scale it fine but vertically aligning it is a bit of a challenge. I need it to be center vertically aligned.
HTML + CSS
<div id="myDiv">
<img src="./img/example.png"></img>
</div>
#myDiv {
position: absolute;
height: 100%;
width: 100%;
top: 0%;
left: 0%;
text-align: center;
}
#myDiv img {
height: auto;
width: auto;
max-height: 70%;
max-width: 70%
}
This example forces both horizontal and vertical alignment of an image inside a box; in this specific case, constrained to 130x130px. Change the width and height defined as 130px in 2 separate places each in the css to change the constrained size.
[edit: added simplified example showing minimum required setup]
Simplified example:
html:
<div class="pic">
<img src="/path/to/pic.jpg"/>
</div>
css:
.pic {
display: inline-block;
width: 130px;
height: 130px;
outline: solid 1px #cccce3;
font-size: 0;
text-align: center;
}
.pic:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
}
.pic img {
max-width: 130px;
max-height: 130px;
display: inline-block;
vertical-align: middle;
}
Complete example:
Original codepen showing more complex example: http://codepen.io/anon/pen/culvD .
Here's the html:
<ul class="pics">
<li>
<div class="pic">
<img src="/path/to/pic1.jpg"/>
</div>
</li>
<li>
<div class="pic">
<img src="/path/to/pic2.jpg"/>
</div>
</li>
</ul>
and here's the css:
ul.pics {
margin: 0;
padding: 0;
list-style-type: none;
text-align: center;
}
ul.pics li {
display: inline-block;
width: 130px;
margin: 4px;
padding: 6px;
background-color: #e6e6ec;
outline: solid 1px #cccce3;
}
ul.pics li .pic {
height: 130px;
font-size: 0;
text-align: center;
}
ul.pics li .pic:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
}
ul.pics li img {
max-width: 130px;
max-height: 130px;
display: inline-block;
vertical-align: middle;
}
to center align an element to the center asign it a width, then margin-left and right to auto.

Resources