Center a div more intelligently with CSS [duplicate] - html

This question already has answers here:
How to center a "position: absolute" element
(31 answers)
Closed 5 years ago.
I'm centering an object with the following code:
.object {
width: 70%;
height: 70%;
position: absolute;
top: 50%;
left:50%;
/* these are the lines to which I will refer */
margin-top: -350px;
margin-left: -350px;
}
I'm using margin top and left to subtract the half of the object size but that size is given as a percentage. So my question is there is a way to assign these margins So that I don't have to change them manually every time I change the box size?

To me, best option you have is to use the transform:translate property.
.object {
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
No need ta calculate the width/2 and height/2 margin anymore.
And if you're using SASS, here is a magic #mixin to use :
#mixin transform($transforms) {
-moz-transform: $transforms;
-o-transform: $transforms;
-ms-transform: $transforms;
-webkit-transform: $transforms;
transform: $transforms;
}
#mixin center($position: "both") {
position: absolute;
#if $position == "vertical" {
top: 50%;
#include transform(translateY(-50%));
}
#if $position == "horizontal" {
left: 50%;
#include transform(translateX(-50%));
}
#if $position == "both" {
top: 50%;
left: 50%;
#include transform(translate(-50%, -50%));
}
}
Then, simply use
.object {
// both vertical and horizontal
#include center;
// only vertical
#include center(vertical);
// only horizontal
#include center(horizontal);
}

One of the many ways - use transform property to center the element - see demo below:
.object {
width: 70%;
height: 70%;
position: absolute;
top: 50%;
left:50%;
border: 1px solid red;
transform:translate(-50%, -50%);
}
<div class="object">Two</div>

