Centering fixed button inside a div - html

I have a div with some elements inside.
I would like to center the start button exactly in the middle of the div. I've tried making it fixed like this:
Board.css
.board{
width: 400px;
height: 400px;
margin: 150px auto 0;
border: 5px solid black;
border-radius: 5px;
background-color: darkgray;
display: flex;
flex-wrap: wrap;
}
.startButton {
position: fixed;
left: 50%;
top:50%;
}
#media(max-width: 650px) {
.board {
width: 300px;
height: 300px;
margin: 150px auto 0;
border: 5px solid black;
border-radius: 5px;
}
}
But as you can see, it is not perfectly aligned in the middle. How do I go about this? I've also made a media-query that makes the div smaller on smaller devices, so it needs to be responsive as well.
Board.js
render() {
return (
<div className="board">
<button className="startButton">Start Game!</button>
<Square clicked={this.squareClickedHandler} val={this.state.squareOne} />
<Square clicked={this.squareClickedHandler} val={this.state.squareTwo} />
<Square clicked={this.squareClickedHandler} val={this.state.squareThree} />
<Square clicked={this.squareClickedHandler} val={this.state.squareFour} />
</div>
)
}

Add position: relative; in .board class and remove all css styles from .startButton and add following code in .startButton
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
Try following code
.board{
position: relative;
width: 400px;
height: 400px;
margin: 150px auto 0;
border: 5px solid black;
border-radius: 5px;
background-color: darkgray;
display: flex;
flex-wrap: wrap;
}
.startButton {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
#media(max-width: 650px) {
.board {
width: 300px;
height: 300px;
margin: 150px auto 0;
border: 5px solid black;
border-radius: 5px;
}
}
<div class="board">
<button class="startButton">Start Game!</button>
</div>

left: 50%
makes the element's x-coördinate be in the middle of your screen.
The value you actually want is
´left: (50% - [element width / 2]) ´
so your the x-coördinate will be a little to the left of the middle so your element can be in the middle

Related

Div isn't stretching to 100% height of parent

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;
}

How to set dynamic width for parent depending on image width using only css

I am creating my own lightbox with React and I want to set width on div with class .lightbox-active depending on image width. For now, I have set max-width: 50%; max-height: 80% for parent element and when e.g. the image is filling only 43% of parent element I want to set 43% width for a parent. Is there any way to achieve this without calculating the width in js?
<div className="lightbox-active">
<img onLoad={() => isFinished()} src={fakeImages[openedImage - 1].url} alt="" />
</div>
My image has got property object-fit: contain and I need this for display image in original proportions, without this image is filling 50% width as it's parent but overflowing height.
Working example:
https://codepen.io/freestyle09/pen/rNNdNNg
Border green should have sizes like an image
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.lightbox {
position: fixed;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,.3);
}
.lightbox-active {
display: flex;
justify-content: center;
max-width: 50%;
max-height: 80%;
border: 1px solid red;
}
.lightbox-active img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
border: 2px solid green;
}
<div class="lightbox">
<div class="lightbox-active">
<img src='https://picsum.photos/1503/1500' alt="" />
</div>
</div>
I have a solution, which can be achieved using position: absolute . It can work for you as you want.
You have to modify the css of .lightbox-active and .lightbox-active img to use absolute positioning.
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.lightbox {
position: fixed;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,.3);
}
.lightbox-active {
max-width: 50%;
max-height: 80%;
border: 1px solid red;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
.lightbox-active img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
border: 2px solid green;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
}
<div class="lightbox">
<div class="lightbox-active">
<img src='https://picsum.photos/1503/1500' alt="" />
</div>
</div>
Using inline block and overflow hidden can solve your issue to some extent. But the image will be cropped at the bottom if image is larger than available space.
Refer the code snippet below.
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.lightbox {
position: fixed;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,.3);
}
.lightbox-active {
display: inline-block;
overflow:hidden;
justify-content: center;
max-width: 50%;
max-height: 80%;
border: 1px solid red;
}
.lightbox-active img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
border: 2px solid green;
}
<div class="lightbox">
<div class="lightbox-active">
<img src='https://picsum.photos/1503/1500' alt="" />
</div>
</div>

