Remove excess padding after transformY on predecessor's ::after - css

(Wow, that was a lousy title!)
I created a little quarter-circle to display after a div. I then used transformY to move it back up the div so that some content overlaps, which is the user's design requirement.
However, doing so leaves some excess space at the bottom of the div... the div retains the full height after the transform. I'd like to reduce that height.
I'm working in a page builder (ClickFunnels). Here's the link: https://www.goupperpeninsula.com/get-your-arts-on
Here's the CSS:
#section-1852710000::after,
#section-1852710000::before {
content: '';
position: relative;
display: block;
background: #ffe121;
width: 285px;
height: 285px;
}
#section-1852710000::after {
border-top-right-radius: 285px;
-webkit-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
Here's the space I'd like to eliminate:
I feel like I'm missing something obvious, I'm just not quite sure what it is!

This is expected. A transform is purely visual and does not affect layout. I'd try negative margin instead.
Here's a demo of the different behaviours I keep around.
* {
box-sizing: border-box;
}
h3 {
text-align: center;
}
.page {
margin: 0 auto;
text-align: center;
}
.wrapper {
border: 5px solid black;
margin: 5px;
display: inline-block;
background: lightblue;
vertical-align: top;
}
.box {
width: 100px;
height: 350px;
background: lightgrey;
border: 1px solid grey;
padding: 10px;
text-align: center;
}
.position {
position: relative;
top: -25px;
}
.margin {
margin-top: -25px;
}
.transform {
transform: translateY(-25px);
}
<h3>DEMONSTRATING THE DIFFERENCE BETWEEN RELATIVE POSITIONING AND POSITIVE/NEGATIVE MARGINS AND TRANSFORMS</h3>
<div class="page">
<div class="wrapper">
<div class="box">
<p>This box is the specimen for comparison purposes.</p>
<p>It is a grey box inside a blue box with a black border.</p>
</div>
</div>
<div class="wrapper">
<div class="box position">
<p>This grey box is moved using relative positioning.</p>
<p>The page remembers where it was and allocates that space as though the element was still there.</p>
</div>
</div>
<div class="wrapper">
<div class="box margin">
<p>This grey box is moved using negative margin.</p>
<p>See how the wrapper div has 'shrunk'?</p>
↓ ↓
</div>
</div>
<div class="wrapper">
<div class="box transform">
<p>This grey box is moved using a transform.</p>
<p>The page remembers where it was and allocates that space as though the element was still there.</p>
</div>
</div>
</div>

Related

Why bottom:0 doesn't work with position:sticky?

