How to remove margin attribute when hover - css

Let's say I have this code:
<div id="block">asd</div>
And I want to make it move from the top left corner to the bottom right when I hover (or when I click it, it doesn't matter)
#block{ border: 1px solid black;
margin-top: 10px;
margin-left: 10px;}
#block:hover{
margin-right:10px;
margin-bottom:10px;
}
But it doesn't work. Somehow I have to remove the margin-top and margin-left attributes when hovering but I don't know how.
Please do it in css if it can be done!

#block:hover{
margin-top: 0px;
margin-left: 0px;
margin-right:10px;
margin-bottom:10px;
}
if you wanna do it in don't repeat yourself philosophy
#block:hover{
margin-top: 0px;
margin-left: 0px;
}

I guess it's easy
You have the:
#block{ border: 1px solid black;
margin-top: 10px;
margin-left: 10px;}
So, in the hover, you have to cancel the margin-top and margin-left (change it to zero), and then apply the margin you want!
#block:hover{
margin-right:10px;
margin-bottom:10px;
margin-top: 0;
margin-left: 0;
}
Like that, the margin you had will disappear on hover!
in the #block:hover css, just put this code there down, and everything should work fine.
#block:hover{
margin-right:10px;
margin-bottom:10px;
margin-top: 0;
margin-left: 0;
}

Just put the margin "all in one".
So it will be:
margin: [top right bottom left]
In your case:
#block{
margin: 10px 0px 0px 10px;
}
#block:hover{
margin: 0px 10px 10px 0px;
}
You can also combine margin like:
margin: [top+bottom] [left+right];

Instead of using margin, use the transform property.
To achieve this you would require another element that serves as a wrapper.
When hovering the wrapper do the following:
Move the wrapper iteself to the right bottom corner using:
transform: translate(calc(100% - [<blockWidth>]), calc(100% - [<blockHeight>]));
Then move the .block element in the opposite direction with:
transform: translate(calc(-100% - [<blockWidth>]), calc(-100% - [<blockHeight>]));
Code Snippet:
body {
margin: 0;
overflow: hidden;
}
.block-container {
box-sizing: border-box;
position: absolute;
width: 100%;
height: 100%;
transition: transform 3s;
}
.block-container:hover {
transform: translate(calc(100% - 2em), calc(100% - 2em));
}
.block {
position: absolute;
width: 2em;
height: 2em;
background-color: darkorange;
transition: inherit;
}
.block-container:hover #block {
transform: translate(calc(-100% - 2em), calc(-100% - 2em));
}
<div class="block-container">
<div class="block"></div>
</div>

maybe something like this:
Css:
#block {
border: 1px solid black;
width: 100px;
height: 100px;
position: absolute;
top: 0;
left: 0;
}
#block:hover {top: 90vh; left: 90vw;}
Html:
<div>try to catch me</div>

Related

CSS: How to add slanted edge to right of div with complete browser cross-compatability?

