Why my 100vw element has a strange left gap? - css

I have a box with three elements, and I also need a full-width of viewport element which place inside item 2
This is pen which show this problem https://codepen.io/in-in/pen/Nwxoar
I’m talking about the purple element (after), and I expect it to occupy the full-width of viewport but it has a strange left margin (41px)
.container {
width: 800px;
height: 100vh;
margin-left: auto;
margin-right: auto;
background-color: tan;
}
.box {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
width: 100%;
height: 80px;
background-color: deeppink;
}
.box__item1 {
flex-basis: 200px;
background-color: dodgerblue;
}
.box__item2 {
position: relative;
flex-basis: 500px;
background-color: coral;
}
.box__item2::after {
position: absolute;
top: 100%;
left: 0;
right: 0;
width: 100vw;
height: 100%;
margin-left: calc(50% - 50vw);
content: "after";
background-color: blueviolet;
outline: 1px solid red;
}
.box__item3 {
flex-basis: 100px;
background-color: seagreen;
}
<div class="container">
<div class="box">
<div class="box__item1"><span>item 1</span></div>
<div class="box__item2"><span>item 2</span></div>
<div class="box__item3"><span>item 3</span></div>
</div>
</div>

The .box__item2 element has a relative position. I moved the position property to the .container element and added a top: 80px and set the height: 80px forafter.
.container {
width: 800px;
height: 100vh;
margin-left: auto;
margin-right: auto;
background-color: tan;
position: relative;
}
.box {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
width: 100%;
height: 80px;
background-color: deeppink;
}
.box__item1 {
-ms-flex-preferred-size: 200px;
flex-basis: 200px;
background-color: dodgerblue;
}
.box__item2 {
-ms-flex-preferred-size: 500px;
flex-basis: 500px;
background-color: coral;
}
.box__item2::after {
position: absolute;
top: 80px;
left: 0;
width: 100vw;
height: 80px;
margin-left: calc(50% - 50vw);
content: "after";
background-color: blueviolet;
outline: 1px solid red;
}
.box__item3 {
-ms-flex-preferred-size: 100px;
flex-basis: 100px;
background-color: seagreen;
}
<div class="container">
<div class="box">
<div class="box__item1"><span>item 1</span></div>
<div class="box__item2"><span>item 2</span></div>
<div class="box__item3"><span>item 3</span></div>
</div>
</div>
link: https://codepen.io/greensleeves/pen/gXrOQx

Related

CSS image, object-fit: contain, margin: auto and percentage?