You should use flex.
HTML
<body>
<div class="square"></div>
</body>
CSS
body{
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.square{
width: 200px;
height: 200px;
background-color: red;
}

.main_div{
width:200px;
height:200px;
border:thin black solid;
position:relative;
}
.main_div .object {
width: 70%;
height: 70%;
position: absolute;
transform:translate(-50%, -50%);
top: 50%;
left:50%;
border: thin red solid;
}
<div class="main_div">
<div class="object">Object Div Text</div>
</div>
Hope this helps.

Why not use margin: 0 auto?
.object {
width: 70%;
height: 70%;
position: absolute;
top:0;
left:0;
right:0;
bottom:0;
margin:0 auto;
}
https://jsfiddle.net/p9hy06tg/4/

Related

How to set ribbon on image by stacking it in a div?

I currently have an ng-repeat that looks like this:
<div class="repeaterDiv" data-ng-repeat="item in itemArray">
<div class="wrapper">
<img class="imageClass" ng-src="{{item.image}}"/>
<div class="corner-ribbon bottom-right sticky green shadow">Changed</div>
</div>
</div>
Here is the CSS pulled from this codePen:
.corner-ribbon{
width: 200px;
background: #e43;
position: absolute;
top: 25px;
left: -50px;
text-align: center;
line-height: 50px;
letter-spacing: 1px;
color: #f0f0f0;
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
}
.corner-ribbon.sticky{
position: fixed;
}
.corner-ribbon.shadow{
box-shadow: 0 0 3px rgba(0,0,0,.3);
}
.corner-ribbon.bottom-right{
top: auto;
right: -50px;
bottom: 25px;
left: auto;
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
}
.corner-ribbon.green{background: #2c7;}
I am trying to figure out how to get the ribbon to be restricted to the wrapper class. Does anyone know how I can do that? so I'm still using the same ribbon, but instead of being in the bottom right of the screen, it is at the bottom right of the image for which it applies?
you need to use relative/absolute position and reset display of .wrapper to shrink on image. Then add overflow:hidden to cut off edges of ribbon:
.corner-ribbon {
width: 200px;
background: #e43;
position: absolute;
top: 25px;
left: -50px;
text-align: center;
line-height: 50px;
letter-spacing: 1px;
color: #f0f0f0;
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
}
.corner-ribbon.sticky {
position: absolute;
}
.corner-ribbon.shadow {
box-shadow: 0 0 3px rgba(0, 0, 0, .3);
}
.corner-ribbon.bottom-right {
top: auto;
right: -50px;
bottom: 30px;
left: auto;
transform: rotate(-45deg);
-webkit-transform: rotate(-45deg);
}
.corner-ribbon.green {
background: #2c7;
}
.wrapper {
position: relative;
display: table-cell;/* or inline-block or float */
overflow: hidden;
}
img {
display: block;
}
<div class="repeaterDiv" data-ng-repeat="item in itemArray">
<div class="wrapper">
<img class="imageClass" ng-src="{{item.image}}" src="http://lorempixel.com/300/200" />
<div class="corner-ribbon bottom-right sticky green shadow">Changed</div>
</div>
</div>
The class has fixed positioning.
.corner-ribbon.sticky{
position: fixed;
}
So for exact css you may not be able to attach ribbon to each img, rather ribbon would go to specific place in window only. However, you can adjust css a bit. Make wrapper class relative, and .corner-ribbon.sticky absolute position. Then adjust your css fot top/bottom/left/right properties to align them.
.wrapper{
position: relative;
}
.wrapper .corner-ribbon.sticky{
position: absolute;
/* put top/bottom/left/right values here*/
}

Full width overlapping triangles

I currently need to make something with CSS that would look like this:
I managed to do it with this:
.top {
position: relative;
}
.top .gray-bar {
position: absolute;
width: 100%;
height: 50px;
background-color: #cdcbcc;
-ms-transform: rotate(1.2deg);
transform: rotate(1.2deg);
margin-top: -25px;
z-index: 2;
}
.top .cyan-bar {
position: absolute;
width: 100%;
height: 90px;
background-color: #2ca1ab;
-ms-transform: rotate(-3deg);
transform: rotate(-3deg);
z-index: 1;
margin-top: -30px;
margin-left: -400px;
}
.top .purple-bar {
position: absolute;
width: 100%;
height: 50px;
background-color: #b71e4c;
-ms-transform: rotate(0.7deg);
transform: rotate(0.7deg);
margin-top: -5px;
z-index: 0;
}
<div class="top">
<div class="gray-bar"></div>
<div class="cyan-bar"></div>
<div class="purple-bar"></div>
</div>
However, when I resize my window, at some point of time, the "cyan" triangle is causing issue because of the margins and the rotation. Therefore, I added some media queries to modify the rotation angle depending on the width of the screen but I feel that it's a bit "playing around" and that there is a better solution to achieve this.
I tried using borders to make the overlapping triangles but as it cannot be expressed as percentage, I'm a bit stuck. Indeed, the goal is that the result looks about the same whatever the user's screen resolution.
Is there a better solution than mine ?
Considering that the .top element uses the full viewport width, you can use viewport percentage units for the borders. This will make the triangles relative to the viewport width.
See this example with one div :
body,html{margin:0;padding:0;}
.topBar{
position:relative;
height:35px;
border-bottom:30px solid transparent;
border-right:100vw solid #B71E4C;
}
.topBar:before, .topBar:after{
content:'';
position:absolute;
top:0; left:0;
height:15px;
}
.topBar:before{
border-bottom:50px solid transparent;
border-left:100vw solid #2CA1AB;
}
.topBar:after{
border-bottom:40px solid transparent;
border-right:100vw solid #CDCBCC;
}
<div class="topBar"></div>
Maybe this help you, but, #web-tiki its the best solution, using pseudo-selectors: :before & :after
.top {
overflow: hidden;
height: 90px;
}
.top .gray-bar {
position: relative;
width: 100%;
height: 50px;
background-color:#cdcbcc;
-ms-transform: rotate(1.3deg);
transform: rotate(1.3deg);
margin-top:-35px;
z-index: 2;
}
.top .cyan-bar {
position: relative;
width: 150%;
height: 50px;
background-color:#2ca1ab;
-ms-transform: rotate(-2deg);
transform: rotate(-2deg);
z-index:1;
top: -5px;
margin-top:-30px;
margin-left:-100px;
}
.top .purple-bar {
position: relative;
width: 100%;
height: 20px;
background-color:#b71e4c;
-ms-transform: rotate(0.7deg);
transform: rotate(0.7deg);
margin-top: -20px;
z-index:0;
}
<div class="top">
<div class="gray-bar"></div>
<div class="cyan-bar"></div>
<div class="purple-bar"></div>
</div>

How can I center align a popup(div) on screen using css, when its content's height/width are not fixed?

I was able to center align it properly when the content height and width were known, but if the popup content can vary in height and width, I cant think of any way to do this. Is there any?
Im doing this so that I can have a generic popup component, which will accept content of any height or width, starting from one line to screen max width/height.
Note: No javascript. Im looking for pure CSS methods.
The modern and bulletproof way to achieve this in late 2021 is with either flexbox or grid:
<-- HTML -->
<section class="parent flex"><div>Flex</div></section><-- OR -->
<section class="parent grid"><div>Grid</div></section>
<-- CSS -->
<style>
.parent.flex {
display: flex;
align-items: center;
justify-content: center;
}
.parent.grid {
display: grid;
place-content: center; /* shorthand for justify-content and align-content */
}
.parent {
width: 100vw; /* whatever */
height: 50vh; /* whatever */
}
</style>
Previous answer (Aug 2015):
There are a bunch of ways to do this, the easiest is using transforms:
// HTML
<div id="parent"><div id="child"></div></div>
// CSS
#parent {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
#child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); // needs browser-prefixes
}
Working dynamic example below. Alternative solutions here: http://codepen.io/shshaw/full/gEiDt
function padding(val) {
document.querySelector("h1").style.padding = val + "em";
}
function text(val) {
document.querySelector("h1").innerText = val;
}
.container {
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.9);
position: absolute;
height: 100%;
width: 100%;
overflow: scroll;
}
h1 {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
padding: 1em;
}
input,
textarea {
position: relative;
}
<div class="container">
<h1>the middle.</h1>
</div>
<textarea type="text" min=1 max=5 step=.1 oninput="text(this.value)">the middle.</textarea>
<input type="range" min=1 max=5 step=.1 value=1 oninput="padding(this.value)">
Note: The above won't work in IE8.
Try this :
Demo: http://jsfiddle.net/GCu2D/834/
CSS:
html, body {
height:100%;
width:100%;
}
#popup {
position:fixed;
top:0;
left:0;
right:0;
bottom:0;
text-align:center;
}
#popup>div.wrapper {
position: absolute;
top: 50%;
left:0;
right:0;
transform: translateY(-50%);
display:block;
text-align:center
}
#popup .content {
display:inline-block;
border:1px solid blue //For visual feedback.
max-width:50%; //In case you want to restrict the div width
}
HTML:
<div id="popup">
<div class="wrapper">
<div class="content">Hello this is a sample content</div>
</div>
</div>
Replace the ID with a class in case you want multiple dialogs
For vertical alignment have you looked at this?
position: relative;
top: 50%;
transform: translateY(-50%);
For horizontal alignment simply apply text-align: center to the containing element.
You can check with the below link.
Fiddle
.reveal-modal {
background:#e1e1e1;
margin: 0 auto;
width:160px;
position:relative;
z-index:41;
top: 25%;
padding:30px;
-webkit-box-shadow:0 0 10px rgba(0,0,0,0.4);
-moz-box-shadow:0 0 10px rgba(0,0,0,0.4);
box-shadow:0 0 10px rgba(0,0,0,0.4);
}

