How to vertically center a dynamic height fixed element? - css

I'm making an overlay window thing and I'm trying to vertically center the message in the center of the screen.... this is my CSS thus far:
#overlay {
position: fixed;
right: 0;
left: 0;
width: 276px;
margin: 0px auto;
padding: 12px 16px;
font-size: 14px;
color: #6d748b;
background-color: #fff;
border: 2px solid #b9c1d6;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
z-index: 7500;
}

This is one way (assuming you're only trying to center one element):
#overlay {
top: 50%;
-ms-transform: translateY(-50%);
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-o-transform: tranlslateY(-50%);
transform: translateY(-50%);
}
Updated fiddle

Related

Modal window in absolute center of viewport | Safari and IOS issue

I have a problem that's driving me insane, and it has done so for quite some time. I've spent days trying to figure this one out with no success. Google is basically purple to me now. Additionally I fear the answer might be embarrassingly easy - but I'm about to go drown myself so here goes:
The problem:
I use pure css modal windows on my site. They are set to be absolutely positioned using margin: 0 auto; and translateY(-50%); like so:
margin: 0px auto;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
I am using named anchors to hide/show the modal windows.
This works beautifully in basically every browser - I get the modal windows to appear and disappear like they are supposed to, in the center of the VIEWPORT of my browser window. In Safari and on iPhones and iPads however, it seems my modal windows get absolutely centered relative to the ENTIRE PAGE/DOCUMENT.
So, if my page has a vertical scrollbar, clicking the anchor link and showing the modal window makes the BROWSER WINDOW jump as well - in order to display the modal window in the absolute center of the entire page.
I include my modal windows just before the closing body tag like so:
<?php
include 'layout/elements/modal/users_online.php';
include 'layout/elements/modal/requests.php';
include 'layout/elements/modal/notifications.php';
include 'layout/elements/modal/messages.php';
include 'layout/elements/copyright.php';
include 'layout/elements/modal/developer.php';
?>
</body>
</html>
This is the code of my modal windows:
.modal {
display: none;
position: fixed;
z-index: 9999;
width: 100%;
height: 100%;
top: 50%;
left: 0;
color: #333333;
}
.modal:target {
display: block;
outline: none;
}
.modal .big_container {
width: -webkit-min-content;
width: -moz-min-content;
width: min-content;
width: 785px;
height: 515px;
margin: 0px auto;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
padding: 20px;
background-color: #ffffff;
box-shadow: 0px 1px 26px -3px #777;
border-radius: 10px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
text-align: center;
}
So thanks to weBer (seriously thank you so much :D) I was able to figure out the answer.
This works:
.modal {
display: none;
position: fixed;
z-index: 9999;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.modal:target {
display: block;
outline: none;
}
.modal .big_container {
position: fixed;
display: block;
width: -webkit-min-content;
width: -moz-min-content;
width: min-content;
min-width: 785px;
max-width: 785px;
min-height: 515px;
max-height: 515px;
margin: 0px auto;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
padding: 20px;
background-color: #ffffff;
box-shadow: 0px 1px 26px -3px #777777;
border-radius: 10px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
text-align: center;
}
Am not sure this is your answer but here it goes.
Am taking .modal as your pop up overlay background. So change its code to -
.modal {
display: none;
position: fixed;
z-index: 9999;
width: 100%;
height: 100%;
top: 0;
left: 0;
color: #333333;
}
And .modal .big_container- which is our content box should have the following style.
.modal .big_container {
width: -webkit-min-content;
width: -moz-min-content;
width: min-content;
width: 785px;
height: 515px;
display:inline-block;
position:absolute;
left:50%;
top:50%;
-webkit-transform: translateY(-50%,-50%);
-ms-transform: translateY(-50%,-50%);
transform: translateY(-50%,);
padding: 20px;
box-sizing:border-box;
background-color: #ffffff;
box-shadow: 0px 1px 26px -3px #777;
border-radius: 10px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
text-align: center;
}
Check if it works for. I think this might, I use this in my most of the projects.

How can I create this particular shape?

Is there an easier or better way to create this particular shape/combination of shapes in CSS3 than what am I currently doing? I have tried a few different things already.
The downward facing triangle should be sitting just below the three lines, but I can't seem to get it there.
I want it to look like this:
https://jsfiddle.net/s6bcjzjr/
.triangle-container {
top: 0;
width: 30px;
height: 40px;
position: relative;
border-bottom: 2px solid #e74c3c;
}
.triangle {
position: relative;
margin: auto;
top: 30px;
left: 0;
right: 0;
width: 21px;
height: 21px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-ms-transform: rotate(45deg);
border-right: 2px solid #e74c3c;
border-bottom: 2px solid #e74c3c;
}
.line {
width: 30px;
position: relative;
border-bottom: 2px solid #e74c3c;
margin-top: 3px;
}
<a href="#" class="open">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
<div class="triangle-container">
<div class="triangle"></div>
</div>
</a>
I switch the triangle container's border to top and adjusted the margins
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.triangle-container {
top: 0;
width: 30px;
height: 40px;
position: relative;
border-top: 2px solid #e74c3c;
margin-top: 3px;
}
.triangle {
position: relative;
margin: auto;
top: -10.5px;
left: 0;
right: 0;
width: 21px;
height: 21px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-ms-transform: rotate(45deg);
border-right: 2px solid #e74c3c;
border-bottom: 2px solid #e74c3c;
}
.line {
width: 30px;
position: relative;
border-bottom: 2px solid #e74c3c;
margin: 3px 0 0 0;
}
<a href="#" class="open">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
<div class="triangle-container">
<div class="triangle"></div>
</div>
</a>
Using SVG:
You can create this easily using SVG. There is nothing complex and all that you would need is three line elements and one path element.
All three line elements have two co-ordinates where (x1,y1) represent the starting point of the line and (x2,y2) represent the ending point of the line.
The path element takes a path (d) and it value can be interpreted as follows:
M5,20 - Move to the point which is 5px to the right of the container and 20px down.
L95,20 - Draw a line from the previous point (5,20) to (95,20).
L50,45 - Draw a line from the previous point (95,20) to (50,45).
z - Close the path. That is, draw a line connecting the point (50,45) and the starting point.
svg {
height: 100px;
width: 50px;
}
line,
path {
stroke: #e74c3c;
stroke-width: 2;
}
path {
fill: none;
stroke-linejoin: bevel;
}
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
<g id='graphic'>
<line x1='5' y1='5' x2='95' y2='5' />
<line x1='5' y1='10' x2='95' y2='10' />
<line x1='5' y1='15' x2='95' y2='15' />
<path d='M5,20 L95,20 L50,45z' />
</g>
</svg>
Using CSS with single element:
You can achieve the same shape using a single element also with CSS. Below is a sample snippet for the same. Below is an explanation of how the shape is achieved.
The parent anchor tag which has the height and width of the container.
The :before pseudo-element which is positioned absolutely with respect to the container and is 20px tall. The background of this element is a linear-gradient which has the required color for 2px and is transparent for the remaining part. Gradients by default repeat to fill its container and so this single background pattern produces the three lines.
The :after element is again positioned absolutely with respect to the container. This pseudo-element is then rotated such that its left and bottom borders produce angled parts of the triangle. Another linear-gradient background produces the top line of the triangle.
I have calculated height and width of the :after pseudo using Pythagoras theorem. If container is not a square then you have to manually calculate the values.
a {
position: relative;
display: inline-block;
height: 50px;
width: 50px;
}
a:before {
position: absolute;
content: '';
top: 3px;
left: 0px;
height: 20px;
width: 100%;
background: linear-gradient(to bottom, #e74c3c 2px, transparent 2px);
background-size: 100% 5px;
}
a:after {
position: absolute;
content: '';
top: 50%;
left: 50%;
height: calc(50px / 1.414);
width: calc(50px / 1.414);
border-bottom: 2px solid #e74c3c;
border-left: 2px solid #e74c3c;
transform: translateX(-50%) translateY(-50%) rotate(-45deg);
background: linear-gradient(to top right, transparent 46%, #e74c3c 46%, #e74c3c 50%, transparent 50%);
}
<a href='#'></a>
.triangle-container {
top: -35px;
width: 30px;
height: 40px;
position: relative;
border-bottom: 2px solid #e74c3c;
}
https://jsfiddle.net/s6bcjzjr/6/
i've updated your fiddle and now your shape looks perfect. What I did is changed the border-bottom to border-top of the triangle-container, and adjusted height and margin to align the triangle perfectly
here is the fiddle - https://jsfiddle.net/s6bcjzjr/5/
The answer is:
.triangle-container {
top: -36px;
}
See it here:
.triangle-container {
top: -36px;
width: 30px;
height: 40px;
position: relative;
border-bottom: 2px solid #e74c3c;
}
.triangle {
position: relative;
margin: auto;
top: 30px;
left: 0;
right: 0;
width: 21px;
height: 21px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-ms-transform: rotate(45deg);
border-right: 2px solid #e74c3c;
border-bottom: 2px solid #e74c3c;
}
.line {
width: 30px;
position: relative;
border-bottom: 2px solid #e74c3c;
margin-top: 3px;
}
<a href="#" class="open">
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
<div class="triangle-container">
<div class="triangle"></div>
</div>
</a>
A one element method using before and after (fiddle):
.down-arrow {
display: inline-block;
position: relative;
width: 30px;
height: 14px;
border-top: 2px solid #e74c3c;
border-bottom: 2px solid #e74c3c;
}
.down-arrow::before {
display: block;
position: absolute;
top: 3px;
right: 0;
left: 0;
height: 3px;
border-top: 2px solid #e74c3c;
border-bottom: 2px solid #e74c3c;
content: '';
}
.down-arrow::after {
display: block;
position: relative;
top: 4px;
left: 0;
right: 0;
width: 21px;
height: 21px;
margin: 0 auto;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-ms-transform: rotate(45deg);
border-right: 2px solid #e74c3c;
border-bottom: 2px solid #e74c3c;
content: '';
}
.triangle-container {
top: 0px;
width: 30px;
height: 1px;
position: relative;
border-top: 2px solid #e74c3c;
margin-top: 3px;
}
.triangle {
position: absolute;
margin: auto;
top: -12px;
left: 0;
right: 0;
width: 21px;
height: 21px;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-moz-transform: rotate(45deg);
-o-transform: rotate(45deg);
-ms-transform: rotate(45deg);
border-right: 2px solid #e74c3c;
border-bottom: 2px solid #e74c3c;
}
.line {
width: 30px;
position: relative;
border-bottom: 2px solid #e74c3c;
margin-top: 3px;
}

Popup window width resizing when not needed

So I have this thing popup-window on my homepage that I fill with some content. The problem I'm having with it is that it's resizeing way to early.
I don't want the popup to resize before getting to big for the window to handle.
How am I going to solve this? Been at it for some time, can't figure it out.
You can try it out in the jsiffle url, resize the width of the preview window and you'll see it shrinks before it's even needed.
http://jsfiddle.net/82gvnamL/
CSS:
#popup {
position: absolute;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.75);
z-index: 2;
}
#popup #loading {
height: 32px;
width: 32px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
background: url('../img/ajax-loading.gif') no-repeat;
background-size: 32px 32px;
display: inline-block;
}
#popup #container {
max-width: 95%;
max-height: 95%;
padding: 10px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
background: #111;
-moz-border-radius: 10px 10px 10px 10px;
-webkit-border-radius: 10px 10px 10px 10px;
border-radius: 10px 10px 10px 10px;
}
#popup #content {
width: 100%;
font-family: 'Oxygen', sans-serif;
font-size: 12px;
color: #ccc;
text-align: left;
line-height: 16px;
}
#popup #close {
width: 20px;
height: 16px;
padding: 4px 0 0 0;
border: 1px solid #333;
border-radius: 50%;
float: right;
background: #222;
position: absolute;
top: -7px;
right: -7px;
font-family: 'Nunito', sans-serif;
font-size: 12px;
text-align: center;
color: #fff;
line-height: 12px;
cursor: pointer;
}
#popup #close:before {
content: 'X';
}
HTML:
<div id="popup">
<div id="container">
<div id="close"></div>
<div id="content">
<p>Very long string in here that should not get cut off until window width is too small. If you understand what I'm saying.</p>
</div>
</div>
</div>
Try changing the container's width like so"
#popup #container {
max-width: 255px;
width: 75%;
}
So on larger screens it will be a fixed width of 255px and on smaller screens it will shrink to 75% width.