I'm trying to understand what css "sticky" does.
I can get it to stick to the 'top' of its parent,
but not to the 'bottom'
My test code is:
.block {
background: pink;
width: 50%;
height: 200px;
}
.move {
position: sticky;
bottom: 0;
}
1111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>
<div class="block">
AAAA
<div class="move">
BBBB
</div>
</div>
222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>
When I have "move" set to 'top:0' it sticks to the top of the pink block, but when set to 'bottom:0' it seems no longer fixed/sticky.
It's working fine but you will see nothing. Let's have a look at the definition:
A stickily positioned element is an element whose computed position value is sticky. It's treated as relatively positioned until its containing block crosses a specified threshold (such as setting top to value other than auto) within its flow root (or the container it scrolls within), at which point it is treated as "stuck" until meeting the opposite edge of its containing blockref
Give a big margin to the block element to hide it from the screen then start scrolling slowly
.block {
background: pink;
width: 50%;
height: 200px;
margin-top:120vh;
}
.move {
position: sticky;
bottom: 0;
}
<div class="block">
AAAA
<div class="move">
BBBB
</div>
</div>
You will notice that when your element is showing the BBB is overlapping the AAA until it reach its initial place. This is the sticky behavior when using bottom:0. So our element is kept position:relative and when the container start going out from the screen on the top, it become sticky to its bottom until it reach the opposite edge (the top of the container).
Exactly the same happen with top:0 but in the opposite direction:
.block {
background: pink;
width: 50%;
height: 200px;
margin-bottom:120vh;
}
.move {
position: sticky;
top: 0;
}
<div class="block">
AAAA
<div class="move">
BBBB
</div>
</div>
So sticky will not position the element to the top or the bottom but it will decide how the element shoul stick in order to be visible when the container will start moving out of the screen.
In order to obtain what you want you need to put your element in the bottom using other properties and keep it bottom sticky.
Here is an example where I place the element at the bottom using flexbox and I specify that I need it to be sticky at the bottom.
.block {
background: pink;
width: 50%;
height: 200px;
margin-top:120vh;
display:flex;
flex-direction:column;
}
.move {
margin-top:auto;
position: sticky;
bottom: 0;
}
<div class="block">
AAAA
<div class="move">
BBBB
</div>
</div>
So position:sticky will never define the position of the element like we do with absolute or fixed but it will define how the element will stick when there is a scrolling behavior.
Here more examples to better understand:
.block {
background: pink;
display:inline-flex;
vertical-align:top;
height: 200px;
max-width:100px;
flex-direction:column;
margin:100vh 0;
}
.e1 {
position: sticky;
top: 0;
}
.e2 {
margin-top:auto;
position: sticky;
top: 0;
}
.e3 {
position: sticky;
top: 20px;
}
.e4 {
position: sticky;
bottom: 0;
margin:auto;
}
.e5 {
position: sticky;
bottom: 0;
top:0;
margin:auto;
}
.e5 {
position: sticky;
bottom: 0;
}
<div class="block">
<div class="e1">Top sticky</div>
</div>
<div class="block">
<div class="e2">Top sticky at bottom (nothing will happen :( )</div>
</div>
<div class="block">
<div class="e3">Top sticky at 10px</div>
</div>
<div class="block">
<div class="e4">bottom sticky in the middle</div>
</div>
<div class="block">
<div class="e5">top/bottom sticky in the middle</div>
</div>
<div class="block">
<div class="e6">bottom sticky at the top (nothing will happen :( )</div>
</div>
Another common mistake with sticky is to forget about the height/width of the element relatively to the one of its parent. If the height of element is equal to the height of the parent (containing block) then logically there will be no sticky behavior because we are already at the opposite edge.
.block {
background: pink;
display:inline-flex;
vertical-align:top;
height: 200px;
max-width:100px;
flex-direction:column;
margin:100vh 0;
}
.block > div {
border:2px solid;
}
.e1 {
position: sticky;
top: 0;
}
<div class="block">
<div class="e1">Top sticky</div>
</div>
<div class="block">
<div class="e1" style="height:100%">I will not stick</div>
</div>
<div class="block">
<div class="e1" style="height:80%">I will stick a little ..</div>
</div>
<div class="block" style="height:auto">
<div class="e1">I will not stick too</div>
</div>
Notice the last case where the height of the parent is set to auto (default value) thus its height will be defined by its content which make the sticky element to have the same height as the containing block and nothing will happen because there is no room for a sticky behavior.
Try the following code:
.block {
background: pink;
width: 50%;
}
.movetop {
position: sticky;
top: 0;
background: #ccc;
padding: 10px;
color: #ae81fe;
z-index: 1;
border: 1px solid #777;
}
.movebot {
background: #ccc;
padding: 10px;
color: #ae81fe;
position: -webkit-sticky;
position: sticky;
border: 1px solid #777;
}
.movebot {
bottom: 0
}
11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>11111<br/>
<div class="block">
<div class="movetop">
header
</div>
content<br>content<br>content<br>content<br>content<br>content<br>content<br>content<br>content<br>content<br>content<br>content<br>
<div class="movebot">
footer
</div>
</div>
222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>222222<br/>
You can find more about position:sticky on gedd.ski/post/position-sticky

Grid layout for diamond icons/buttons using Boostrap [duplicate]

I have a selection of squares (squares turned 45° to look like diamonds) which I want to use to make up a big diamond shape with a central red diamond.
I am having issues organising the diamonds themselves and the href seems to fail.
How do I position the responsive diamonds in a regular grid?
Her is my code:
body {
background: black;
color: #000000;
font: 13px georgia, serif;
line-height: 1.4;
font-weight: lighter;
text-rendering: optimizelegibility;
}
#diamond {
width: 0;
height: 0;
border: 50px solid transparent;
border-bottom-color: white;
position: relative;
top: -50px;
}
#diamond:after {
content: '';
position: absolute;
left: -50px;
top: 50px;
width: 0;
height: 0;
border: 50px solid transparent;
border-top-color: white;
}
#diamond_red {
width: 0;
height: 0;
border: 50px solid transparent;
border-bottom-color: #AA1C08;
position: relative;
top: -50px;
}
#diamond_red:after {
content: '';
position: absolute;
left: -50px;
top: 50px;
width: 0;
height: 0;
border: 50px solid transparent;
border-top-color: #AA1C08;
}
<a class="navigation">
<center>
<div id="diamond"></div>
<div id="diamond"></div>
<div id="diamond" href="/photos/"></div>
<div id="diamond_red"></div>
<div id="diamond" href="/projects/"></div>
<div id="diamond"></div>
<div id="diamond"></div>
<div id="diamond" href="/archive/"></div>
</center>
</a>
The responsive grid of diamons:
I don't think you have the right aproach to achieve a regular responsive diamond grid layout. It would be much simpler to:
create a responsive grid of squares (3x3 or whatever grid you feel like)
then rotate the grid 45 degrees.
That way you won't have to fiddle with borders, pseudo elements (:after, :before) and positioning each diamond.
Here is a responsive example
It uses percentage width and padding-bottom to keep the diamonds responsive and transform:rotate(45deg); to rotate te whole grid and make it look like a diamond grid:
body{background:#000;}
#big_diamond {
width: 50%;
margin:15% auto;
overflow:hidden;
transform: rotate(45deg);
}
.diamond {
position: relative;
float: left;
width: 31.33%;
padding-bottom: 31.33%;
margin: 1%;
background: #fff;
transition:background-color .4s;
}
.diamond a {
position: absolute;
top: 0; left: 0;
width: 100%; height: 100%;
}
#red{background-color: #AA1C08;}
.diamond:hover, #red:hover{background-color:darkorange;}
<div id="big_diamond">
<div class="diamond"></div>
<div class="diamond"></div>
<div class="diamond"></div>
<div class="diamond"></div>
<div class="diamond" id="red"></div>
<div class="diamond"></div>
<div class="diamond"></div>
<div class="diamond"></div>
<div class="diamond"></div>
</div>
As other people have mentioned, there are some errors in your HTML that I corrected like: Ids need to be unique and href can't be used on divs.
You're going to need to be more specific / clear on your first question.
First of all, you are using the ID 'diamond' many times. IDs are meant to be unique and used for one element. You should be using classes for this, not IDs.
Second, you can't use href within div tags. You could wrap the divs in a tags like this:
<div class="diamond"></div>
Or, even better so that the whole shape is clickable you can put the a inside of the div and make the a a block level element that is 100% width and height like this:
<div class="diamond"></div>
div a{
width: 100%;
height: 100%;
display: block;
}
JSFiddle Example: http://jsfiddle.net/kQj24/1/
This html has fallback for browsers that don't support transform in that the diamond becomes a square. Also the <div> elements can be wrapped in <a> tags using this method without altering any existing css rules for a. If transform isn't supported the text inside the square class doesn't rotate either.
<center>
<div class="diamond">
<div class="row">
<div class="square"><p>Text</p></div>
<div class="square"></div>
<div class="square"><p>Text</p></div>
</div>
<div class="row">
<div class="square"><p>Text</p></div>
<div class="square red"><p>Text</p></div>
<div class="square"><p>Text</p></div>
</div>
<div class="row">
<div class="square"><p>More</p></div>
<div class="square"></div>
<div class="square"><p>Text</p></div>
</div>
</div>
</center>
CSS, using your existing body rule:
.diamond {
padding-top: 50px;
transform:rotate(45deg);
-ms-transform:rotate(45deg);
-webkit-transform:rotate(45deg);
}
.square {
background-color: white;
display: inline-block;
height: 50px;
overflow: hidden;
width: 50px;
}
.square:hover {
background-color: green;
}
.square p {
transform:rotate(-45deg);
-ms-transform:rotate(-45deg);
-webkit-transform:rotate(-45deg);
}
.red {
background-color: red;
}
http://jsfiddle.net/5Q8qE/8/