I'm looking to achieve a slanted edge on my div. The problem I'm coming across is the simple code I found to accomplish this is not cross-browser compatible. In fact, it only shows in Chrome.
Can anyone advise on how to do the following so it works in ALL browsers:
clip-path:polygon(0 0, 70% 0, 100% 100%, 0 100%);
This effect would achieve:
Here's my entire CSS code:
.my-slanted-div {
position:absolute;
bottom:0;
left:0;
width:100px;
padding:10px 10px;
background-color:#eee;
font-size:20px;
clip-path:polygon(0 0, 70% 0, 100% 100%, 0 100%);
}
Can anyone help me out?
You can also skew pseudo-element, like this:
.my-slanted-div {
position:absolute;
bottom:40px;
left:0;
width:80px;
padding:10px 10px;
background-color:red;
font-size:20px;
}
.my-slanted-div:after {
width:50px;
background:red;
position:absolute;
height:100%;
content:' ';
right:-22px;
top:0;
transform: skew(45deg);
}
<div class="my-slanted-div">
TEXT
</div>
p.s. change angle, play with values...to get desired result...
Edit: Demo in context -> https://jsfiddle.net/Lbwj40mg/2/
This should do the trick using borders.
<div id="container">
<p id="text">Hello</p>
<div id="slanted"></div>
</div>
#container {
position: relative;
height: 200px;
width: 200px;
background:url(http://placehold.it/200x200);
}
#text {
position: absolute;
bottom: 15px;
left: 10px;
z-index: 1;
margin: 0;
}
#slanted {
position: absolute;
bottom: 0;
left: 0;
height: 0;
width: 0;
border-left: 75px solid #dedede;
border-right: 50px solid transparent;
border-bottom: 50px solid #dedede;
}
jsfiddle
I've made it work one way with :before and :after pseudos, you simply need to update the widths, heights and line-height to suit the size of tab you want; the rectangle must be the same height as the :before and :after bits for a clean look.
.box {
background: red;
width: 200px;
position: relative;
height: 100px;
line-height: 100px;
text-align: center;
margin-left: 50px;
color: white;
font-size: 21px;
font-family: arial, sans-serif;
}
.box:after {
position: absolute;
right: -50px;
content: '';
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
}
.box:before {
position: absolute;
left: -50px;
content: '';
width: 0;
height: 0;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
border-bottom: 100px solid red;
}
<div class="box">
Text in the box
</div>
Here's a way with transform: rotate just to add to the list. Quite annoying as you will have to play with pixels for alignment and make some entries into #media rules for different screen sizes. But it should be fairly cross browser friendly (but maybe not opera mini)
body {
background-color: #333;
}
.container {
position: absolute; /* needs a position, relative is fine. abolsute just for this example */
top: 50%; left: 50%;
transform: translate(-50%, -50%);
width: 400px;
height: 200px;
background-color: #ccc;
overflow: hidden; /* required */
}
.salutations {
position: absolute;
bottom: 0;
left: 0;
padding: 0 10px 0 15px;
background-color: #fcfcfc;
height: 50px;
line-height: 50px; /* match height to vertically center text */
font-size: 30px;
}
.salutations::before {
content: '';
position: absolute;
top: 21px; /* play with this for alignment */
right: -36px; /* play with this for alignment */
height: 40px; width: 70px; /* may need to adjust these depending on container size */
background-color: #fcfcfc;
transform: rotate(60deg); /* to adjust angle */
z-index: -1; /* puts the pseudo element ::before below .salutations */
}
<div class="container">
<div class="salutations">Hello</div>
</div>
P.S. May have to adjust a pixel or two, my eyes suck.
Browser Compatability
transform: rotate
pseudo elements (::before)
Fiddle
https://jsfiddle.net/Hastig/wy5bjxg3/
It is most likely it is an SVG scaled to always fit its text which is simple and quick way of doing it; if you must use CSS then you could always:
Set a gradient to the div from color to transparent so that it takes up most of the div and the transition of color is abrupt and not smooth like how a normal gradient looks.
create another div and using borders create a triangle to touch the other main rectangular div such as doing:
.triangle {
width: 0;
height: 0;
border-style: solid;
border-width: 200px 200px 0 0;
border-color: #fff transparent transparent transparent;
}
Using css you can generate an element that takes the shape of a triangle.
Css tricks has a post on that.
By making the .slanted class position itself relative, we can position the generated content on the right side of the slanted div using absolute positioning.
It'll take some fiddling to get the perfect result you want, but here's an example.
.slanted{
background: #007bff;
color: #fff;
position: relative;
display:inline-block;
font-size: 20px;
height: 25px;
padding: 2px 4px;
}
.slanted::after {
content: " ";
display: block;
width: 0;
height: 0;
border-style: solid;
border-width: 29px 0 0 20px;
border-color: transparent transparent transparent #007bff;
position: absolute;
top: 0;
right: -20px;
}
<div class="slanted">Hello</div>

Pseudo CSS element not displaying outside of parent div