I'm looking for an alternative to this css code, which is working as expected on chrome, but not on firefox.
The pins are not keeping their position when the viewport size is different. You can resize (height and width) the viewport on jsfiddle on chrome to see what I expect and on firefox to see what I don't.
I guess there is something between margin: auto and object-fit: contain which is not calculated the same way...
Chrome margin from devtools
Firefox margin from devtools
I know that I can do it in javascript but i'd like to know if it's possible with css !
<div class="site">
<div class="wrapper">
<div class="title">TITLE</div>
<div class="subtitle">Subtitle</div>
<div class="container">
<div class="img-wrapper">
<img src="./img.jpg" alt="">
</div>
<div class="pin-container">
<div class="pin pin1">?</div>
<div class="pin pin2">?</div>
<div class="pin pin3">?</div>
<div class="pin pin4">?</div>
</div>
</div>
</div>
</div>
.site{
position: relative;
width: 100%;
height: 80vh;
display: flex;
flex-direction: column;
margin: 0 auto;
max-width: 960px;
border: 1px solid blue;
}
.wrapper{
display: flex;
flex-direction: column;
}
.container{
position: relative;
border-radius: 6px;
margin: auto;
}
.img-wrapper{
height: 100%;
}
.img-wrapper img{
width: 100%;
height: 100%;
object-fit: contain;
}
.pin-container{
position: absolute;
color: red;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.pin{
position: absolute;
background-color: white;
width: 20px;
height: 20px;
border-radius: 50%;
text-align: center;
transform: translate(-50%, -50%);
}
.pin1 {
top: 50%;
left: 24%;
}
.pin2 {
top: 30%;
left: 52%;
}
.pin3 {
top: 87%;
left: 79%;
}
.pin4 {
top: 100%;
left: 100%;
}
https://jsfiddle.net/MathieuSP/8u3gLz4q/
Thank you ! :)
I think it's because of display: flex in the .wrapper.
The flex-box itself will always keep the content to fit inside so it will shrink your image down or scale it up.
You can use flex: 1 to keep the image from being change (you can read more about it here) and set the aspect-ratio to keep width and height of the image consistent. Just set it in the .container
.container {
position: relative;
border-radius: 6px;
margin: auto;
flex: 1;
aspect-ratio: 1.5;
}
Here is the snippet, hope this can help you
* {
margin: 0;
overflow: hidden;
box-sizing: border-box;
}
body{
height: 100vh;
width: 100vw;
color: white;
background-color: black;
}
.title{
text-align: center;
padding: 2rem 0;
font-size: 2rem;
}
.subtitle{
text-align: center;
padding: 1rem 0;
font-size: 1rem;
}
.site{
position: relative;
width: 100%;
height: 80vh;
display: flex;
flex-direction: column;
margin: 0 auto;
max-width: 960px;
border: 1px solid blue;
}
.wrapper{
display: flex;
flex-direction: column;
}
.container{
position: relative;
border-radius: 6px;
margin: auto;
flex: 1;
aspect-ratio: 1.5;
}
.img-wrapper{
height: 100%;
}
.img-wrapper img{
width: 100%;
height: 100%;
object-fit: contain;
}
.pin-container{
position: absolute;
color: red;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.pin{
position: absolute;
background-color: white;
width: 20px;
height: 20px;
border-radius: 50%;
text-align: center;
transform: translate(-50%, -50%);
}
.pin1 {
top: 50%;
left: 24%;
}
.pin2 {
top: 30%;
left: 52%;
}
.pin3 {
top: 87%;
left: 79%;
}
.pin4 {
top: 100%;
left: 100%;
}
<div class="site">
<div class="wrapper">
<div class="title">TITLE</div>
<div class="subtitle">Subtitle</div>
<div class="container">
<div class="img-wrapper">
<img src="https://images.pexels.com/photos/1534057/pexels-photo-1534057.jpeg" alt="">
<div class="pin-container">
<div class="pin pin1">?</div>
<div class="pin pin2">?</div>
<div class="pin pin3">?</div>
<div class="pin pin4">?</div>
</div>
</div>
</div>
</div>
</div>
They are moving because their container size changes bigger than the picture. For such positioning, always put the image and absolute elements in one container with fit-content width and height. and of course relative position If you do so, they will stay in the same spot.
* {
margin: 0;
overflow: hidden;
box-sizing: border-box;
}
body{
height: 100vh;
width: 100vw;
color: white;
background-color: black;
}
.title{
text-align: center;
padding: 2rem 0;
font-size: 2rem;
}
.subtitle{
text-align: center;
padding: 1rem 0;
font-size: 1rem;
}
.site{
position: relative;
width: 100%;
height: 80vh;
display: flex;
flex-direction: column;
margin: 0 auto;
max-width: 960px;
border: 1px solid blue;
}
.wrapper{
display: flex;
flex-direction: column;
}
.container{
position: relative;
border-radius: 6px;
margin: auto;
}
.img-wrapper{
height: 100%;
}
.img-wrapper img{
width: 100%;
height: 100%;
object-fit: contain;
}
.pin-container{
position: absolute;
color: red;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 1px solid red;
}
.pos-container {
border: 3px solid orange;
position: relative;
width: fit-content;
height: fit-content;
}
.pin{
position: absolute;
background-color: white;
color: red;
width: 20px;
height: 20px;
border-radius: 50%;
text-align: center;
transform: translate(-50%, -50%);
}
.pin1 {
top: 50%;
left: 24%;
}
.pin2 {
top: 30%;
left: 52%;
}
.pin3 {
top: 87%;
left: 79%;
}
.pin4 {
top: 100%;
left: 100%;
}
<body>
<div class="site">
<div class="wrapper">
<div class="title">TITLE</div>
<div class="subtitle">Subtitle</div>
<div class="container">
<div class="img-wrapper">
<div class="pos-container">
<img src="https://images.pexels.com/photos/1534057/pexels-photo-1534057.jpeg" alt="">
<div class="pin pin1">?</div>
<div class="pin pin2">?</div>
<div class="pin pin3">?</div>
<div class="pin pin4">?</div>
</div>
</div>
</div>
</div>
</div>
</body>

Set relative positioned image tag to take up 100% of parent div's vertical space

I have an image div that I previously had positioned perfectly by using an absolute positioned image in a relative positioned parent div as is often suggested. I'm in the process of animating that image, and it needs to be relative positioned without a container div in order to animate properly with the method I'm using (GSAP/Motion Path).
I temporarily set the height of my logo to 10vh, since setting height to 100% causes it to take up most of the screen. I also tried setting logo to object-fit: cover and contain, but neither has any effect even if I set width and height to 100%.
Here's what it looks like. I'm trying to center the image with a grey background and have it fill the vertical space of the red div.
Here's my CodePen.
https://codepen.io/TheNomadicAspie/pen/YzVLaMr
And here's my code:
logo.src = "https://i.imgur.com/D9LOkQI.png";
menu_image.src = "https://i.imgur.com/l6GysYf.png";
* {
outline: none;
opacity: 1;
-webkit-box-sizing: border-box;
-mo-box-sizing: border-box;
box-sizing: border-box;
}
html,
body {
position: fixed;
height: 100%;
background-color: blue;
font-size: 2vh;
margin: 0 auto;
font-family: open_sans;
}
.screen {
position: absolute;
height: 100%;
}
.menu-bar {
display: grid;
grid-template-columns: 33.33% 33.33% 33.33%;
position: relative;
height: 13.714%;
width: 100vw;
top: 0%;
text-align: center;
background-color: red;
}
.logo {
grid-column: 1/2;
position: relative;
height: 10vh;
background-color: grey;
}
.title {
grid-column: 2/3;
position: relative;
color: #f5f5f5;
height: 100%;
width: 100%;
margin: 0 auto;
text-align: center;
justify-content: center;
align-items: center;
font-family: hack;
font-size: clamp(2vw, 8vw, 10vh);
display: flex;
top: 0%;
}
.menu-button {
grid-column: 3/4;
position: relative;
height: 100%;
}
.menu-button img {
position: absolute;
height: auto;
max-height: 75%;
max-width: 75%;
left: 50%;
right: 50%;
top: 50%;
bottom: 50%;
transform: translate(-50%, -50%);
}
.display {
position: relative;
height: 86.286%;
width: 100vw;
}
.speech-bubble {
display: grid;
grid-template-rows: 80% 0% 20%;
position: relative;
background-color: #f5f5f5;
height: 61.8%;
width: 90vw;
margin: auto;
border-radius: 2em;
padding-bottom: 1em;
}
<div id="screen" class="screen">
<div id="menu_bar" class="menu-bar">
<img id="logo" class="logo">
<div id="title" class="title">Title</div>
<div id="menu_button" class="menu-button"> <img id="menu_image"> </div>
</div>
<div id="display" class="display">
<div id="speech_bubble" class="speech-bubble">
<div id="logo_animation" class="logo-animation" data-flip-id="logo">
<img id="logo_animation_image">
</div>
</div>
</div>
</div>
</div>
I think you want something like this. I changed a little bit of CSS for logo class.
Hope it will help you out but if you want perfectly aligned navbar I recommend you to use flexbox.
logo.src = "https://i.imgur.com/D9LOkQI.png";
menu_image.src = "https://i.imgur.com/l6GysYf.png";
* {
outline: none;
opacity: 1;
-webkit-box-sizing: border-box;
-mo-box-sizing: border-box;
box-sizing: border-box;
}
html,
body {
position: fixed;
height: 100%;
background-color: blue;
font-size: 2vh;
margin: 0 auto;
font-family: open_sans;
}
.screen {
position: absolute;
height: 100%;
}
.menu-bar {
display: grid;
grid-template-columns: 33.33% 33.33% 33.33%;
position: relative;
height: 13.714%;
width: 100vw;
top: 0%;
text-align: center;
background-color: red;
}
.logo {
grid-column: 1/2;
height: 13.714vh;
position: absolute;
background-color: grey;
left:50%;
top:0px;
}
.title {
grid-column: 2/3;
position: relative;
color: #f5f5f5;
height: 100%;
width: 100%;
margin: 0 auto;
text-align: center;
justify-content: center;
align-items: center;
font-family: hack;
font-size: clamp(2vw, 8vw, 10vh);
display: flex;
top: 0%;
}
.menu-button {
grid-column: 3/4;
position: relative;
height: 100%;
}
.menu-button img {
position: absolute;
height: auto;
max-height: 75%;
max-width: 75%;
left: 50%;
right: 50%;
top: 50%;
bottom: 50%;
transform: translate(-50%, -50%);
}
.display {
position: relative;
height: 86.286%;
width: 100vw;
}
.speech-bubble {
display: grid;
grid-template-rows: 80% 0% 20%;
position: relative;
background-color: #f5f5f5;
height: 61.8%;
width: 90vw;
margin: auto;
border-radius: 2em;
padding-bottom: 1em;
}
<div id="screen" class="screen">
<div id="menu_bar" class="menu-bar">
<img id="logo" class="logo">
<div id="title" class="title">Title</div>
<div id="menu_button" class="menu-button"> <img id="menu_image"> </div>
</div>
<div id="display" class="display">
<div id="speech_bubble" class="speech-bubble">
<div id="logo_animation" class="logo-animation" data-flip-id="logo">
<img id="logo_animation_image">
</div>
</div>
</div>
</div>
</div>
i just put image in a div and centered vertically with top:50%;transform: translateY(-50%).
Update:
then center both directions with translate()
logo.src = "https://i.imgur.com/D9LOkQI.png";
menu_image.src = "https://i.imgur.com/l6GysYf.png";
* {
outline: none;
opacity: 1;
-webkit-box-sizing: border-box;
-mo-box-sizing: border-box;
box-sizing: border-box;
}
html,
body {
position: fixed;
height: 100%;
background-color: blue;
font-size: 2vh;
margin: 0 auto;
font-family: open_sans;
}
.screen {
position: absolute;
height: 100%;
}
.menu-bar {
display: grid;
grid-template-columns: 33.33% 33.33% 33.33%;
position: relative;
height: 13.714%;
width: 100vw;
top: 0%;
text-align: center;
background-color: red;
}
.logo {
grid-column: 1/2;
position: relative;
height: 10vh;
background-color: grey;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
.title {
grid-column: 2/3;
position: relative;
color: #f5f5f5;
height: 100%;
width: 100%;
margin: 0 auto;
text-align: center;
justify-content: center;
align-items: center;
font-family: hack;
font-size: clamp(2vw, 8vw, 10vh);
display: flex;
top: 0%;
}
.menu-button {
grid-column: 3/4;
position: relative;
height: 100%;
}
.menu-button img {
position: absolute;
height: auto;
max-height: 75%;
max-width: 75%;
left: 50%;
right: 50%;
top: 50%;
bottom: 50%;
transform: translate(-50%, -50%);
}
.display {
position: relative;
height: 86.286%;
width: 100vw;
}
.speech-bubble {
display: grid;
grid-template-rows: 80% 0% 20%;
position: relative;
background-color: #f5f5f5;
height: 61.8%;
width: 90vw;
margin: auto;
border-radius: 2em;
padding-bottom: 1em;
}
<div id="screen" class="screen">
<div id="menu_bar" class="menu-bar">
<img id="logo" class="logo">
<div id="title" class="title">Title</div>
<div id="menu_button" class="menu-button"> <img id="menu_image"> </div>
</div>
<div id="display" class="display">
<div id="speech_bubble" class="speech-bubble">
<div id="logo_animation" class="logo-animation" data-flip-id="logo">
<img id="logo_animation_image">
</div>
</div>
</div>
</div>
</div>
I set width to auto and height to 100% and it works.
logo.src = "https://i.imgur.com/D9LOkQI.png";
menu_image.src = "https://i.imgur.com/l6GysYf.png";
* {
outline: none;
opacity: 1;
-webkit-box-sizing: border-box;
-mo-box-sizing: border-box;
box-sizing: border-box;
}
html,
body {
position: fixed;
height: 100%;
background-color: blue;
font-size: 2vh;
margin: 0 auto;
font-family: open_sans;
}
.screen {
position: absolute;
height: 100%;
}
.menu-bar {
display: grid;
grid-template-columns: 33.33% 33.33% 33.33%;
position: relative;
height: 13.714%;
width: 100vw;
top: 0%;
text-align: center;
background-color: red;
}
.logo {
grid-column: 1/2;
width: auto;
height: 100%;
position: relative;
background-color: grey;
}
.title {
grid-column: 2/3;
position: relative;
color: #f5f5f5;
height: 100%;
width: 100%;
margin: 0 auto;
text-align: center;
justify-content: center;
align-items: center;
font-family: hack;
font-size: clamp(2vw, 8vw, 10vh);
display: flex;
top: 0%;
}
.menu-button {
grid-column: 3/4;
position: relative;
height: 100%;
}
.menu-button img {
position: absolute;
height: auto;
max-height: 75%;
max-width: 75%;
left: 50%;
right: 50%;
top: 50%;
bottom: 50%;
transform: translate(-50%, -50%);
}
.display {
position: relative;
height: 86.286%;
width: 100vw;
}
.speech-bubble {
display: grid;
grid-template-rows: 80% 0% 20%;
position: relative;
background-color: #f5f5f5;
height: 61.8%;
width: 90vw;
margin: auto;
border-radius: 2em;
padding-bottom: 1em;
}
<div id="screen" class="screen">
<div id="menu_bar" class="menu-bar">
<img id="logo" class="logo">
<div id="title" class="title">Title</div>
<div id="menu_button" class="menu-button"> <img id="menu_image"> </div>
</div>
<div id="display" class="display">
<div id="speech_bubble" class="speech-bubble">
<div id="logo_animation" class="logo-animation" data-flip-id="logo">
<img id="logo_animation_image">
</div>
</div>
</div>
</div>
</div>

css overlapping circle and text box

I am trying to produce this effect with CSS. I have tried creating a box with a triangle and then using negative margin to overlap it onto the circle, but cannot get it right.
Many thanks for any help.
fiddle
https://jsfiddle.net/Hastig/n3w0tztv/
Getting the circle to stay vertically centered and have the text container min-height the height of circle is tricky and is not worked out in this example. A cheap fix is adding align-items: center to .container at a breakpoint with #media.
body {
display: flex;
justify-content: center;
align-items: center;
margin: 0;
background-color: white;
height: 100vh;
}
.container {
display: flex;
width: 100%;
padding: 10px;
overflow: hidden;
}
.left {
position: relative;
display: flex;
width: 150px;
height: 150px;
margin-top: -4px;
margin-bottom: -4px;
margin-right: -17px;
background-color: #ec847c;;
border-style: solid;
border-color: white;
border-width: 4px;
border-radius: 100%;
z-index: 10;
}
.right {
position: relative;
display: flex;
flex: 2;
font-size: 20px;
color: white;
background-color: #4ca132;
}
.square {
position: absolute;
left: 0;
width: 50px;
height: 50px;
background-color: white;
overflow: hidden;
}
.square-top { top: 0; }
.square-btm { bottom: 0; }
.square::before {
content: "";
position: absolute;
display: flex;
width: 100%;
height: 100%;
transform: rotate(45deg) scale(2);
background-color: #4ca132;
z-index: 1;
}
.square-top::before { top: 50%; left: 50%; }
.square-btm::before { bottom: 50%; left: 50%; }
.text {
position: relative;
z-index: 2;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
padding: 20px 20px 20px 40px;
}
<div class="container">
<div class="left">
</div>
<div class="right">
<div class="square square-top"></div>
<div class="square square-btm"></div>
<div class="text">
Roles play an extremely important part in family funtion.
</div>
</div>
</div>

Absolutely positioning with flexbox in Safari

Safari has full support for FlexBox according to caniuse.
I am simply trying to stack some differently sized div's on top of each other using flexbox. I am genuinely curious as to why this works in Chrome/Firefox but not in Safari:
<div class="container">
<div class="inner-one"></div>
<div class="inner-two"></div>
</div>
.container {
width: 15rem;
height: 15rem;
border-radius: 50%;
background-color: blue;
display: flex;
align-items: center;
justify-content: center;
}
.container div {
position: absolute;
}
.inner-one {
width: 13rem;
height: 13rem;
border-radius: 50%;
background-color: green;
}
.inner-two {
width: 11rem;
height: 11rem;
border-radius: 50%;
background-color: purple;
}
See JSFiddle here: https://jsfiddle.net/19n95exf/3/
Because position: absolute; break display: flex, use transform: translate instead
.container {
position: relative;
width: 15rem;
height: 15rem;
border-radius: 50%;
background-color: blue;
}
.container div {
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
.inner-one {
width: 13rem;
height: 13rem;
background-color: green;
}
.inner-two {
width: 11rem;
height: 11rem;
background-color: purple;
}
<div class="container">
<div class="inner-one"></div>
<div class="inner-two"></div>
</div>
Or give the inner elements a left/top value
.container {
width: 15rem;
height: 15rem;
border-radius: 50%;
background-color: blue;
display: flex;
align-items: center;
justify-content: center;
}
.container div {
border-radius: 50%;
position: absolute;
}
.inner-one {
left: 1.5rem;
top: 1.5rem;
width: 13rem;
height: 13rem;
background-color: green;
}
.inner-two {
left: 2.5rem;
top: 2.5rem;
width: 11rem;
height: 11rem;
background-color: purple;
}
<div class="container">
<div class="inner-one"></div>
<div class="inner-two"></div>
</div>

Fluid - horizontally and vertically aligned image relative to its wrapper

In this fiddle, I have an image inside a wrapper in dark-blue, I want it to be 70% horizontally and vertically aligned relative to its wrapper.
I tried to use table-cell and it seems does not work.
HTML:
<div id="menu_content">
<div id="menu_wallet">
<div id="menu_mywallet">
<div id="wallet_logo_new">
<div id="wallet_logo_new_padding">
<img src="https://imagizer.imageshack.us/v2/849x565q90/833/uua2.jpg" id="img_wallet_logo_new" />
</div>
</div>
<div id="wallet_txt">Test</div>
</div>
</div>
</div>
CSS:
#menu_content {
height: 70%;
width: 100%;
position: relative;
border: 0px solid blue;
}
#menu_wallet {
overflow: hidden;
height: 35%;
width: 100%;
display:table;
background-color: #416DB4;
width: 85%;
margin-left: auto;
margin-right: auto;
border-radius: 0.3em;
}
#wallet_logo_new {
display: table-cell;
vertical-align: middle;
width: 50%;
}
#wallet_logo_new_padding {
position: relative;
height: 70%;
width: 70%;
margin: auto;
background-color: #1F58A5;
border-radius: 5px;
display: table;
}
#img_wallet_logo_new {
//margin-top:15px;
width: 20%;
//height: 20%;
//width: 60px;
//height: 60px;
position: relative;
}
#wallet_txt {
display: table-cell;
vertical-align: middle;
font-size: 3em;
color: #FFFFFF;
width: 50%;
}
Is this what you want?
#wallet_logo_new_padding img
{
position: relative;
width: 70%;
margin-left: 15%;
margin-right: 15%;
}

Resources