Negative margin not the solution - but what is? - css

Here's part of a design:
As you can see - its simply a button that is exactly positioned between the two divs. The code is simply:
<div class="uc-apply-widget1">
<div class="top">
</div>
<div class="bottom">
<a>Get Started</a>
</div>
</div>
.uc-apply-widget1
{
.top
{
background-color:#primary-color;
height:30rem;
}
.bottom
{
background-color:#primary-600;
padding:0 1.6rem 1.6rem 1.6rem;
a
{
margin-top:-2.8rem;
}
}
}
However, I've come across a problem with using negative margins. I expected to just be able to move the button outside of the bottom div by applying a half height negative margin. Although the button does move upwards, it doesn't move the full 2.8 rem - the amount of movement is the same even if I apply 50rem.
The other solution is to use position relative, which does move the button up, but does not drag the bottom div upwards with it.
So I'm looking to move the button up by n amount and reduce the bottom div height by n amount - any ideas - I may just be having a bad day.

use
position: absolute;
top: 0; left: 0;
transform: translateY(-50%);
on your button
https://developer.mozilla.org/en-US/docs/Web/CSS/transform

Here is one way of realizing your design.
Set the a element to have display: table and position: absolute with
top and left offsets to 0 and 50% respectively.
The display: table rule will give you a shrink-to-fit width, which may be what you need.
You can then use the CSS3 transform property to translate the element by -50% both in the X and the Y directions to get the centering.
The advantage here is that you don't have to specify the dimensions for the a element.
.uc-apply-widget1 {
width: 400px;
margin: 0 auto;
}
.top {
background-color: beige;
height: 10rem;
}
.bottom {
background-color: lightgray;
height: 5rem;
padding: 0 1.6rem 1.6rem 1.6rem;
position: relative;
}
a {
display: table;
width: auto;
margin: 0 auto;
padding: 10px;
border: 1px dotted blue;
position: absolute;
top: 0;
left: 50%;
transform: translateY(-50%) translateX(-50%);
}
<div class="uc-apply-widget1">
<div class="top">
</div>
<div class="bottom">
<a>Get Started</a>
</div>
</div>

Related

Modal isn't covering the whole document

I am currently trying to make my .modal class's black background span the whole document length and width (not just the whole viewport, which it is currently doing). It would also be great to make it so you couldn't scroll the document anymore until you interacted with it.
I have verified that its parent container would be body, which I believe should be at least 600px due to my containers having a minimum height of 300px each and them being stacked on top of each other. I have used both 100% width and 100% height and absolutely positioned my element but have had no luck with it covering anything past the bottom of the viewport. I used z-index to ensure it was sitting on top of the other elements in the page and nothing seems to work.
<body>
<main class="todo">
<section class="todo__ctn todo__ctn--lists">
<span>Hello man...lists</span>
</section>
<section class="todo__ctn todo__ctn--tasks">
<span>Hello man...tasks</span>
</section>
</main>
<div class="modal">
<div class="modal__content">
<p>Hello Man...content</p>
</div>
</div>
</body>
````````````````
/* SCSS Styling */
* {
box-sizing: border-box;
}
.todo {
display: grid;
grid-template-columns: repeat(auto-fit,minmax(300px,1fr));
border: 1px solid black;
&__ctn {
min-height: 300px;
&:first-child {
border-bottom: 1px solid black;
}
}
&__ctn--lists {
background: gold;
}
&__ctn--tasks {
background: tan;
}
}
.modal {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
background: rgba(0,0,0,.8);
color: orange;
&__content {
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
}
}
Like I had mentioned, I would like to have the black background persist, even when you scroll down the page. Once I scroll past the bottom of the viewport, the black background seems to stop and I don't know why.

How to position an element to the LEFT of an other element?

What is the idiomatic way to position an element (X) to the left of an other element (inline-box 2), independent of its size, using standard CSS & HTML?
It is okay if it appears over other elements.
I have found a solution: to position an element to the left of another one, no matter their sizes, make it its child, and then absolute-position it right: 100%.
100% means the width of its parent, so 100% from the right will put it just left of it!
Using left: -100% wouldn't work, because it means: offset the left of the element left of the parent by the parent's width, however we want to offset by the width of the child element, itself.
CSS-only demo:
/* The important parts */
#box2 {
position: relative;
}
#x {
position: absolute;
right: calc(100% + 5px);
top: -1px;
}
/* Just styling */
#box1, #box2 {
border: 1px solid blue;
width: 200px;
margin-right: 10px;
display: inline-block;
}
#x {
border: 1px solid orangered;
width: 100px;
height: 150px;
}
<div id="container">
<div id="box1">box1</div>
<div id="box2">box2
<div id="x">X</div>
</div>
</div>

Why do I get a different result from setting translate to -50% and setting margins to 50%?