I have a pseudo element that is refusing to display outside of it's parent div. I've set it half in, half out so you can see the issue on the following fiddle.
Fiddle
Been trying a whole bunch of different solutions that I've found on here for this but I can't get it working.
Any suggestions?
Code :
.box {
display:block;
position: relative;
z-index: 10;
background: #FFF;
width: 350px;
height:140px;
box-shadow: 0 1px 3px #888;
padding:20px;
overflow: auto;
top: 30px;
left:50px;
text-align:center;
border-radius: 5px;
border: 1px solid #FFF;
}
.box::before {
position:absolute;
font-family:FontAwesome;
content:"\f0d8";
color:red;
z-index: 20;
font-size:80px;
left:50px;
top:-45px;
}
Assuming you didn't need that overflow:auto; here is a working solution: https://jsfiddle.net/ug88rptL/1/. I just removed that property.
If you need overflow:auto; and you can use position:fixed; on the ::before pseudo element: https://jsfiddle.net/ug88rptL/2/
Definitive answer after comments:
If you need position:absolute; and imperatively cannot use position:fixed;, just remove position:relative; from the .box div and use different margins to maintain the original positioning. Works as long as you don't set a left or right value for the pseudo-element: https://jsfiddle.net/ug88rptL/10/
the ::before pseudo element is treated as a child element of the element you attach it to, so it will always be inside the box. you're better off wrapping the box in another element and then giving that element the ::before child
Read more here.
.box {
display: block;
background: #FFF;
width: 350px;
height: 140px;
box-shadow: 0 1px 3px #888;
padding: 20px;
overflow: auto;
text-align: center;
border-radius: 5px;
border: 1px solid #FFF;
position: relative;
top: 130px;
left: 30px;
}
.wrapper {
position: relative;
}
.wrapper::before {
position: absolute;
font-family: FontAwesome;
content: "\f0d8";
color: red;
font-size: 80px;
left: 50px;
top: 0;
}
<div class="wrapper">
<div class="box">
BLAH BLAH BLAH BLAH BLAH
</div>
</div>

Divs side-by-side, centred, and overflowing edge of screen

I am trying to design a landing page to link to 2 web apps. I am trying to make the design as visually attractive as possible. I think it would look good if the Divs containing the links were side-by-side at the centre of the screen, with their edges overflowing the left and right of the screen. I can then put a border-radius on them and some nice blocky colour:
Goal:
I have tried numerous options, including inline-block and overflow:hidden:
HTML
<div id="centre-pane">
<div class="app-btn">
<img src="icon.png">link text
</div>
<div class="app-btn">
<img src="icon2.png">link text
</div>
</div>
CSS
.app-btn
{
width:1000px;
height:320px;
display:inline-block;
border:10px solid black;
border-radius: 50px;
}
#centre-pane {
width:2000px;
margin:0 auto;
text-align:center;
overflow-x: hidden;
}
Is this possible? I have found several ways of getting them side-by-side (eg here) but nothing that also lets them overflow the screen.
Just using position absolute would do the trick.
I've added a wrapper but it may not be required.
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body,
html,
.wrapper {
height: 100%;
}
.wrapper {
position: relative;
}
.btn {
width: 45%;
height: 30%;
background: lightblue;
border: 2px solid blue;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.left {
left: 0;
border-radius: 0 25% 25% 0;
border-left: none;
}
.right {
right: 0;
border-radius: 25% 0 0 25%;
border-right: none;
}
<div class="wrapper">
<div class="btn left"></div>
<div class="btn right"></div>
</div>
You can achieve this with absolute positioning and negative margins (for the right item). You'll have to fix the size of the body though in order to achieve the effect. I've also added individual classes to the first and second item respectively (.app-btn-1 and .app-btn-2):
body {
width: 2000px;
overflow-x: hidden;
}
.app-btn {
width:1000px;
height:320px;
position: absolute;
border:10px solid black;
border-radius: 50px;
overflow-x: hidden;
}
.app-btn-1 {
left: -500px;
text-align: right;
}
.app-btn-2 {
left: 100%;
margin-left: -500px;
}
DEMO
NOTE: For my demo to look right in jsfiddle, I've quartered the sizes so you can see the effect in the small window
Here is the code you need:
.menu {
display: inline-block;
height: 200px;
width: 40%;
margin-top: calc(50% - 100px);
border: 2px solid red;
background-color: brown;
color: black;
text-decoration: none;
transition: all 0.5s;
}
#left {
float: left;
border-top-right-radius: 10px;
border-bottom-right-radius: 10px;
margin-left: -10px;
}
#right {
float: right;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
margin-right: -10px;
}
.menu:hover {
background-color: gray;
border-color: brown;
color: red;
}
<div class="menu" id="left">Left</div>
<div class="menu" id="right">Right</div>
I made a
JS Fiddle for you.

css make responsive oval block