CSS align chat boxes to bottom of screen

I have several chat boxes and other div elements that need to be positioned at the bottom of the screen, aligned to the right.
Problem #1: Elements do not have the same height, and the smaller ones are vertically aligned with the top of the highest element. Fiddle: http://jsfiddle.net/sd69jdxp/
#container { position: fixed; bottom:0; left:0; right:0; }
.chat { border: 1px solid #999; float: right; position: relative; margin: 0 5px; }
Problem #2: Using the approach of
display: inline-block; vertical-align: bottom;
to align divs to the bottom of the page, the links (anchors) over the first (smallest) chat box are not clickable, as the parent container overlaps the links. And it's not possible to set a lower z-index to the chat container than to the content behind, since the chat boxes are children of the chat container and they MUST have a higher z-index than the page content. How can this issue be solved?
Fiddle showing this issue: http://jsfiddle.net/xw689yv8/
Summary
How can I force all divs to be aligned with the bottom right of the screen, without having the chat container (parent div of chat boxes) overlap the content in the page behind the chat boxes, thus making it unclickable?
Use pointer-events: none on the container; elements underneath it will now be clickable.
Arrange the chat boxes inside the fixed container with display: inline-block and vertical-align: bottom.
The chat boxes get pointer-events: auto so they and their children can be clicked.
For IE10 and below, check out this answer to an older question to transfer click events.
Example
See it full screen and select the text input sitting underneath the invisible container.
.under {
position: absolute;
bottom: 200px;
right: 200px;
}
#container {
position: fixed;
bottom: 0;
right: 0;
pointer-events: none;
}
.chat {
border: 1px solid #999;
display: inline-block;
vertical-align: bottom;
position: relative;
margin: 0 5px;
pointer-events: auto;
}
.title {
padding: 0.5em;
background-color: blue;
color: white;
}
.text {
padding: 10px;
}
<div class="under">
<input type="text" value="select me!" />
</div>
<div id="container">
<div class="chat">
<div class="title">This is the chat title</div>
<div class="text">
<p>Text 1</p>
<p>Text 2</p>
<p>Text 3</p>
</div>
<div class="chatbox">
<input type="text" />
</div>
</div>
<div class="chat">
<div class="title">This is the chat title</div>
<div class="text" style="height:250px">
<p>Text 1</p>
<p>Text 2</p>
<p>Text 3</p>
</div>
<div class="chatbox">
<input type="text" />
</div>
</div>
</div>
I am not sure how you want to align them so I put them over each other.
http://jsfiddle.net/ouu94tfv/
#container { position: fixed; bottom:0; left:0; right:0; }
.chat { border: 1px solid #999; right:0; position: absolute; bottom: 0; margin: 0 5px; display:inline-block; float:right;}
.title { padding: 0.5em; background-color: blue; color: white; }
.text { padding: 10px; }

How to get a background picture going outside max-width div

I have a responsive website with max-width set to 1000px, but I need to fit background picture that will overlap one of the divs and also place full page-width bottom borders to other divs.
The code i have is like this:
.container {
width: 100%;
max-width: 1000px;
}
.logotest {
background-color: #03b9e5;
height: 50px;
}
.navtest {
background-color: #e4ed00;
height: 25px;
}
.socialtest {
background-color: #ab801a;
height: 25px;
}
.main {
height: 750px;
background: url(background.jpg) no-repeat top center;
margin: auto;
}
.line {
border-bottom: 1px solid black;
}
.container:after {
clear: both;
content: ".";
display: block;
height: 0;
visibility: hidden;
}
<body>
<div class="container" id="first">
<div class="logotest">
</div>
<div class="socialtest">
</div>
<div class="navtest">
</div>
</div>
<div class="line"></div>
<div class="main line" id="second">
</div><div class="container">
<div id="third">
</div>
</div>
</body>
I get the first div with correct width and bottom border going across the full page width, second div has got the background picture showing, but the max-width of 1000px does no longer apply. The bottom border is shown correctly (dividing second and third div) and the third div has got the correct max-width applied again.
What am I doing wrong/not doing to get the max-width for the second div?
YOUR SOLUTION
If the browser support of background-size property is good enough for you, you can use background-size: cover;. Check here or here to see browser support.
Here is the code snippet to show how it works. Be sure to position your background-image to center center if you want it to always be centered.
.container {
width: 100%;
max-width: 300px;
margin: 0 auto;
}
.line {
border-bottom: 1px solid black;
}
.logotest {
background-color: #03b9e5;
height: 50px;
}
.navtest {
background-color: #e4ed00;
height: 25px;
}
.socialtest {
background-color: #ab801a;
height: 25px;
}
.main {
height: 250px;
background: url(http://lorempixel.com/250/250) no-repeat center center;
background-size: cover; /* This does the magic */
}
.container:after {
clear: both;
content: ".";
display: block;
height: 0;
visibility: hidden;
}
<body>
<div class="container" id="first">
<div class="logotest">
</div>
<div class="socialtest">
</div>
<div class="navtest">
</div>
</div>
<div class="line"></div>
<div class="main" id="second">
<div class="container">Put your content in here.</div>
</div>
<div class="line"></div>
<div class="container">
<div id="third">
</div>
</div>
<div class="line"></div>
</body>
LAST (BUT NOT LEAST)
You might want to check this great article about the state of responsive images in web design, that will help you if you are going into responsive web design: Responsive images done right.

creating custom popup background (dynamic height - resizable) made of three elements (top, middle, bottom)

I want to build CSS popup (or block) from three elements (top, middle, bottom).
I have always do it in simple way but there was no text area above the top/bottom part.
Now i have to build a custom background but don't have any idea how. Height of popup (block) should be dependent of content.
Is it possible to do without any JS hacks?
Slice it into nested boxes etc.
What i've tried is to create a container first, the a div for the arrow, then the content (with your background gradient) and a wrapper for the content (with the red background) and the content inside.
HTML
<div class="popup">
<div class="arrow"></div>
<div class="content">
<div class="wrapper">
<div class="top">Content top</div>
<div class="red-area">Your main content</div>
<div class="bottom">Bottom</div>
</div>
</div>
</div>​
Now you've a nice html basis, with which you can play with floating, padding, margin, background-colors and rounded corners, like this:
CSS
* { margin: 0; padding: 0 }
body { background: #eee; padding: 50px; }
/* .popup { width: 250px; } */ /* If you wanto to manually set a width for the whole popup */
.arrow {
float: left;
width: 25px;
height: 50px;
margin-top: 10px;
background: white; /* your arrow image here */
position: relative;
}
.content {
margin-left: 25px;
background: white;
background: white url("your/gradient-image.jpg") repeat-x center bottom;
padding: 10px;
border-radius: 10px;
box-shadow: 0 0 15px rgba(0,0,0,0.25);
}
.wrapper {
padding: 15px;
background: #ff7f7f;
}
​
I've floated the arrow to the left, left margin for the content and paddings for the wrapper.
It depends on border-radius and box-shadow which are supported in newer browsers.
If you like to support older browsers, then i recommend you to use more images for the visual effects.
Hope this helps. jsFiddle example
Try this:
-Divide the layout in 3 divs: top/bottom, with a fixed height and the top/bottom image as a background; and middle, using the middle image and repeating the background. Something like:
<!--Container-->
<div class="popup-container">
<!--Top part-->
<div class="top" style="height: 20px; background-image: url(top.jpg);"></div>
<!--Now the middle div with the background repeating only vertically-->
<div class="middle" style="height: auto; background-image: url(middle.jpg);
background-repeat: repeat-y;"></div>
<!--Bottom part-->
<div class="bottom" style="height: 20px; background-image: url(bottom.jpg);"></div>
</div>
Take a look on ColorBox it's so easy to use and u can customize it's css to do whatever you want.
you also able to define the popup content as a content from another page like that:
$.colorbox({href:"simplepage.html"});
Now the popup width will fit to whatever your page have....
it's apowerful tool try it.
I have found simple way to do it!
First create related block, inside content and three absolute blocks. Each of color don't overlaps other! Look at the example:
HTML:
<div class="popup-container">
<div class="content">
test 1<br />
test 2<br />
test 3<br />
test 4<br />
test 5<br />
test 6<br />
</div>
<div class="top"></div>
<div class="middle"></div>
<div class="bottom"></div>
</div>
CSS:
.popup-container {
position: relative;
}
.content {
z-index: 9999;
}
.top {
position: absolute;
width: 100%;
height: 20px;
background-color: red;
top: 0;
z-index: -1;
opacity: 0.5;
}
.middle {
position: absolute;
width: 100%;
background-color: yellow;
bottom: 40px;
top: 20px; /* height of top */
z-index: -1;
opacity: 0.5;
}
.bottom {
position: absolute;
width: 100%;
height: 40px;
background-color: blue;
bottom: 0;
z-index: -1;
opacity: 0.5;
}
http://jsfiddle.net/bhnuh/5/

Resources