I have been given positions in the form of an object for a box to be drawn over an image. I have tried to do this using a wrapper div but the box is positioned on the top right of the image and is not fixed to the image.
I want a bounding box to be drawn directly on the image given the position coordinates that resizes with the image. How can I edit the CSS to achieve what I'm looking for?
<div key={index} className="wrapper">
<img src={`images/${item.Img_Name}`} className="App-images" alt="" loading="lazy"/>
<div
style={{
position: "inherit",
top: `${item.Top}px`,
left: `${item.Left}px`,
width: `${item.Width}px`,
height: `${item.Height}px`,
border: "1px solid red",
}} className="Box">
</div>
</div>
</div>
Here is the current CSS file
.Box {
grid-area: 1 / 1;
flex: 0 0 33.33333%;
max-width: 75%;
margin-top: 20px;
}
.App-images {
flex: 0 0 33.33333%;
max-width: 75%;
margin-top: 20px;
grid-area: 1 / 1;
}
.wrapper {
flex: 0 0 33.33333%;
max-width: 75%;
margin-top: 20px;
display: grid;
}
it seems what you're trying to do here is position a div within the confines of another div. For this case, you would use position: relative and position: absolute, with top and left to change the location of the parent. For more details, visit this question. Below is an example in the limited code you copy pasted in from your question, with the HTML being the same:
.Box {
grid-area: 1 / 1;
flex: 0 0 33.33333%;
max-width: 75%;
margin-top: 20px;
position: absolute; /* the position */
top: 10px; /* can also be sent to percents, vw, etc. places position in parent*/
left: 10px; /* can also be sent to percents, vw, etc. places position in parent */
}
.App-images {
flex: 0 0 33.33333%;
max-width: 75%;
margin-top: 20px;
grid-area: 1 / 1;
}
.wrapper {
flex: 0 0 33.33333%;
max-width: 75%;
margin-top: 20px;
display: grid;
position: relative; /* this is for the parent */
}
Here is an easier to understand example:
div.main { /* parent */
border: 2.5px solid black;
background-color: red;
padding: 2.5px;
width: 100px;
height: 100px;
position: relative;
}
img {
width: 80px;
height: 80px;
}
div.apart { /* child */
position: absolute;
background-color: white;
top: 10px;
left: 10px;
}
<div class=main>
<img src="https://picsum.photos/500">
<div class=apart>10px top+left</div>
</div>
Related
I'm designing my CSS layout, but can't get the div to stretch to 100% of the height of the parent.
I have a menu bar that takes up the top 13.714vh of the screen. Then I have a main div that I want to take up the remainder of the screen height which I did with height: 100%. bottom-container takes up the bottom 38.2% of the vertical space available in main, and I want speech-bubble to take up the remaining 61.8% of the vertical space in main.
For some reason though, there's a huge white container in the middle of the screen, and speech-bubble isn't taking up the remaining space because of it. Can anyone help me figure out what's going on?
Is there a problem with my HTML or did I make an error in the CSS?
Here's the code pen:
https://codepen.io/TheNomadicAspie/pen/NWjKwxE
body {
margin: 0;
}
.menu-bar {
height: 13.714vh;
width: 100vw;
background: darkblue;
top: 0%;
}
.main {
background: black;
grid-template-rows: 61.8% 100%;
height: 100%;
width: 100%;
padding-left: 1.5%;
padding-right: 1.5%;
padding-top: 1.5%;
padding-right: 1.5%;
}
.speech-bubble {
grid-row: 1;
position: relative;
background: orange;
height: 97%;
width: 97%;
border-radius: 4em;
}
.speech-bubble:after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
width: 0;
height: 0;
border: 4em solid transparent;
border-top-color: white;
border-bottom: 0;
margin-left: -4em;
margin-bottom: -4em;
}
.email-container {
visibility: hidden;
}
.question-text {
visibility: hidden;
}
.bottom-container {
grid-row: 2;
position: fixed;
background: green;
height: 38.2%;
width: 100vw;
bottom: 0%;
left: 0%;
}
<div id="menu_bar" , class="menu-bar"></div>
<div id="main" , class="main">
<div id="speech_bubble" , class="speech-bubble">
<div id="email_container" class="email-container">
<label for="email">Enter your email:</label>
<input type="email" id="email" name="email">
<button id="submit_email_btn" class="btn">Submit</button>
</div>
<div id="question_text" class="question-text">Question</div>
</div>
</div>
<div id="bottom_container" , class="bottom-container">
</div>
</div>
</div>
Do you want anything like this? screenshot.
If so, making your .menu-bar as position: relative and modifying your .main class styles as follows will work:
.main {
position: absolute;
background: black;
left: 0;
right: 0;
height: 50%;
}
Also, you may add margin: auto in your speech-bubble class to align it to center.
Your main tag is not taking full height as your html and body tags are not taking the full height.
Always remember that block elements can stretch maximum to their's parent's height, hence you need to give html and body tag height of 100%.
I have added the additional css below.
html, body { height: 100%;}
I think you want thing like this
* {
margin: 0;
box-sizing: border-box;
}
body {
display: flex;
flex-direction: column;
height: 100vh;
}
.menu-bar {
height: 13.714vh;
background-color: tomato;
color: #fff
}
.main {
background: black;
padding: 1.5%;
flex: 1
}
.speech-bubble {
background-color: orange;
border-radius: 4em;
height: 95%;
position: relative;
display: flex;
flex-direction: column;
}
.speech-bubble:after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
width: 0;
height: 0;
border: 4em solid transparent;
border-top-color: white;
border-bottom: 0;
margin-left: -4em;
margin-bottom: -4em;
}
.email-container {
align-items: center;
justify-content: center;
flex: 1;
display: flex;
}
.question-text {
height: 50px;
position: relative;
text-align: center
}
.bottom-container {
height: 70px;
background-color: lightseagreen;
}
I asked this earlier and was sent: Can I create a div with a Curved bottom?
But a curved bottom div is not what I want.
I am after a very large circle (not just with a curved bottom but a proper circle)... which is positioned with a negative margin-top and has a flexible width when the browser windows is resized.
Here's an image of exactly what I want
Here's an image of what the layout should look like zoomed out - so you can see the whole circle
Here's what I have so far:
https://jsfiddle.net/etmgho6s/
#container {
width: 100%;
margin: 0 auto;
padding: 0;
position: relative;
}
#nav-bg {
width: 90vw;
height: 90vw;
margin: 0 auto;
padding: 0;
margin-top: -45vw;
background: red;
border-radius: 50%;
position: absolute;
}
#title {
margin: 0 auto;
text-align: center;
position: absolute;
margin-top: 20px;
}
Any help would be appreciated!
Thanks, Josh
Does this work for you?
#container {
width: 100%;
margin: 0 auto;
padding: 0;
position: relative;
display: flex; /* line added */
justify-content: center; /* line added */
}
#nav-bg {
width: 150vw;
height: 90vw;
margin: 0 auto;
padding: 0;
margin-top: -60vw;
background: red;
border-radius: 50%;
position: absolute;
}
#title {
margin: 0 auto;
text-align: center;
position: absolute;
margin-top: 20px;
}
<div id="container">
<div id="nav-bg"></div>
<h1 id="title">Navigation content goes here</h1>
</div>
I have created a container (red border with line denoting the center) that scrolls horizontally if there is overflow.
The first child (purple block) of this container is always a button.
When you click this button, it adds additional children to the container.
What I am trying to do is figure out a way with pure CSS, so that the first child is always centered when the app is loaded, and the last child element in the container, if there is more than one child, can also be scrolled to the very center of the container.
I am having difficulties figuring this out because I have applied a min-width (i.e. 100px) in addition to a responsive width (i.e. 25vw) to the child elements.
The way I was initially planning on achieving this was by applying a padding-left to the parent container, and then an ::after pseudo element to :not(.first-child).children:last-child, but then I realized the approach is not sufficient if I want it to be completely responsive. However, I know I can manually calculate at which width min-width will be triggered and then use a #media query, but I am hoping there is a better way.
#container {
width: 100%;
height: 100%;
padding-left: ; /* Half the window width minus half the width of the child. */
overflow-x: scroll;
display: flex;
align-items: center;
background: skyblue;
box-sizing: border-box;
border: solid red 2px;
}
#container::-webkit-scrollbar {
display: none;
}
.children {
width: 25vw;
min-width: 100px;
height: 50%;
min-height: 200px;
position: relative;
margin-right: 5%;
display: flex;
justify-content: center;
align-items: center;
background: purple;
}
:not(.first-child).children:last-child::after {
content: '';
width: ; /* Half the window width minus half the width of the child. */
height: 100%;
position: relative; /* relative or absolute */
left: ; /* and offset appropriately. */
transform: ; /* */
}
Does anybody have any ideas of how to do this?
You can apply margin-left to the first child and to deal with the min-width you can use media query. When the screen is less than 400px the 25vw will be less than 100px and you change the value to consider the 100px.
#container {
position: fixed;
top:0;
left:0;
width: 100%;
height: 100%;
overflow-x: scroll;
display: flex;
align-items: center;
background:
linear-gradient(red,red) center/1px 100% no-repeat,
skyblue;
box-sizing: border-box;
border: solid red 2px;
}
#container::-webkit-scrollbar {
display: none;
}
.children {
width: 25vw;
min-width: 100px;
height: 40%;
min-height: 100px;
position: relative;
margin-right: 5px;
display: flex;
justify-content: center;
align-items: center;
background: purple;
flex-shrink:0; /* don't forget this to avoid the shrink */
}
.children:first-child {
margin-left: calc(50% - 12.5vw);
}
#media (max-width:400px) {
.children:first-child {
width: 25vw;
min-width: 100px;
margin-left: calc(50% - 50px);
}
}
<div id="container">
<div class="children"></div>
<div class="children"></div>
<div class="children"></div>
<div class="children"></div>
</div>
Without media query you can consider a pseudo element where you will have a max-width constraint:
#container {
position: fixed;
top:0;
left:0;
width: 100%;
height: 100%;
overflow-x: scroll;
display: flex;
align-items: center;
background:
linear-gradient(red,red) center/1px 100% no-repeat,
skyblue;
box-sizing: border-box;
border: solid red 2px;
}
#container::-webkit-scrollbar {
display: none;
}
.children {
width: 25vw;
min-width: 100px;
height: 40%;
min-height: 100px;
position: relative;
margin-right: 5px;
display: flex;
justify-content: center;
align-items: center;
background: purple;
flex-shrink:0;
}
#container:before {
content:"";
width: calc(50% - 12.5vw);
max-width:calc(50% - 50px);
flex-shrink:0;
}
<div id="container">
<div class="children"></div>
<div class="children"></div>
<div class="children"></div>
<div class="children"></div>
</div>
I was able to create a strictly responsive solution using calc, even though I am using vh as the width of the children. CSS is a savior.
#container {
--offset: calc(50vw - ((100vh / 100) * 20);
padding-left: var(--offset);
background: skyblue;
}
.children {
min-width: 40vh; /* vh is used for width to account for the height of window. */
min-height: 60vh;
position: relative;
background: purple;
}
:not(.first-child).children:last-child::after {
content: '';
width: var(--offset);
height: 1px;
position: absolute;
left: 100%;
}
I want something like this (the pink circle): CSS quarter circle 100vh example.
So far, I have a half-circle (see CSS below), but when I try to make it 100vh, it stretches and I can't figure out how to keep it proportional.
.circle {
height: 180px;
width: 90px;
border-radius: 0 90px 90px 0;
-moz-border-radius: 0 90px 90px 0;
-webkit-border-radius: 0 90px 90px 0;
background: red;
margin: 100px;
position: absolute;}
Any insights greatly appreciated. Thanks
I modified the code to only use 200vh to calculate both width and height of circle. This will give you a perfect circle at any screen size.
* {margin:0;padding:0;box-sizing:border-box}
html, body {width:100vw;height:100vh}
.box {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
.box > .circle {
height: 200vh;
width: 200vh;
position: absolute;
bottom: -100vh;
right: -100vh;
border-radius: 50%;
background: hotpink;
}
<div class="box">
<div class="circle"></div>
</div>
You can do it like this:
* {margin:0;padding:0;box-sizing:border-box}
html, body {width:100vw;height:100vh}
.box {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
.box > .circle {
height: 200vh;
width: 125.5vw; /* if exactly 16:9 vw/vh aspect ratio */
position: absolute;
bottom: -100vh;
right: -56.250vw; /* if exactly 16:9 vw/vh aspect ratio */
border-radius: 50%;
background: hotpink;
}
<div class="box">
<div class="circle"></div>
</div>
Conclusion: This works perfectly if the screen viewport is exactly at 16:9 aspect ratio (see it inside the editor (not "Run code snippet") without Menu Bar & Bookmarks Toolbar but better to see it in full screen), anything else than that fails so I wouldn't recommend using viewport units for this task. If anyone can prove me wrong or do it better, go ahead.
And with px:
* {margin:0;padding:0;box-sizing:border-box}
html, body {width:100%}
.box {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
}
.box > .circle {
height: 180px;
width: 180px;
position: absolute;
bottom: -90px;
right: -90px;
border-radius: 50%;
background: hotpink;
}
<div class="box">
<div class="circle"></div>
</div>
you can start to keep the box into the ratio you want and center it when it doesn't fill the whole screen (=> downscaling to fit within the screen)
to size things, you can relay on %, vw,vh,vmax and or vmin units.
basicly you can start with size and max-size using the viewport as reference for the main box:
height:100%;
width:100%;
max-width:179vh;/* height viewport*/
max-height:56vw;/* width viewport*/
to align content you can use the flex display and margins and position.
To draw that 1/4 circle, you need a square that is at least the height of your box if it is to be drawn from border-radius. ( else a radial-gradient would do just fine).
for the vertical text, you may take a look at writing-mode.
A mix of CSS3 rules and positionning method can allow to do something that is about fluid.
Run the snippet below in fullpage and resize your window (heigh/width/both) your browser to see behavior.(or play with the codepen)
html {
height: 100%;
display: flex;
background: #ccc;
}
body {
margin: auto;
background: linear-gradient( to right, rgb(231, 231, 231) 25%, rgb(225, 207, 207) 25%);
height: 100%;
width: 100%;
max-width: 179vh;
max-height: 56vw;
display: flex;
align-items: center;
overflow: hidden;
position: relative;
box-shadow: 0 0 0 2px;
/* debug , see me */
}
/* make div be squares */
div:before {
content: "";
display: inline-block;
padding-top: 100%;
vertical-align: top;
}
.small {
border-radius: 50%;
background: rgb(101, 112, 168);
width: 25%;
margin-left: 13%;
box-shadow: 20vmin 20vmin 40vmin;
}
.big {
background: linear-gradient(to top, rgb(195, 90, 131), rgb(195, 90, 131)) no-repeat 0 0;
width: 56%;/* according to the ratio choosen */
border-top-left-radius: 100%;
flex-shrink: 0;/* avoid flex to shrink it */
margin: auto 0 0 auto;
}
/* position piece of text via absolute */
p {
margin: 0;
position: absolute;
bottom: 1%;
right: 5%;
font-size: 15vmin;
white-space: nowrap;
color: white;
}
p span {/* this rules might need to be tune to specific font-family*/
width: 0.25em;
display: inline-block;
vertical-align: -0.1em;
font-size: 0.155em;
writing-mode: vertical-lr;
transform: scale(-1);/*=> writing-mode:sideways-lr; not avalaible everywhere*/
}
h1,
body:before {
top: 0;
color: rgb(101, 112, 168);
position: absolute;
width: 5em;
font-size: 2vmin;
margin: 12vmin 0 5vmin 5vmin;
}
body:before {
content: "2017";
top: auto;
bottom: 0;
font-weight: bold;
}
h1:before {
content: "HB";
color: rgb(195, 90, 131);
border-radius: 50%;
position: absolute;
bottom: 150%;
font-size: 2.5em;
width: 0.75em;
height: 0.75em;
line-height: 0.75em;
letter-spacing: -0.35em;
border: solid 1px;
text-indent: -0.35em;
overflow: hidden;
}
<h1>VISUAL EXPLORATION</h1>
<p><span>BACK TO</span>BASIS</p>
<div class="small"></div>
<div class="big"></div>
By using the same view port unit for both height and width, you can achieve a perfect circle. Then putting it within a container which is fixed to the height of the view port and hiding the rest of the overflow will allow you to remove any unnecessary scroll bars and still allow for content below the circle.
The below demo will show the circle proportionally correct, always 100% of the view port height while making sure it is always a perfect circle.
It will obviously look better in full screen.
* {
margin: 0;
padding: 0;
}
.container {
width: 100%;
height: 100vh;
position: relative;
overflow: hidden;
background: #dedede;
}
.dark {
background: #777777;
}
.circle {
width: 200vh;
height: 200vh;
border-radius: 100%;
position: absolute;
right: -100vh;
background: pink;
}
<div class="container">
<div class="circle"></div>
</div>
<div class="container dark">
</div>
Is it possible to anchor a textarea to an image that is centered in the middle of the page, so that it doesn't move out of the image when the screen size changes?
Example on jsfiddle: https://jsfiddle.net/rxg7t2ca/1/
.container {
width: 60%;
margin: 0 auto;
/* border: 2px solid blue; */
}
#cat {
display: block;
margin: 0 auto;
}
.box1 {
position: relative;
top: -250px;
left: 30px;
width: 100px;
height: 100px;
}
<div class="container">
<img src="http://i.imgur.com/a2Wd9D2.jpg" height=300px id="cat" />
<textarea class="box1"> This is a text box </textarea>
</div>
.container {
position: relative;
width: 60%;
margin: 0 auto;
border: 2px solid blue;
}
#cat {
width: 100%;
object-fit: cover; /* 1 */
vertical-align: bottom; /* 2 */
}
.box1 {
position: absolute; /* 3 */
top: 50%; /* 3 */
left: 50%; /* 3 */
transform: translate(-50%, -50%); /* 3 */
width: 100px;
height: 100px;
}
<div class="container">
<img src="http://i.imgur.com/a2Wd9D2.jpg" height=300px id="cat" />
<textarea class="box1"> This is a text box </textarea>
</div>
Explanations:
Why isn't object-fit working in flexbox?
Mystery white space underneath image tag
Element will not stay centered, especially when re-sizing screen
In the container use 'position:relative', and in the textarea and in the image use 'position: absolute'.
CSS absolute property: The element is positioned relative to its first positioned (not static) ancestor element.
.container{
width: 60%;
margin: 0 auto;
position:relative;
/* border: 2px solid blue; */
}
#cat{
position: absolute;
top: 0px;
left: 0px;
display: block;
margin: 0 auto;
}
.box1{
position: absolute;
top: 25px;
left: 30px;
width: 100px;
height: 100px;
}