I am trying to make a css blocks for numbers shown in image below. My idea / goal is to make one responsive block so if there will be one number it will be round, if two then like second. I have been tried to make border-radius: 50% so the first block I succeed to do second was not like in image with border-radius: 50%
So my question is it possible to make such result with one class block or for each button (left | right) I need to write special class for each block ?
For ellipse use 100%:
border-radius: 100%;
For stadium use big value in px:
border-radius: 9999px;
Example
.round{
display: inline-block;
width:50px;
height:50px;
background: red;
border-radius: 100%;
margin: 10px;
}
.ellipse,.stadium{
width: 80px;
}
.stadium{
border-radius: 9999px;
}
<div class="round circle"></div>
<div class="round ellipse"></div>
<div class="round stadium"></div>
Fixed Height Solution
For this you will need a "fixed" height (otherwise, you'll need to calculate this with jquery).
What you'll need to do is something like this;
html,body{background:#222;}
div {
margin:10px;
display: inline-block;
height: 30px;
border-radius: 25px;
background: lightblue;
font-size: 30px;
min-width: 30px;
text-align: center;
line-height: 30px;
padding: 10px;
position:relative;
color:blue;
}
div:before{
content:"";
position:absolute;
left:0;
top:-10px;
width:100%;
border-top:3px solid tomato;
}
<div>1</div>
<div>123</div>
Note: The border-radius should be set to half the overall height for this.
I've also included a min-width to ensure it is always at least a circle.
JQuery Solution For non-fixed heights
$(document).ready(function() {
$('div').each(function(index) {
var height = $(this).height();
$(this).css("border-radius", height + "px");
});
});
html,
body {
background: #222;
}
div {
margin: 10px;
display: inline-block;
border-radius: 25px;
background: lightblue;
font-size: 30px;
min-width: 30px;
text-align: center;
line-height: 30px;
padding: 10px;
position: relative;
vertical-align:top;
color: blue;
}
div:before {
content: "";
position: absolute;
left: 0;
top: -10px;
width: 100%;
border-top: 3px solid tomato;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>1</div>
<div>123</div>
<div>Not a set height,
<br/>either :)</div>
div{
height:50px;
width:50px;
border-radius:9999px;
background:red;
text-align:center;
display:inline-block;
line-height:3em;
font-weight:bold;
font-size:16px;
}
<div>2</div>
<div>28</div>

I cant get a div to sit 20 px below another div that has a varying height

I know this is probably very simple but I have tried using all position settings, float, and nesting. The top div varies in height due to dynamically created text and I need the div below it to be 20px below the top div. Any help is greatly appreciated.
I know I have the position as absolute but that is just to demonstrate kind of what I'm looking for.
#wrapper {
position:absolute;
width:341px;
height:371px;
z-index:1;
border: solid #777 1px;
}
#topbox {
position:absolute;
width:280px;
z-index:1;
padding: 30px;
border: solid #000 1px;
top: 7px;
}
#bottombox {
position:absolute;
width:280px;
z-index:1;
padding: 30px;
top: 136px;
border: solid #000 1px;
}
<div id="wrapper">
<div id="topbox">Top text box #1. The text is dynamically created here with a height that will vary. </div>
<div id="bottombox">Bottom text box #2. The text is dynamically created here with a height that will vary and needs to be 20px below the bottom of the top text box.</div>
</div>
Looking at the CSS you have, the problem is you are using absolute positioning. For a task like this you should use relative positioning. Here it is on jsFiddle to show you it in action & here is the CSS I adjusted to achieve that:
#wrapper
{
position: relative;
float: left;
display: inline;
width: 341px;
min-height: 371px;
z-index: 1;
border: solid #777 1px;
}
#topbox
{
position: relative;
float: left;
display: inline;
width: 280px;
z-index: 1;
padding: 30px;
margin: 7px 0 0 0;
border: solid #000 1px;
}
#bottombox
{
position: relative;
float: left;
display: inline;
width: 280px;
z-index: 1;
padding: 30px;
margin: 20px 0 0 0;
border: solid #000 1px;
}
Here is how it renders in my local browser now:
I also looked over your CSS & combined/consolidated it since I find that repeating code can cause confusion when debugging items like this. Here is how I would code this:
#wrapper, #topbox, #bottombox
{
position: relative;
float: left;
display: inline;
}
#topbox, #bottombox
{
width: 280px;
z-index: 1;
padding: 30px;
border: solid #000 1px;
}
#wrapper
{
width: 341px;
min-height: 371px;
z-index: 1;
border: solid #777 1px;
}
#topbox { margin: 7px 0 0 0; }
#bottombox { margin: 20px 0 0 0; }
To give #topBox a bottom margin you simply have to use:
#topBox {
margin-bottom: 20px;
}
The problem is that since you use position: absolute the elements jumps out of their normal flow and will no longer relate to each other.

Resources