I'm designing a generator. Today, refactoring code I encountered a problem that I have seen several times in my path, but somehow I never penetrated into its existence. Namely - div after adding the attribute in CSS transform: translateY (-50%) loses on the quality of its elements inside, someone knows why this is happening? Elements are blurry, especially fonts and banners.
I'm using this line to center the diva vertically
If i delete this line, everything back to normal
#message {
width: 500px;
top: 50%;
transform: translateY(-50%);
left: 50%;
margin-left: -250px;
position: fixed;
background: #fff;
z-index: 201;
padding: 20px;
box-sizing: border-box;
}
I would believe that it is because og "half pixels".
You tell the div to transform -50%.
If the div has a height of 101px, the 50% will be 50.5px, and you cant have a half pixel.
You can check if this is the problem, by setting a specific height, that can be split in two, without going into halves.
Related
I have a background image on my website. I want to skew it so that it looks like cover photos on Netflix / Disney Plus (attached below).
Attempt
I tried adding this to my image's CSS, inspired from this question: CSS transform like netflix cover image
transform: rotateY(-30deg) rotateX(40deg) perspective(800px) scale(1.6)
It doesn't produce the desired result, though. Instead it slants incorrectly and doesn't stretch the container entirely.
Code sample
Here is my example: https://jsfiddle.net/gd3wL8nk/11/
Screenshots
Update
I got it to work by adding perspective: 2000px to the containing div, and adding this to the inner div:
transform: rotateY(-20deg) rotateX(20deg) scale(2) translateX(-10%)
My final CSS (with edits for measurement, etc) looked like this:
.container {
height: 90vh;
position: relative;
max-width: 100%;
overflow: hidden;
perspective: 2000px;
height: 900
}
.bg {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 110%;
background-image: url('image-here');
background-size: cover;
transform: rotateY(-20deg) rotateX(20deg) scale(2);
position: absolute;
top: -10%;
left: 0;
minWidth: 800;
}
See fiddle: https://jsfiddle.net/fernandorojo/kr567zp8/4/
You might be looking for transform: skew();!
i.e.
transform: skew(20deg) scale(1.6);
It won't work with both X and Y rotation though. A good method to ensure it's fullscreen is to use the image as a background in an oversized container. For any children items (like the form, if you nest it in the parent div) you will need to apply the opposite skew to ensure it appears without a slant.
If you check the asset Netflix uses, it's been skewed in Photoshop already.
The plunkr link is https://plnkr.co/edit/mv3lL1vwu2LxoeFZw0TX
I want to position a div at the center of a page (vertically and horizontally). The div has a button which should be at the center of the div. I found a solution in Vertically center in viewport using CSS but it doesn't work for me. Also, I want to create two separate rules, one for vertical alignment and one for horizontal alignment and use them together (or separately) so that I can pick which element should be aligned in which way.
I do not want to use Flex, Bootstrap etc. as I am trying to understand CSS concepts.
the horizontal alignment rule is straightforward.
.center-horizontally-common-styles {
display: block;
margin: auto auto;
}
The vertical alignment rule is (modified from the SO link)
.centre-vertical-common-styles {
position: fixed;
right: 50%;
top: 50%;
transform: translateY(-50%);
transform: translateX(50%);
}
.debug-border-common-styles {
border: 3px solid black;
height:40px;
width:200px;
}
HTML
<div class="debug-border-common-styles centre-vertical-common-styles center-horizontally-common-styles">
<button type="button"> Click Me! </button>
</div>
My understanding is that right: 50%; top: 50%; will use the browser's window (viewport?) as the reference and move the div's top edge and right edge to the location which is 50% mark of the browser's respective edge's location. TranslateY and TranslateX should now move the div upwards (-50%) and towards left(50%) respectively to align the button's center to the middle of the page thus centering the button. The issues I am facing are:
1) The translateY doesn't seem to work. If I change the height of the div to say 200px. the div starts growing downwards (i.e. its top edge seem to be fixed!) It doesn't happen if the width is changed to say 200px.
.debug-border-common-styles {
border: 3px solid black;
height:200px;
width:200px;
}
2) The button inside the div is not at the center of the div. I created the following css rule for the button but translateY doesn't seem to work on this one as well.
.centre-button-vertical-common-styles {
position: absolute; /*use absolute so that the origin is no the parent div*/
right: 50%;
top: 50%;
transform: translateY(-50%);
transform: translateX(50%);
}
3) Ideally, I would like to create two separate rules, say .center-vertical and .center-horizontal and combine them to use the desired effect. But If I do something like follows, it doesn't work. Is it possible to create two separate rules?
.center-horizontally-common-styles {
display: block;
margin: auto auto;
}
Not use right here because horizontal rule should place the item in middle
.centre-button-vertical-common-styles {
position: absolute;
top: 50%;
transform: translateY(-50%);
}
Bro, you need few arrows of style. Do like this:)
.centre-vertical-common-styles {
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.debug-border-common-styles {
border: 3px solid black;
height:40px;
width:200px;
display:flex;
align-items:center;
justify-content:center;
}
As the question says, I am trying to center a div on the middle of the screen both horizontally/vertically and resize it at the same time.
I do not have any problems on resizing the content when the screen is smaller even to center the wrapper when it is displayed on big screens, the problems comes when I try to resize the screen and, as the wrapper has a max-height property, it does not never vertically center when resize the screen (because it occupy 300px all the time).
I would like that the div that is centered (wrapper) never will be more than 300px and will be always centered (both vertically/horizontally).
Here is my code:
HTML:
<div id="wrapper">
<div id="content">
</div>
</div>
CSS:
html{
width: 100%;
}
body{
width: 100%;
background-color: red;
margin: 0;
}
#wrapper{
position: absolute;
max-width: 300px;
max-height: 300px;
width: 100%;
height: 100%;
margin: auto;
top: 0; left: 0; bottom: 0; right: 0;
}
#content{
position: absolute;
width: 100%;
padding-bottom: 100%;
background-color: yellow;
}
JSFiddle.
I tried a lot of configurations and looked a lot of questions here on StackOverflow but any of them worked for me because most of them are only for horizontally/vertically center or resize a div, but not both.
Note: I cannot use flexbox and I would like to maintain as much as possible the actual CSS code, if possible.
How can I avoid to use max-height (that is broken my vertically centering) and get the same behaviour?
EDIT: The div is already centered both vertically/horizontally. What I want is that the square will be always a square and always be centered. I am sorry if I do not put it very clear.
Now the content is being resize as I want (as a square), the problem is only with vertically align at the same time it resizes.
EDIT 2: If you want to see the effect that I refer in the above edit, resize the screen on my example JSFiddle horizontally and you will see the effect.
Thanks in advance!
You can easily do this with CSS3 transform. It depends of the browsers support you want to offer.
I would suggest to place your content absolute at 50% of your wrapper. Then, you can use a negative translate of 50%. top: 50% and left: 50% will place your content top left corner in the middle. Negative translate of 50% (translate(-50%, -50%)) will move your content half of its width to the left and half of its height to the top.
#content{
position: absolute;
width: 100%;
height: 100%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
You can see your updated jsfiddle
EDIT
I misunderstood a part of your question the first time. But you can easily merge a part of your solution and mine to get what you want.
You just need to replace height: 100%; with padding-bottom: 100%; of my previous answer above:
#content{
position: absolute;
width: 100%;
padding-bottom: 100%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
See this updated jsfiddle.
Maybe I'm missing something(?), but it looks like you can just add height:100%; to your #content css instead of padding-bottom and it works:
https://jsfiddle.net/puajxgsz/
Also, I played with another way to do it without absolutely positioning anything...because, well, it was sort of interesting:
https://jsfiddle.net/j0ch7oxj/
I have been playing around with an idea of a contact card type of thing. Apparently hexagons are quite a new trend, but I'd like to keep it a tad simpler, namely: rotated squares. Considering I am quite knowledgeable with HTML and CSS, it wasn't that hard to accomplish this. In a few minutes I came up with this.
HTML
<a href="#" title="Profile of Banana">
<span style="background-image: url(http://s5.favim.com/orig/52/portrait-sigma-50mm-f1.4-hsm-canon-eos-5d-mk2-face-Favim.com-473053.jpg);">
Queen Elizabeth
</span>
</a>
CSS
a {
display: inline-block;
margin: 50px;
width: 150px;
height: 150px;
transform: rotate(45deg);
position: relative;
overflow: hidden;
}
/* Pseudo element for border */
a:after {
content: "";
display: block;
width: 142px;
width: calc(100% - 8px);
height: 142px;
height: calc(100% - 8px);
border: 2px solid white;
position: relative;
z-index: 10;
top: 4px;
left: 4px;
}
/* Span for bg-image and text */
a > span {
display: block;
height: 213px;
width: 213px;
top: -31px;
left: -31px;
position: absolute;
background-size: cover;
background-position: center;
transform: rotate(-45deg);
padding: 76px 24px 0;
}
The idea is quite simple:
Make the link itself a block element, rotated it 45 degrees. Don't forget overflow: hidden
Rotate its child 45 degrees back, apply a background-image to this element (dynamically loaded in my case, therefore inline)
This works in all major browsers and degrades gracefully into a simple square in other browsers (IE8 and below; though you might need a background size polyfill). For this reason I want to keep this HTML structure.
So, what's the problem? First of all I'd like to make it applicable to different sizes where I would only need to set the width and height of the link itself (a) after which the height and width of its child are calculated automatically - in my project I can use the relatively new CSS3 calc() function, if that's of any help, along with the beauty of SASS/SCSS. In other words, I need the ratio between the width of a and its child span. As far as I can tell, it seems that the ratio is the square root of 2: 213 / 150 = 1.42. My first question is, then, why? What's the logic and/or arithmetic behind this? Why can't the span simply take up 100% width of its parent? Why need it be exactly square root 2 times more?
Additionally, I also would like to know where the top and left values come from. I haven't figured out yet which arithmetic might be the base of is. I do know that this might be dependent on the value of transform-origin, but I don't know how exactly. In other words, is it possible with a pre-defined transform-origin value to have top and left to be zero and by doing so removing the need for a per-case calculated value? If not, how can the value of these properties be calculated based on the width value of its parent, as that's the only value that should be known?
Summary, if only the width and height of a are known, how do I:
calculate the width for its child, and how can that be explained?
calculate/use the offsets (top and left) on span and how can they be explained?
I do not want to use any JS solutions for this. If something isn't clear, please post a comment so I can clarify.
UPDATED FIDDLE
First of all, as the background-image defined for span will overlap the actual a element, it needs to be bigger. As we are talking about an angle of 45 degrees, this leads to a triangular cut-off shape in which the size of the main square (i.e. the image) is the long side, and the other two equally-sized lines are of the anchor. Therefore, the size of the image (span) should be equal to sqrt(2)*100% ~= 141.42%.
The positioning of the span then. First we rotate the image back by 45 degrees. Import for this action is that the transform-origin is set to 0 0 rather than 50% 50%. By doing so, the element is rotated around a single point right in the top middle of the rhombus. After rotating it's only a matter of translate the element on the X-axis, which can also be done with CSS transforms: translateX(-50%).
No matter what value is now passed onto a's width and height, the image should always be aligned perfectly within it, with the correct dimensions.
(In the fiddle, try giving a a value of, say, 400px. It looks nice, doesn't it? You can also give nice hover effects to the image.)
a {
display: inline-block;
width: 200px;
height: 200px;
transform: rotate(45deg) translate(50%);
position: relative;
overflow: hidden;
}
a:after {
content: "";
display: block;
width: calc(100% - 8px);
height: calc(100% - 8px);
border: 2px solid white;
position: relative;
z-index: 10;
top: 4px;
left: 4px;
}
a > span {
display: block;
height: 141.42%;
width: 141.42%;
top: 0;
left: 0;
position: absolute;
background-size: cover;
background-position: center;
transform: rotate(-45deg) translateX(-50%);
transform-origin: 0 0;
}
Is it possible to create the following shape as a DIV in CSS.
The browser support is not important.
You cannot skew an element like this directly, you'll need to use two elements (or generated content) and hide certain overflow to make the flat bottom edge:
http://jsfiddle.net/6DQUY/1/
#skew {
height: 240px;
overflow: hidden;
}
.skew {
background: #000;
display: inline-block;
height: 300px;
width: 500px;
margin-top: 100px;
transform: skew(-8deg, -8deg);
}
Note: I removed the cross browser definitions for better readability.
UPDATE: This would be a more fluid example which resizes in set dimensions: http://jsfiddle.net/6DQUY/3/. Note the padding-bottom on the wrapper which defines the ratio. You may have to play around with the percentage amounts.
#skew {
padding-bottom: 20%;
overflow: hidden;
position: relative;
}
.skew {
background: #000;
position: absolute;
top: 30%;
right: 8%;
left: 8%;
height: 100%;
transform: skew(-8deg, -8deg);
}
Using SVG:
Below is a sample using SVG polygon which can also be scaled easily. Text (if required) can be absolutely positioned on top of the shape.
.shape-svg {
position: relative;
height: 100px;
width: 300px;
}
svg {
position: absolute;
top: 0px;
left: 0px;
height: 100%;
width: 100%;
}
polygon {
fill: black;
}
/* Just for demo*/
.shape-svg{
transition: all 1s;
}
.shape-svg:hover {
height: 200px;
width: 600px;
}
<div class="shape-svg">
<svg viewBox='0 0 100 100' preserveAspectRatio='none'>
<polygon points='5,35 100,0 95,100 0,100' />
</svg>
</div>
The shape can be created using SVG clip path also instead of polygon.
Using CSS and Single Element:
The same shape can be achieved with CSS using only one element also. The key is to set the transform-origin as the side that is required to be straight.
.shape{
height: 100px;
width: 300px;
margin-top: 50px;
background: black;
transform-origin: 0% bottom;
transform: perspective(300px) rotateY(-15deg) skewX(-10deg);
transition: all 1s;
}
.shape:hover{
width: 350px;
height: 150px;
transform: perspective(450px) rotateY(-15deg) skewX(-10deg);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class="shape"></div>
The shape achieved using this method can also be scaled. However as the height of the shape increases, the right side becomes taller and pushes the top-right corner even more higher. So, either the rotation angle needs to be decreased (or) the perspective needs to be increased (shape needs to be moved farther away) for the height of the right side to remain small enough and be within the viewing area. Or else, the margin-top should be increased.
Below is an explanation on why this happens:
Consider a rectangle positioned 300px in front of the viewer's eye. It is being rotated towards to the viewer and as the rotation happens, the side which is getting closer to the user will appear taller than the other side.
We have fixed the transform origin's x coordinate as 0% and so the height of the left side of the shape would be constant and that of the right side would keep increasing based on the rotation angle.
Because the transform origin's y coordinate is bottom, the bottom side of the shape would be kept straight and any height increase on the right side of the element would be projected upwards resulting in the shape going outside of the screen.
There is no such problem if only the width increases because the rotation angle is too minimal and so the shape's right side will never get anywhere close enough to the viewer to look very tall.
The shape in question is not an exact duplicate of the one discussed here but you can get some more ideas by looking at it :)
You could look into CSS transformations (transform) I have created a JsFiddle with a quick example.
HTML
<div class="skew"></div>
CSS
/* Skew the container one way */
.skew {
background: #000;
display: inline-block;
height: 50px;
width: 500px;
margin-top: 100px;
-webkit-transform: skewY(-5deg);
-moz-transform: skewY(-5deg);
-ms-transform: skewY(-5deg);
-o-transform: skewY(-5deg);
transform: skewY(-5deg);
}
NOTE:
You may need to include other transformations to get the unbalanced look.
--EDIT--
Here is another solution but using :before and :after CSS. JsFiddle.