Assume the parent is relative, the child (style-x) is absolute. I used top 50%, left 25% to center the child.
I wish to actually center the child, so I set transform: translate(-50%, -50%). I am unsure if this is centered, so I double check by deleting that line and adding 'margin-top: -55px;' (half of the height), and 'margin-left: -45px;' (half of the width).
These two lines position my element in slightly different locations, yet this is different from my model of CSS. What's going on?
body {
height: 100%;
width: 100%;
margin: 0 auto;
}
#main {
overflow: auto;
height: 64vh;
width: 38vw;
margin: 0 auto;
margin-top: 10%;
position: relative;
border: 1vh solid black;
overflow: hidden;
}
#style-x {
/*Why doesn't translate(-50%, -50%) give me
the same position as setting the margin top and
left to half of the width and height?*/
width: 90px;
height: 110px;
/*
transform: translate(-50%, -50%);*/
margin-top: -55px;
margin-left: -45px;
position: absolute;
top: 50%;
left: 25%;
padding: 2%;
text-align: center;
background: green;
}
#left-col {
float: left;
width: 4%;
height: 101%;
margin-left: 46%;
background: black;
}
#right-col {
float: left;
width: 4%;
height: 101%;
margin: 0 auto;
margin-left: 0;
background: black;
}
<body>
<section id='main'>
<div id='style-x'>X</div>
<div id='left-col'></div>
<div id='right-col'></div>
</section>
</body>
Here's my Codepen if you'd like a visualization.
http://codepen.io/sentedelviento/pen/ORyqzv
There is no problem in your method. Both will try to center based on the values you provide.
The margin method fails cos you aren't using a Box Sizing method like so.
box-sizing: border-box
This results in all your elements to be larger than the height and width specified. Without this, you are telling the browser to add any padding or border to both width & height.
And so your larger element shifts when using using the margin method.
You've set a 2% padding on style-x, and a width of 38vw on #main. When using margins to center things, you would need to account for these varying values.
When you set a percentage padding, its calculated based on the width of the containing block.
The transform method on the other hand, uses the bounding box of the containing block and has no problem centering a larger element.
I'd suggest you include this box-sizing on main and style-x if using the margin method. You could just use
*, after, before {
box-sizing: border-box;
}
This gives better control over dimensions across all elements.

The perfectly rounded border

For a new Wordpress template, I designed (in Photoshop) a round-ish header that overlaps the image beneath.
The Design:
My try:
Code:
Right now, I'm using a border radius, since I want to do it in CSS rather than cutting out an image (also for responsive reasons).
border-radius: 100% / 100%;
No matter how I change the values, the border won't become nicely rounded.
The website so far: http://voorbeeld.website/19/
Maybe I was a little too creative in Photoshop, but nothing is impossible! Right?
Use a pseudo element, in this case I used the :before
Make sure the .wrapper's elements also have a position, relative or absolute, or you need to set z-index: -1 to the :before
.wrapper {
position: relative;
height: 200px;
overflow: hidden;
}
.wrapper:before {
content: '';
position: absolute;
top: -200px;
left: -10%;
width: 120%;
height: 400px;
background: lightgray;
border-radius: 50%;
}
.content {
position: relative;
padding: 20px;
text-align: center;
}
<div class="wrapper">
<div class="content">
Put your content here
</div>
</div>

How can I clip and transform an image, adding rounded corners and perspective?

How can I use HTML and CSS to make a div with an image inside it that is clipped and masked so that it looks like the following:
I've been trying to find a way to do this for about 2 hours now and got nowhere so I was just hoping someone could point me in the right direction. To be specific here, I wish to clip the image such that the top two corners are rounded, and embed it in a div element with four rounded corners and a 1/4 bottom padding, with both elements transformed such that it appears the right edge is further away from the viewer than the left.
In order to create such an effect, where the image remains the same, but the outer shape has this perspective look, you could use something similar to the demo below.
div.inner {/*gives top section effect, also crops the image*/
position: absolute;
top: 0;
left: 0;
border-radius: 20px 20px 0 0;
height: 200px;
width: 300px;
overflow: hidden;
border: 10px solid red;
transform: skewY(5deg);
}
.inner img {/*removes transform skew from image*/
transform: skewY(-5deg);
transform-origin: top left;
height:100%;width:100%;
}
.wrap {
display: inline-block;
height: 200px;
width: 300px;
position: relative;
/*for demo only*/
margin: 100px 100px;
}
.wrap:after { /*give bottom section the effect*/
content: "";
position: absolute;
bottom: -50%;
left: 0;
height: 100%;
width: calc(100% + 20px);
transform: skewY(-10deg);
transform-origin: bottom right;
background: red;
z-index: -1;
border-radius: 20px;
}
<div class="wrap">
<div class="inner">
<img src="http://lorempixel.com/500/500" />
</div>
</div>
In order to create the effect, I have had to incorporate this wrapper div. This allows the use of a pseudo element (the :after css) to generate the lower part of the shape:
+----------------------------+
| |
| _______/ <-- curved corner
| ------/
| ------/
\-----/
/\
\_____ also curved corner
The inner div is then hence used to generate the upper part of the shape. Using the skew declaration, the shape allows the opposite of the :after element, bringing the right hand side of the red shape down wards.
The overflow:hidden ensures any part of the image that does not fit within this inner div will be cropped (the border-radius:20px 20px 0 0; ensures only the upper corners are affected).
The last point to note is the .inner img css. Since I have skewed the .inner div, it is important to then 'unskew' the image so it remains the rectangular shape. This is why there is a 'counter-skew' here (transform: skewY(-5deg);).
Here's my attempt using perspective.
Thanks to #vals for the pointing out that perspective can be used as part of the transform.
* {
box-sizing: border-box;
}
figure {
perspective: 1000px;
width: 420px;
margin: 5em auto;
height: 350px;
background: red;
text-align: center;
padding: 10px;
border-radius: 25px;
transform: perspective(1200px) rotateY(50deg);
}
img {
border-radius: 20px 20px 0 0;
}
<figure>
<img src="http://lorempixel.com/400/200/sports/1/" alt="" />
</figure>

Resources