Having trouble centering div in CSS - html

I'm working with one of my first pages. It contains a pop-up that needs to be centered in the exact middle of the page. I'm aware that there are many ways to do this, but I'm having trouble with each one of them;
The first one I tried is this:
<div class="mod" id="modal">
<div class="mod-header">
<div class="mod-title">15% off for new customers</div>
<button data-close-button class="close-button">×</button>
</div>
<div class="mod-body">
<h2>subscribe to our newsletter and get 15% off your first purchase</h2>
<form method="POST">
{{ form|crispy }}
{% csrf_token %}
<button class="submit-btn" type="submit">go</button>
</form>
</div>
</div>
Styles:
.mod{
position: fixed;
transition: 200ms ease-in-out;
transform: translate(-50%, -50%) scale(0);
border: 1px solid black;
z-index: 999;
padding: 1.2em;
background-color: #f6f1eb;
}
.mod.active{
top:50%;
left:50%;
transform: translate(-50%, -50%) scale(1);
-webkit-font-smoothing: antialiased;
}
The problem with this is that I'm getting a blurry effect in the div. I tried everything (webkit antialiasing, setting translate to 51%, etc) and it won't change.
Some other ways of centering implicate selecting the parent container, but that's impossible in my case since this is a large website and I need this to be in the center of the entire page, not the container.
I also considered using calc() instead of translate() and subtract the width and height of the container, but then I'd need to know the dimentions all the time, and it would lose the responsiveness.
Is there any better way to do this? I'm sure it's very simple, but I'm a beginner and don't know much. Let me know if I'm lacking code or I'm not being clear enough. Thanks in advance!

Just give your modal another container and it's good to go.
.mod {
/* Remove background if backdrop is not needed */
background: rgba(0, 0, 0, 0.1);
position: fixed;
/* 0, 0, 0, 0 gives 100% full height and width on absolute/fixed elements */
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.mod .wrapper {
width: 300px;
height: 300px;
/* since there's no feature to vertically center you need margin top,
while the auto will center horizontally automatically whatever the width is.
Do note that left, top 50% is quite unreliable since it doesn't take into account the size
of the container
*/
margin: 10% auto 0;
background: white;
display: block;
border-radius: 4px;
text-align: center;
}
<!-- Will be the one that is position fixed -->
<div class="mod" id="modal">
<!-- While this one will make the modal look, with this you can use margin left/right: auto to automatically center horizontally regardless of the width -->
<div class="wrapper">
<div class="mod-header">
<div class="mod-title">15% off for new customers</div>
<button data-close-button class="close-button">×</button>
</div>
<div class="mod-body">
<h2>subscribe to our newsletter and get 15% off your first purchase</h2>
<form method="POST">
</form>
</div>
</div>
</div>

Change the position property of the modal to absolute and add top and left property to it. Remove other properties of the active class and add only display property to it.
let btn = document.querySelector("#btn");
let closeBtn = document.querySelector(".close-button");
let modal = document.querySelector("#modal");
btn.addEventListener("click", () => {
modal.classList.add("active");
});
closeBtn.addEventListener("click", () => {
modal.classList.remove("active");
});
.mod {
position: absolute;
top: 50%;
left: 50%;
display: none;
width: 400px;
transition: 200ms ease-in-out;
transform: translate(-50%, -50%);
border: 1px solid black;
z-index: 999;
padding: 1.2em;
background-color: #f6f1eb;
}
.active {
display: block;
}
<button id="btn">Show Modal</button>
<div id="modal-container">
<div class="mod" id="modal">
<div class="mod-header">
<div class="mod-title">15% off for new customers</div>
<button data-close-button class="close-button">×</button>
</div>
<div class="mod-body">
<h2>subscribe to our newsletter and get 15% off your first purchase</h2>
<form method="POST">
Your content here!
<button class="submit-btn" type="submit">go</button>
</form>
</div>
</div></div>

Related

How to position Left/Right buttons on top of left/right edges of image?

I've spent several hours trying to correctly position left & right buttons in the correct place for any image I load. Here's an example of the way they should look:
I have a React component called FullSizeImage that is correctly centered, horizontally & vertically in a modal that covers 100% of my browser window. Now what I want to do is add a left button and a right button, have them vertically centered, and positioned left & right respectively over top of the image. But no matter what I've tried, I can't get it working!
Here's some sample layout code:
<div className={styles.container}>
<div className={styles.buttonContainer}>
<div>
<Button type={ButtonType.Circular} text='<' onClick={() => {}} />
<Button type={ButtonType.Circular} text='>' onClick={() => {}} />
</div>
</div>
<img src={`${item.path}${transformation}/${item.name}`} alt={item.name} />
</div>
I have complete flexibility how I introduce those two buttons in relation to the img element.
Any ideas how to do this properly - ie. HTML layout and corresponding CSS?
Have the buttons and image in the same container. Use position: absolute on the buttons.
.container {
width: 100%;
height: 500px;
position: relative;
}
.smaller-container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%)
}
.img {
width: 500px;
}
.left-button, .right-button {
position: absolute;
top: 50%;
translateY(-50%);
}
.left-button {
left: 0;
}
.right-button {
right: 0;
}
<div class="container">
<div class="smaller-container">
<button class="left-button">left</button>
<button class="right-button">Right</button>
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/3/3e/Lupine_R01.jpg/475px-Lupine_R01.jpg" alt="flower" />
</div>
</div>
In the interest of completeness, and helping others, I simplified things and found a solution:
<div key={`${item.mediaId}_large`} className={styles.main}>
<img src={`${item.path}${transformation}/${item.name}`} />
<div className={styles.leftButton}>
<Button type={ButtonType.Circular} text='<' onClick={() => {}} />
</div>
<div className={styles.rightButton}>
<Button type={ButtonType.Circular} text='>' onClick={() => {}} />
</div>
</div>
.main {
div {
height: 100vh;
position: absolute;
top: 50vh;
}
.leftButton {
left: 10px;
}
.rightButton {
right: 10px;
}
}
Originally I thought it would be cool to have the left/right buttons superimposed on every image but I'm entirely content with having them on the edges of the viewport.
Here's the end result:

