CSS Centering is by top left of inner element - html

I'm trying to center an inner element using CSS, and for some reason the inner element is centering based on the top left corner, rather than its center: http://codepen.io/anon/pen/WvxeEo
HTML:
<div class="topic">
<span class="title-box">hello!</span>
</div>
CSS:
.topic {
background-color: #84BACE;
border: 1px solid #e8e8e8;
width:500px;
height:500px;
position: relative;
}
.title-box {
background-color: #000;
color: #fff;
font-size: 60px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);"
}
Is there a way to set it so that it's properly centered? The inner element will be of unknown width/height, as it's dynamic text.
Thanks!

Try this — http://codepen.io/sergdenisov/pen/ZGOzrr:
.topic {
background-color: #84BACE;
border: 1px solid #e8e8e8;
width:500px;
height:500px;
position: relative;
}
.title-box {
background-color: #000;
color: #fff;
font-size: 60px;
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}

I made one simple change to your code here.
I hope this is what you were asking. The reason "hello" was centered in the blue instead of the page was that that span was inside the blue div. I simply moved the span outside of the div.
<div class="topic"></div>
<span class="title-box">hello!</span>

Related

Absolute positioning :after and transforming it not aligning it in center

Hey guys I had to create simple dots on a carousel like so:
And hence I used the following method:
.banner-nav-dots > li > a {
position: relative;
}
.banner-nav-dots > li.active > a:after {
content: '';
background: #6e2c91;
height: 5px;
width: 5px;
display: inline-block;
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%,-50%);
-ms-transform: translate(-50%,-50%);
-o-transform: translate(-50%,-50%);
transform: translate(-50%,-50%);
border-radius: 50%;
}
Now that should have really centered the dot , but as can be seen on THIS LINK, they are not exactly aligning in the center. Why? Why are they not aligning in the center?
Below is a MVCE:
.circle {
position: relative;
box-sizing: border-box;
display: inline-block;
border: 2px solid #6e2c91;
border-radius: 50%;
height: 15px;
width: 15px;
}
.circle:after {
position: absolute;
content: '';
display: inline-block;
height: 5px;
width: 5px;
top: 50%;
left: 50%;
border-radius: 50%;
background: #6e2c91;
transform: translate(-50%, -50%);
}
<div class='circle odd-numbered'></div>
I am more interested in the WHY part. Can somebody explain please?
P.S. this absolute position method combined with transform has always worked for me, but just on this instance its caused this issue and I don't know why. Checked both in FF and Chrome.
The problem seems to be due to a combination of odd numbered dimensions for parent container (height: 15px, width: 15px) and the 50% value for positioning attributes on child (top: 50%, left: 50%). This means that the actual calculated value will be 5.5px ((15px - 4px) / 2) for left and top (15px - 4px due to box-sizing: border-box also being applied on the parent).
When such fractional values are encountered, it looks like the browsers round-off the value. I couldn't find anything about this in the specs (whether it should be a round-up or down) and there aren't many recent articles on the net also about this particular thing. However, I did manage to find this old article which says that each browser treats them differently. Some round it down whereas others round it up. Either ways, the child element is not going to at the exact center.
The fix for this case seems to be to set an even-numbered value for the parent's dimensions.
.circle {
position: relative;
box-sizing: border-box;
display: inline-block;
border: 2px solid #6e2c91;
border-radius: 50%;
}
.odd-numbered {
height: 15px;
width: 15px;
}
.even-numbered {
height: 16px;
width: 16px;
}
.circle:after {
position: absolute;
content: '';
display: inline-block;
height: 5px;
width: 5px;
top: 50%;
left: 50%;
border-radius: 50%;
background: #6e2c91;
transform: translate(-50%, -50%);
}
<h4>Odd Numbered Dimensions - PROBLEM </h4>
<div class='circle odd-numbered'></div>
<h4>Even Numbered Dimensions - NO PROBLEM </h4>
<div class='circle even-numbered'></div>

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*/
}

Scrollable Modal with Max Height that will only be as tall as its contents

I'm trying to get a modal window that will size with its content up to 80% of the height of the window, and then scroll. I also need the close button (represented by the "X" in the top-right) to stay fixed. This is what I have so far:
HTML
<div>
<div class="dialog-overlay"></div>
<div class="dialog" style="left:75%;">
<span class="close">X</span>
<div class="dialog-wrap">
<div class="dialog-content">
<!-- Long amounts of content here -->
</div>
</div>
</div>
</div>
CSS
.dialog-overlay {
background-color: rgb(0, 0, 0);
position: fixed;
z-index: 88;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0.8;
}
.dialog {
background-color: rgb(66, 66, 66);
position: absolute;
height: 80%;
max-height: 80%;
width: 40%;
top: 50%;
left: 50%;
z-index: 89;
border-width: 1px;
border-style: solid;
border-color: #666;
border-radius: 5px;
box-shadow: 4px 4px 80px #000;
transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
-moz-transform: translate(-50%, -50%);
}
.dialog .close {
position: absolute;
top: 0px;
right: 20px;
}
.dialog-wrap {
overflow-y: auto;
height: 100%;
}
.dialog-content {
color: #ccc;
padding: 20px;
}
With this code, I got as far as the codepen below, but I'm stuck. The one on the right works as desired, but then the one on the left, where the content is small, is too big with unnecessary empty space. If I comment out the "height: 80%" from .dialog, the one on the left is fixed, but then the scrolling one on the right ceases to work correctly. I don't want to have to set the height, but it seems to be required for the inner content to scroll for some reason, even though I thought max-height should do it as well.
http://codepen.io/evshell18/pen/QNPyGr

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>

Creating a slopy element

I am trying to achieve this effect in my webpage..
The red box is where I will be placing a menu, I would like the bottom of the red box to be slanted. The section on the right of the slant needs to be transparent as there may be an image in the background where the grey color is.
The only thing I can come up with is to rotate the element but that would also rotate the contents of the element which I do not want.. Only the bottom bg of the red element (which will be a solid color) should be slanted.
you can do it like that, just highlighted the rotated part blue, that you see what happens ;)
you might have to play with the top: and left: values if you change the size
edit: added a small menu example (really small ^^)
jsfiddle link
here is the html part:
<div id="menucontainer">
<ul>
<li>some</li>
<li>menu</li>
<li>here</li>
</ul>
</div>
<div id="rotatedDiv">
</div>
<div id="background"></div>
and here the css part:
#menucontainer{
position: relative;
z-index: 100;
background: red;
height: 100px;
}
#menucontainer ul {
position: absolute;
bottom: 0px;
left: 30px;
}
#menucontainer li {
list-style: none;
margin-left: 10px;
background: #123;
display: inline-block;
}
#rotatedDiv {
z-index: 99;
background: blue;
position: absolute;
top: 14px;
left: -5px;
height: 90px;
width: 200%;
-moz-transform: rotate(-2deg);
-webkit-transform: rotate(-2deg);
-o-transform: rotate(-2deg);
-ms-transform: rotate(-2deg);
transform: rotate(-2deg);
}
#background {
background: green;
}
you might want to modify it in any way you can think of, but the main part should be clear i think ;)
You can do it with a transparent border:
html
<div class="bgone">
<div class="content">This is where the menu would go.</div>
</div>
<div class="bgtwo"></div>
css
.bgone {
height: 100px;
background: black;
position: relative;
}
.bgtwo {
height: 50px;
border-top: 100px solid black;
border-right: 1000px solid transparent;
}
.content {
position: absolute;
top: 10px;
left: 10px;
color: #FFF;
}