Box-shadow on absolute positioned div with no content?

I have a DIV that I'm using as a "separator".
Requirements:
That separator should be placed on the bottom of the header.
I need that separator to span across the full viewport width.
I need to style it using box-shadow on it.
Problems:
I have an outer Layout DIV that limits everything to max-width = 500px;
My header is not fixed (it's sticky, so it only becomes fixed after some scroll). It starts as relative, so I can absolute position the separator.
I had to make the separator DIV with position: absolute and width: 100vw so make it span the full viewport with.
QUESTION
It works as intended if I use the border-bottom property. It spans the full width of the viewport (1st snippet).
But it doesn't work with box-shadow (nothing is displayed. 2nd snippet). Why? Is it possible to make it work with box-shadow in this situation?
SNIPPET: works with border-bottom
.layout {
width: 100%;
max-width: 500px;
margin: auto;
}
.header {
height: 120px;
background-color: lightblue;
position: relative;
}
.separator {
position: absolute;
width: 100vw;
height: 3px;
top: 100%;
border-bottom: 1px solid black;
/*box-shadow: 0 4px 3px -3px black;*/
left: 50%;
transform: translate(-50%, -50%);
}
.main {
height: 150px;
background-color: lightgreen;
}
<div class="layout">
<div class="header">
Header
<div class="separator"></div>
</div>
<div class="main">
Main
</div>
</div>
SNIPPET: does NOT work with box-shadow
.layout {
width: 100%;
max-width: 500px;
margin: auto;
}
.header {
height: 120px;
background-color: lightblue;
position: relative;
}
.separator {
position: absolute;
width: 100vw;
height: 3px;
top: 100%;
/*border-bottom: 1px solid black;*/
box-shadow: 0 4px 3px -3px black;
left: 50%;
transform: translate(-50%, -50%);
}
.main {
height: 150px;
background-color: lightgreen;
}
<div class="layout">
<div class="header">
Header
<div class="separator"></div>
</div>
<div class="main">
Main
</div>
</div>
The 5-value box-shadow shorthand you're using sets the following properties:
offset-x | offset-y | blur-radius | spread-radius | color
Your spread radius is set to -3px. This diminishes the "height" of the shadow to 0, since the height of your separator is 3px.
The shadow will display if you increase the spread radius. Try this instead:
box-shadow: 0 4px 3px 0px black
Somehow the box-shadow property in that situation need some minimal height render a shadow. I've managed to find a solution. See snippet below.
.layout {
width: 100%;
max-width: 500px;
margin: auto;
}
.header {
height: 120px;
background-color: lightblue;
position: relative;
}
.separator {
position: absolute;
width: 100vw;
height: 10%;
top: 95%;
/*border-bottom: 1px solid black;*/
box-shadow: 0 4px 3px -3px black;
left: 50%;
transform: translate(-50%, -50%);
}
.main {
height: 150px;
background-color: lightgreen;
}
<div class="layout">
<div class="header">
Header
<div class="separator"></div>
</div>
<div class="main">
Main
</div>
</div>

How to arrange correctly?

I'm trying to create two banners with cropped corners, but I'm having problems with my code:
https://codepen.io/Jeerjmin/pen/VdBVKL
.container {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
background-color: white;
}
.banner-1 {
min-width: 200px;
max-width: 200px;
height: 300px;
margin: 70px;
background-color: white;
border: solid #01579B 4px;
border-radius: 15px;
overflow: hidden;
}
.banner-1:before {
position: absolute;
content: '';
min-width: 38px;
height: 60px;
top: 39px;
left: 303px;
background-color: white;
border-bottom: solid #01579B 4px;
transform: rotate(-45deg);
}
.banner-2 {
min-width: 200px;
max-width: 200px;
height: 300px;
margin: 70px;
background-color: white;
border: solid #01579B 4px;
border-radius: 15px;
overflow: hidden;
}
.banner-2:before {
position: absolute;
content: '';
min-width: 38px;
height: 60px;
top: 39px;
left: 652px;
background-color: white;
border-bottom: solid #01579B 4px;
transform: rotate(-45deg);
}
img {
position: relative;
top:100px;
left: 25px;
width: 200px;
height: 150px;
}
.dot {
height: 50px;
width: 50px;
background-color: deepskyblue;
border-radius: 50%;
position: relative;
left: -50px;
bottom: 100px;
text-align:center;
}
p {
text-align:center;
}
<div class="container">
<div class="banner-1">
<p>Card-1</p>
<img src="https://img2.goodfon.ru/original/1366x768/6/5e/koshka-kot-meyn-kun-belyy-fon-5567.jpg"></img>
<span class="dot dot-1">
<h1>0,5</h1>
<h5>кг</h5>
</span>
</div>
<div class="banner-2">
<p>Card-2</p>
<img src="https://img2.goodfon.ru/original/1366x768/6/5e/koshka-kot-meyn-kun-belyy-fon-5567.jpg"></img>
<span class="dot dot-2">
<h1>0,5</h1>
<h5>кг</h5>
</span>
</div>
</div>
Problem 1:
I'm trying to crop the top left corners of the banners, but the cards move around while the crops stay where they are.
Problem 2:
The span with class="dot" should form a colored circle, but does not.
Not sure what you meant in Problem 1. As for problem 2, you need to add display: block to your .dot class and you also can remove left property form it.
I had to make several changes to your code to get this working, so see the code snippet below for all the changes. However, here are a few key points:
To position your ::before pseudo-elements in correct relation to the banners, add relative positioning to the banners.
To make your blue dot work, and to align its contents correctly, Flexbox layout is a good solution.
To simplify your code, it's preferable to style similar items together. For that reason, I've given your banners shared styles.
<img> elements should not have a corresponding closing tag (the technical term for this kind of element is "self-closing"). That said, I changed your image to be a background image. The reason is that you can't both have overflow: hidden on your banners and put the clipped corner over its borders.
.container {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
background-color: white;
}
/* Target both banners together,
since they share styles */
.banner-1,
.banner-2 {
min-width: 200px;
max-width: 200px;
height: 300px;
margin: 70px;
border: 4px solid #01579B;
border-radius: 15px;
/* Relatively position the banner,
so that the clipped corners,
can be properly placed */
position: relative;
/* To have the image clip to
the banner, make it a
background image */
background: white no-repeat 10px bottom / auto 150px
url("https://img2.goodfon.ru/original/1366x768/6/5e/koshka-kot-meyn-kun-belyy-fon-5567.jpg");
}
.banner-1::before,
.banner-2::before {
content: "";
width: 22px;
height: 38px;
position: absolute;
left: 0;
top: -1px;
background-color: white;
border-right: 4px solid #01579B;
/* Adjust your transform origin,
to make the rotation easier */
transform-origin: top right;
transform: rotate(45deg);
}
.dot {
/* Use Flexbox to align the
content in your dot */
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 80px;
width: 80px;
background-color: deepskyblue;
border-radius: 50%;
position: absolute;
left: 20px;
bottom: 100px;
}
h1, h5 {
/* Remove margins on
dot content */
margin: 0;
}
p {
text-align: center;
}
<div class="container">
<div class="banner-1">
<p>Card-1</p>
<span class="dot dot-1">
<h1>0,5</h1>
<h5>кг</h5>
</span>
</div>
<div class="banner-2">
<p>Card-2</p>
<span class="dot dot-2">
<h1>0,5</h1>
<h5>кг</h5>
</span>
</div>
</div>

Is it possible to anchor an element to a centered element?

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;
}