Position small images in a circular array around large image

I am trying to find a clean way to float multiple image bubbles around a large image in a circular manner.
There will probably be no more than six bubbles per image, but I want to find a recursive and responsive way to position these bubbles around any sized parent image. These parent images will be equal height/width and no lower than 100px. (100 x 100, 130 x 130, ect..)
Not sure how to do this best while making it responsive to the screen size and supported on all main browsers. I also would prefer if this can be done with pure css/sass, and without an external library.
Code so far: http://jsfiddle.net/qatkr261/1/
HTML
<div id="body">
<div id="background">
<div class="company-container">
<img class="company" src="https://placeholdit.imgix.net/~text?txtsize=10&txt=120%C3%97120&w=120&h=120" />
<img src="https://placeholdit.imgix.net/~text?txtsize=10&txt=50%C3%9750&w=50&h=50" class="company-side-bubble" />
<img src="https://placeholdit.imgix.net/~text?txtsize=10&txt=50%C3%9750&w=50&h=50" class="company-side-bubble" />
<img src="https://placeholdit.imgix.net/~text?txtsize=10&txt=50%C3%9750&w=50&h=50" class="company-side-bubble" />
</div>
<div class="company-container">
<img class="company" src="https://placeholdit.imgix.net/~text?txtsize=10&txt=120%C3%97120&w=120&h=120" />
<img src="https://placeholdit.imgix.net/~text?txtsize=10&txt=50%C3%9750&w=50&h=50" class="company-side-bubble" />
<img src="https://placeholdit.imgix.net/~text?txtsize=10&txt=50%C3%9750&w=50&h=50" class="company-side-bubble" />
<img src="https://placeholdit.imgix.net/~text?txtsize=10&txt=50%C3%9750&w=50&h=50" class="company-side-bubble" />
</div>
</div>
</div>
CSS (#body and #background are just demo containers)
#body {
height:500px;
width:500px;
}
#background {
background:#F9F9F9;
}
.company-container {
display:inline-block;
padding:20px;
}
.company {
border-radius: 80px;
display: block;
height: 130px;
width: 130px;
margin: 15px auto;
background:#E5E5E5;
}
.company:hover {
transform: scale(1.2);
cursor:pointer;
}
.company-side-bubble {
border-radius: 30px;
width: 40px;
height: 40px;
position:absolute;
top:0;
border: solid 1px red;
}
.company-side-bubble:hover {
transform: scale(1.2);
cursor:pointer;
}
.company-side-bubble:nth-of-type(2) {
margin-top: 15px;
margin-left: 44px;
}
.company-side-bubble:nth-of-type(3) {
margin-top: 34px;
margin-left: 91px;
}
.company-side-bubble:nth-of-type(4) {
margin-left: 109px;
margin-top: 81px;
}
You can do that using percents instead of pixels as unit.
Also you will need to to use translateX and translateY to compensate for the small images width and height.
Here, i have done it for you: http://jsfiddle.net/qatkr261/2/
.company-side-bubble:nth-of-type(2) {
top: 0%;
left: 50%;
transform: translateX(-50%) translateY(25%);
}
.company-side-bubble:nth-of-type(3) {
top: 25%;
right: 25%;
transform: translateX(50%) translateY(-50%);
}
.company-side-bubble:nth-of-type(4) {
right: 0%;
top: 50%;
transform: translateX(-25%) translateY(-50%);
}
.company-side-bubble:nth-of-type(5) {
top: 75%;
right: 25%;
transform: translateX(50%) translateY(-50%);
}
.company-side-bubble:nth-of-type(6) {
bottom: 0%;
left: 50%;
transform: translateX(-50%) translateY(-25%);
}
.company-side-bubble:nth-of-type(7) {
bottom: 25%;
left: 25%;
transform: translateX(-50%) translateY(50%);
}
.company-side-bubble:nth-of-type(8) {
top: 50%;
left: 0%;
transform: translateX(25%) translateY(-50%);
}
.company-side-bubble:nth-of-type(9) {
top: 25%;
left: 25%;
transform: translateX(-50%) translateY(-50%);
}
I have altered also some css on other classes to make it work, most important: .company do not have top:0 anymore and it's margin now is uniform (all four sides equal) and have grown, .company-container lost padding (compensated by .company margin) and gained position:relative
UPDATE:
If you want the bubbles to spread as well you will need to make additional selector for each one as follows:
.company:hover ~ .company-side-bubble:nth-of-type(2) {
top: -5%;
}
.company:hover ~ .company-side-bubble:nth-of-type(3) {
top: 20%;
right: 20%;
}
.company:hover ~ .company-side-bubble:nth-of-type(4) {
right: -5%;
}
...