Image card hover effect width issue

In the code below, I have an image card with a hover effect. On hover, I'd like the black box to cover the complete image by default. In the code below, the black box does not cover the complete image unless the title or description text wraps two a second line.
What is the best way to get the black box to fill the complete width of the parent element ".page-card" even without content inside of it? I have tried:
width: 100%, flex direction, clears, table hacks, and many other tips I found without any luck. Any help would be appreciated.
Quick note: for .page-card figcaption I'm using an image on the site so the cover properties are needed.
.page-card {
overflow: hidden;
text-align: left;
margin-top: 30px;
}
.page-card a {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 2;
}
.page-card * {
-webkit-box-sizing: border-box;
box-sizing: border-box;
-webkit-transition: all 0.35s ease;
transition: all 0.35s ease;
}
.page-card img {
object-fit: cover;
width: 100%;
}
.page-card figcaption {
position: absolute;
top: calc(77%);
height: 100%;
background-color: black;
/* the site uses an image here I filled it with black for the code snip */
background-size: cover;
border-top: 1px solid #333;
margin-right: 15px;
padding: 35px 25px 65px;
color: white;
}
.page-card:hover figcaption,
.page-card.hover figcaption {
top: 0px;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container">
<!--Example 1 not spanning dark hover color 100% width-->
<div class="row d-flex flex-row">
<figure class="col-md-6 col-xl-4 page-card">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/331810/sample45.jpg" width="880" height="640">
<figcaption>
<h1>Title</h1>
<p>Descrition</p>
<button type="button" class="btn btn-outline-light itm-space">Learn More</button>
</figcaption>link
</figure>
</div>
<!--Example 2 does cover 100% width when text wraps to a second line-->
<div class="row d-flex flex-row">
<figure class="col-md-6 col-xl-4 page-card">
<img src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/331810/sample45.jpg" width="880" height="640">
<figcaption>
<h1>Title</h1>
<p>Descrition Text that continues to wrap to a second line and fills the complete width like I want it to by default</p>
<button type="button" class="btn btn-outline-light itm-space">Learn More</button>
</figcaption>
</figure>
</div>
</div>
You need to give to give to the "hover" div width :100%:
.page-card figcaption {width:100%}
When an element is given position:absolute is no longer a "block" element with default widh 100%.
Once you do it, you may notice it takes more room than the image below. That is becouse the image parent has padding and you are not using the rule box-sizing:border-box If you add this to the top of you css sheet it should solve your problem.
* {box-sizing:border-box}
Adding:
.page-card figcaption {width:100%}
resolved the width issue but created 30px of overflow because the parent elements padding was not being respected with absolute positioning.
.page-card figcaption {clip-path: inset(0px 30px 0px 0px)}
The code above will clip the overflow.

Why is my container height not fitting to content?

I cannot figure out why my container (main-container) background is not stretching with the content inside. It looks like the container background is stuck on initial view height. When I scroll pass the initial view height, the rest of it is white.
Here is the css
.main-container {
margin: 0;
padding: 0;
font-family: 'montserrat';
height: fit-content;
}
.main {
position: absolute;
top: 65%;
left: 50%;
transform: translate(-50%, -50%);
width: 400px;
background: greenyellow;
border-radius: 10px;
margin-bottom: 40px;
padding-bottom: 20px;
}
<div class="main-container">
<div class="main">
<h1>Signup</h1>
<form method="POST">
<div class="txt-field">
<input type="text" required>
<span></span>
<label>First Name</label>
</div>
<h1>Upload Image</h1>
<button class="btn btn-primary">Upload<i class="fa fa-upload fa-1x"></i></button>
<input type="submit" value="Signup">
</form>
</div>
</div>
This is what it looks like initially.
This is what it looks like when I scroll down
The reason is that you have position: absolute on your .main class - any elements positioned absolutely will be taken out of the regular document flow and will have no effect on the layout of their parent(s).
It looks like you are using absolute position to try and center the .main element. Have you considered using a flexbox on .main-container instead? Using a flexbox with justify-content: center and align-items: center is an easy way to center an element inside its parent while keeping the regular document flow.

Centering a div in Skeleton

For a project of mine, I'm using Skeleton Boilerplate for the first time. And I'm looking for the best practice of centring a div in Skeleton without bashing into the rules of Skeleton.
At the moment, I've the following structure for a login page.
HTML:
<div class="container">
<div class="sixteen columns vertical-offset-by-one">
<div id="loginBox">
<img src="images/yeditepeLogo.png" alt="Yeditepe Logo" class="yeditepeLogo" />
<form action="" id="loginForm">
<input type="text" name="username" required placeholder="username" class="loginTextField">
<input type="password" name="password" required placeholder="password" class="loginTextField">
<input type="submit" value="Log In" class="loginButton" />
</form>
</div><!-- loginBox -->
</div><!-- sixteen columns -->
<div class="sixteen columns">
<p align="center">Click here to register</p>
</div>
</div><!-- container -->
CSS:
#loginBox, #registrationBox {
width: 470px;
height: 450px;
background-color: white;
left: 245px; */
top: 20px; */
position: relative;
margin: 0px auto; }
#registrationBox {
height: 500px; }
.yeditepeLogo {
position: relative;
left: 40px;
top: 33px; }
#loginForm, #registrationForm {
position: relative;
top: 45px; }
.loginTextField, .registrationTextField {
position: relative;
height: 40px;
width: 388px;
left: 40px;
border-color: #dedede;
border-style: solid;
border-width: 1px;
margin-bottom: 10px;
text-align: left;
font-size: 18px;
text-indent: 10px;
-webkit-appearance: none; }
.loginTextField:focus, .registrationTextField:focus {
outline-color: #ff9800;
outline-style: solid;
outline-width: 1px;
border-color: white; }
.loginTextField:nth-child(2), .registrationTextField:nth-child(3) {
margin-bottom: 40px; }
.loginButton, .registrationButton {
background-color: #77a942;
position: relative;
border: none;
width: 390px;
height: 60px;
left: 40px;
color: white;
font-size: 24px;
text-align: center;
opacity: 0.8; }
.loginButton:hover, .registrationButton:hover {
opacity: 1; }
As you can see, that #loginBox has a fixed width/height and it should always be on the centre of the page. margin: 0px auto code gives it the horizontal centring. But is it the best practice in Skeleton? Does Skeleton provide a better way?
Also how can I provide it's vertical centring?
There's actually a built in way of centering divs in Skeleton.
<div class="sixteen columns">
<div class="four columns offset-by-six">
<p>Lorem ipsum dolor sit amet.</p>
</div>
</div>
The offset-by-six in this case can be altered from one to fifteen, and offsets the column at hand by as many columns as entered. As a neat feature, the offsetting is not affecting alignment when smaller screens are used.
To clarify: This doesn't center the actual content in the div, but centers the div itself.
I know it has been a while since this question was asked, but maybe somebody else can use the answer.
I was able to accomplish centering with Skeleton by filling one-third column class with a space, then the next one-third column class with content, then another one-third column class with a space again.
<div class="one-third column"> </div>
<div class="one-third column"><p>Center of the screen.</p></div>
<div class="one-third column"> </div>
You can set the container to
.container {
position: absolute;
top: 50%;
left: 50%;
margin-left: -43 //replace with half of the width of the container
margin-top: -52 //replace with half of the height of the container
}
set the parent container or element to position: relative;
Here's a good article about How to Center Anything With CSS
Asus3000's answer is good as that is what I do and it works well. I would only add that on mobile, it adds quite a bit of unwanted vertical space. To avoid mobile vertical space, I use a class .filler and hide it on mobile.
HTML
<div class="one-third column filler"> </div>
<div class="one-third column"><p>Center of the screen.</p></div>
<div class="one-third column filler"> </div>
CSS
/* or whatever mobile viewport */
#media only screen and (max-width: 960px) {
.filler { display: none}
}
A way I believe works pretty good is:
<div class="container">
<div class="row">
<div class="two-half column">
centered div content
</div>
</div>
</div>
This makes the div centered and responsive. You can change margin-top to make it all the way in the middle, however changing width will (of course) not make it centered anymore.
Correct me if I'm wrong but this works for me! :)