How to create a speech bubble in css?

I would like to create a speech like this,
I try to create using CSS. But I cannot align the top arrow like this. My Code is,
.bubble
{
position: relative;
width: 275px;
height: 40px;
padding: 5px;
background: #C00006;
-webkit-border-radius: 14px;
-moz-border-radius: 14px;
border-radius: 14px;
}
.bubble:after
{
content: '';
position: absolute;
border-style: solid;
border-width: 0 19px 79px;
border-color: #C00006 transparent;
display: block;
width: 0;
z-index: 1;
margin-left: -19px;
top: -79px;
left: 69%;
}
<br><br><br><br>
<div class="bubble"></div>
Online example (on JSFiddle).
You could achieve that by using skewX transform and specifying the origin of the transform as follows:
.bubble {
position: relative;
top: 4.8em;
width: 275px;
height: 40px;
padding: 5px;
background: #C00006;
-webkit-border-radius: 14px;
-moz-border-radius: 14px;
border-radius: 14px;
}
.bubble:after {
content: '';
position: absolute;
border-style: solid;
border-width: 0 19px 79px;
border-color: #C00006 transparent;
display: block;
width: 0;
z-index: 1;
/* top: -79px; */
bottom: 100%; /* better than specifying the top */
right: 38px; /* equal to width of the arrow, for instance */
-webkit-transform: skewX(-45deg);
-moz-transform: skewX(-45deg);
-ms-transform: skewX(-45deg);
-o-transform: skewX(-45deg);
transform: skewX(-45deg);
-webkit-transform-origin: 38px 100%;
-moz-transform-origin: 38px 100%;
-ms-transform-origin: 38px 100%;
-o-transform-origin: 38px 100%;
transform-origin: 38px 100%;
}
<div class="bubble"></div>
It's worth noting that CSS transforms are supported in IE 9 and newer.
You can use the CSS3 skew() method on your :after psuedo selector like this:
.bubble:after {
-ms-transform: skew(-40deg, 0deg);
-webkit-transform: skew(-40deg, 0deg);
transform: skew(-40deg, 0deg);
}
Here's a jsFiddle Demo.
.bubble {
position: relative;
width: 275px;
height: 40px;
padding: 5px;
background: #C00006;
-webkit-border-radius: 14px;
-moz-border-radius: 14px;
border-radius: 14px;
}
.bubble:after {
content: '';
position: absolute;
border-style: solid;
border-width: 0 27px 79px;
border-color: #C00006 transparent;
display: block;
width: 0;
z-index: 1;
margin-left: -19px;
top: -79px;
left: 69%;
-ms-transform: skew(-40deg, 0deg);
-webkit-transform: skew(-40deg, 0deg);
transform: skew(-40deg, 0deg);
}
<br/>
<br/>
<br/>
<br/>
<div class="bubble"></div>
try this http://jsfiddle.net/harshdand/gczu8w4e/
.bubble:after
{
content: '';
position: absolute;
border-style: solid;
border-width: 0 19px 120px;
border-color: #C00006 transparent;
display: block;
width: 0;
z-index: 1;
margin-left: -49px;
top: -79px;
left: 95%;
-ms-transform: (50deg);
-webkit-transform: rotate(50deg);
transform: rotate(50deg);
}
transform: rotate(50deg);
edit
usw skew instead of rotate . see the snippet with minimal CSS
transform: skew(-45deg);
.bubble {
position: relative;
bottom: -70px;
width: 275px;
height: 40px;
padding: 5px;
background: #C00006;
border-radius: 14px;
}
.bubble:after {
content: '';
position: absolute;
border-style: solid;
border-width: 0 19px 79px;
border-color: #C00006 transparent;
width: 1px;
z-index: 1;
bottom: 95%;
left: 79%;
transform: skew(-45deg);
}
<div class="bubble"></div>

How do I center a rotated DIV as a corner banner?

I have a div which I'm using as a corner banner, but I'm having trouble centering the text after the DIV has been rotated 45 degrees. How do I calculate the top and left values so a DIV which is 300px wide is centered in the top left corner of the screen? Here is a snippet of my CSS and HTML:
#cornerBanner {
color: #F47D31;
background-color: #333;
-moz-box-shadow: 2px 2px 20px #888;
-moz-transform: rotate(-45deg);
-moz-transform-origin: 50% 50%;
position: absolute;
width: 300px;
top: 50px;
left: -100px;
text-align: center;
}
<DIV ID="cornerBanner">Beta</DIV>
It is centered. You just need to adjust the positioning of it slightly:
#cornerBanner {
color: #F47D31;
background-color: #333;
-moz-box-shadow: 2px 2px 20px #888;
-moz-transform: rotate(-45deg);
-moz-transform-origin: 50% 50%;
-webkit-transform: rotate(-45deg);
-webkit-transform-origin: 50% 50%;
position: absolute;
width: 300px;
top: 45px;
left: -95px;
text-align: center;
}
http://jsfiddle.net/AlienWebguy/UxzaL/

Resources