Align rotated div with another div

I have a main div (the red div in the fiddle) that has a smaller vertical tab on the side (the blue div in the fiddle).
The RED div is standard BUT the Blue div is rotated through 90 degrees (as I need to have vertical text in it). This is where the problems starts.
The red div is vertically positioned at 50% so it is in the middle of the page and locked with scrolling etc.
I want to align the blue div so that the top edge of the blue div is at the same Y position as the top edge of the red div.
I would prefer NOT to use jQuery but can do if required.
Desired output :
Fiddle is here : http://jsfiddle.net/kBKf6/
Here is the code I am using :
<div id="main" style="position: fixed; top: 50%; margin-top: -250px; left:0; height: 500px; width: 450px; background-color:red;">
Main Content Div
</div>
<div id="vertical_div" style="overflow:hidden; position: fixed; left:350px; height:40px; width:200px; margin: auto; background-color:blue; text-align:center; color:white; -webkit-transform: rotate(90deg) translate(-50%, -50%); -moz-transform: rotate(90deg) translate(-50%, -50%); -ms-transform: rotate(90deg) translate(-50%, -50%); -o-transform: rotate(90deg) translate(-50%, -50%); transform: rotate(90deg) translate(-50%, -50%);">
Side Tab
</div>
You don't need JS to align the rotated div. You can define a transform origin in CSS then, it becomes easy to align.
Side note : You can remove the -moz- and -o- vendor prefixes see caniuse
DEMO
HTML :
<div id="main">Main Content Div
<div id="verticaldiv">Side Tab</div>
</div>
CSS :
#main {
position: fixed;
top: 50%;
margin-top: -250px;
left:0;
height: 500px;
width: 450px;
background-color:red;
}
#verticaldiv {
overflow:hidden;
position: absolute;
left:100%;
bottom:100%;
height:40px;
width:200px;
background-color:blue;
text-align:center;
color:white;
-webkit-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg);
-ms-transform-origin:0 100%;
-webkit-transform-origin: 0 100%;
transform-origin: 0 100%;
}
You can also do it without relying on hardcoded sizes that move your div into position, but you need a wrapper around your .verticaldiv
demo:
http://jsfiddle.net/MCr6f/
demo 2:
http://jsfiddle.net/9LtKw/ (to show that different sizes don't matter)
html:
<div class="one">
Hello
<div class="pivot">
<div class="two">
Pretty!
</div>
</div>
</div>
css:
.one {
background: red;
position: relative;
float: left;
/*strange and difficult sizes*/
font-size: 3.237827em;
padding: 10px;
}
.pivot {
position: absolute;
top: 0;
right: 0;
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
transform: rotate(90deg);
width: 0px;
height: 0px;
}
.two {
background: blue;
color: white;
position: absolute;
left: 0;
bottom: 0;
/*strange and difficult sizes*/
font-size: 12px;
padding: 0.3em;
}