Shrink a div to it's horisontal center

I am trying to implement a CSS3 animation on my site where 2 divs would squeeze together another div with a background image. It's pretty hard to explain, so I made a quick video. Please note that the problem I want to solve is present on this video.
What I'd like to do is when animating the height of a div, it wouldn't shrink to it's horisontal center instead of it's top.
Can this be done in any way?
My HTML:
<div id="container">
<div id="top-bar">
<ul id="nav">
<li>Főoldal
</li>
<li>Szolgáltatások
</li>
<li>Portfólió
</li>
<li>Kapcsolat
</li>
</ul>
</div>
<div id="content">
<div id="card">
<!-- The orange card : irrelevant -->
</div>
<div id="main">
<div id="inner-content"></div>
</div>
</div>
<div id="bottom-bar">
<div id="logo">
<!-- Logo Image -->
</div>
</div>
</div>
Please check the jsFiddle examples for the full code.
jsFiddle code
jsFiddle Full Screen Result
I have created a fiddle here. Every time you click the button it will add/remove the class that has the scaling transform.
CSS:
.box {
width: 300px;
height: 300px;
background: black;
-webkit-transition: all .6s ease-in-out;
transition: all .6s ease-in-out;;
}
.box-change {
-webkit-transform: scale(0,0);
}
JS:
$(function() {
$("#bt").click(function() {
$(".box").toggleClass("box-change");
});
});
HTML:
<div class="box"></div>
<input type="button" value="Let's Do This Thing" id="bt">
You can change CSS to this:
.box-change {
-webkit-transform: scale(1,0);
}
for shrinking to "horizontal center" effect.
See this demo
fiddle
The CSS is:
div {
width: 200px;
position: absolute;
}
.mid {
background: url("http://placekitten.com/200/300");
height: 200px;
top: 100px;
-webkit-transition: all 2s;
transition: all 2s;
}
.top {
top: -100px;
height: 100px;
background-color: gray;
}
.bottom {
bottom: -100px;
height: 100px;
background-color: gray;
}
.mid:hover {
height: 0px;
margin-top: 100px;
background-position: 0px -50px;
}
The trick is to modify the height, and at the same time change the margin-top so that the center stays at the same place. And at the same time change the background position, also accordingly.
I have done this effect because this is what I saw in the video, even though your question seems to ask for the background shrinking. If what you want is the later, please say so.