Inherit padding width without position absolute? Is it possible? - javascript

Not sure, but I am currently not able to figure out. I'm trying to center the inner div (blue transparent one) from the parent (with the red background) inside the background. As an example, they're technically in each other perfectly at the first example in the snippet.
At the second example however I've added padding: 5px; to both of them to the red and blue one. To the blue one because I wanted to inherit the width some how.
https://jsfiddle.net/L8enbcy3/
.box-1-1 {
width: 50px;
height: 50px;
background: red;
position: relative;
display: block;
}
.box-1-2 {
width: 50px;
height: 50px;
background: #0000ffb0;
position: relative;
}
.box1 {
width: 50px;
height: 50px;
background: red;
padding: 5px;
position: relative;
display: block;
}
.box2 {
width: 50px;
height: 50px;
background: #0000ffb0;
padding: 5px;
}
<div class="box-1-1">
<div class="box-1-2"></div>
</div>
<pre>
</pre>
<div class="box1">
<div class="box2"></div>
</div>
What I'm trying is to get "box2" centered into "box1" like example 1 but with its padding, so that's covered by blue. without having to position: absolute it, if possible. What I'm thinking I have to do is to create and invisibile box absolute it, "center it with top: 0 and left: 0 when the parent has position: relative. Then as I mentioned with it being absolute it would go to the corners of the parents padding too and then in the absolute box, I would create a relative one with display: table and put in all the content.
My question now though is, is there another way to do that?

Solution 1: transform: translate()
You could use transform: translate() with variables to achieve what you want, without weird margins (next solution). Here's some MDN about translate().
:root {
--padding: 5px;
}
.box1 {
height: 50px;
width: 50px;
background-color: red;
padding: var(--padding);
}
.box2 {
height: calc(50px + var(--padding)*2);
width: calc(50px + var(--padding)*2);
background-color: #0000ffb0;
transform: translate(calc(0px - var(--padding)), calc(0px - var(--padding)))
}
<div class="box1">
<div class="box2"></div>
</div>
As you can see, the box is brought up and left with translate, and the height is lengthened by adding the needed padding to it. Thisachieves the desired cover effect.
Solution 2: Positive padding, negative margin
You could also use positive paddings and negative margins. Info below code snippet.
:root {
--padding: 5px;
}
.box1 {
height: 50px;
width: 50px;
background-color: red;
padding: var(--padding);
position: relative;
display: block;
}
.box2 {
height: 50px;
width: 50px;
background-color: #0000ffb0;
padding: var(--padding);
margin: calc(0px - var(--padding));
}
<div class="box1">
<div class="box2"></div>
</div>
What's happening here is following the CSS box model, found on MDN and w3schools. We're simply pushing out with margin and sucking in with padding.
Then, as per request in the comments, --padding is a CSS variable that stores the amount of padding that you want.
Hope I helped!
Cheers, Bobbay

You can add a negative margin if you insist on keeping the padding in place.
.box-1-1 {
width: 50px;
height: 50px;
background: red;
position: relative;
display: block;
}
.box-1-2 {
width: 50px;
height: 50px;
background: #0000ffb0;
position: relative;
}
.box1 {
width: 50px;
height: 50px;
background: red;
padding: 5px;
position: relative;
display: block;
}
.box2 {
width: 50px;
height: 50px;
background: #0000ffb0;
padding: 5px;
margin: -5px;
}
<div class="box-1-1">
<div class="box-1-2"></div>
</div>
<pre>
</pre>
<div class="box1">
<div class="box2"></div>
</div>

To center box2 within box1 without absolute position, you can use following css:
.box1 {
display: flex;
align-items: center;
justify-content: center;
}

Edit: example 2 illustrate your need. just remove padding from both boxes and settop: 0; and 'left: 0' with position: relative on box 2. I hope this is the required solution
to center box 2 you need to make its dimension less than box 1. consider the extra pixels added with padding. so the inner box width and height should be 10px less than the outer box.
Example:
.box1 {
width: 50px;
height: 50px;
background: red;
padding: 5px;
position: relative;
display: block;
}
.box2 {
width: 40px;
height: 40px;
background: #0000ffb0;
padding: 5px;
}
.box1-1 {
border: 2px solid yellow;
width: 50px;
height: 50px;
background: red;
position: relative;
display: block;
}
.box2-2 {
position:relative;
top: 0px;
left: 0px;
width: 50px;
height: 50px;
background: #0000ffb0;
}
<div class="box1">
<div class="box2"></div>
</div>
<br>
<div class="box1-1">
<div class="box2-2"></div>
</div>

Related

Inline divs are not lining up in a row

It's my understanding that simply adding display:inline to divs with a relative position will line them up (left to right), somewhat like float:left. I've tried both approaches but they haven't worked.
Below is an example of my last attempt, using inline displaying. I want all three segments to line up from left to right, but they're displaying just like unstyled divs.
function showProfile() {
var profile = document.getElementById('userprofile');
profile.style.opacity = 0.8;
var profileImage = document.getElementById('userimage');
profileImage.style.opacity = 0.8;
}
.profile {
top: 68px;
background-color: #424755;
color: #dddddd;
width: 100%;
min-height: 50px;
opacity: 0;
position: fixed;
font: 16px"Tahoma";
}
.miniProfileImage {
opacity: 0;
width: 100px;
height: 100px;
}
.miniBioSegment {
display: inline;
margin-right: 5px;
width: 33%;
}
<div class="profile" id="userprofile">
<div class="miniBioSegment">
<img class="miniProfileImage" id="userimage" src="http://dummyimage.com/100x100/000088/ffffff.png&text=Profile+image">
</div>
<div id="miniBio" class="miniBioSegment">
This is basic information about this person that you clicked.
</div>
<div id="miniQuote" class="miniBioSegment">
This is a tag line from the person that you clicked.
</div>
</div>
<button onclick="showProfile()">View Profile</button>
You should use inline-block instead of inline for more control. I used a width of 33%-2px because the browser rounds the div's size up therefore leading to overflowing. Your 5px margins weren't helping with the sum either.
function showProfile() {
var profile = document.getElementById('userprofile');
profile.style.opacity = 0.8;
var profileImage = document.getElementById('userimage');
profileImage.style.opacity = 0.8;
}
.profile {
top: 68px;
background-color: #424755;
color: #dddddd;
width: 100%;
min-height: 50px;
opacity: 0;
position: fixed;
font: 16px"Tahoma";
}
.miniProfileImage {
opacity: 0;
width: 100px;
height: 100px;
display:inline-block;
}
.miniBioSegment{
display: inline-block;
width: calc(33% - 2px);
vertical-align:middle;
}
<div class="profile" id="userprofile">
<div class="miniBioSegment">
<img class="miniProfileImage" id="userimage" src="http://dummyimage.com/100x100/000088/ffffff.png&text=Profile+image">
</div>
<div id="miniBio" class="miniBioSegment">
This is basic information about this person that you clicked.
</div>
<div id="miniQuote" class="miniBioSegment">
This is a tag line from the person that you clicked.
</div>
</div>
<button onclick="showProfile()">View Profile</button>
CSS should target the ID's and use float:left. See example
.profile {
top: 68px;
background-color: #424755;
color: #dddddd;
width: 100%;
min-height: 50px;
position: fixed;
font: 16px"Tahoma";
}
.miniProfileImage {
float:left;
max-width: 33%;
height: 100px;
}
#miniBio {
float:left;
margin-right: 5px;
width: 33%;
}
#miniQuote {
float:left;
margin-right: 5px;
width: 33%;
}
<div class="profile" id="userprofile">
<div class="miniBioSegment">
<img class="miniProfileImage" id="userimage" src="http://dummyimage.com/100x100/000088/ffffff.png&text=Profile+image">
</div>
<div id="miniBio" class="miniBioSegment">
This is basic information about this person that you clicked.
</div>
<div id="miniQuote" class="miniBioSegment">
This is a tag line from the person that you clicked.
</div>
</div>
I'm asking myself, why do you have position:absolute;?
To make it work, I have just added display: flex; justify-content: space-between; to the .profileclass.
Remove the position, and try adding the last two lines.
See example here: http://sandbox.clickadelic.de/demos/lineup.html
With the divs set to display: inline; they will only line up horizontally if the total length of the divs does not exceed the container's width.
And width, height of inline elements is ignored, you should use display: inline-block; instead. The wrapping behavior is the same as above.
Also browser renders whitespace among inline* elements, which is about 4px, see How to remove the space between inline-block elements? for more details.
In your example, there are 3 divs, if you want them to be equal width, you can do:
.profile {
font-size: 0; /*remove whitespace*/
background: silver;
}
.miniBioSegment {
font-size: 16px; /*reset font-size*/
display: inline-block;
vertical-align: top; /*vertical alignment*/
width: 33.3333%;
}
However, the image object in the first div is set to 100px, I think you would prefer that div to be the same width too, and each one takes 50% of the rest space for other two divs. Examples:
1. Inline block
jsFiddle
.profile {
font-size: 0;
background: silver;
}
.miniBioSegment {
font-size: 16px;
display: inline-block;
vertical-align: top;
border: 1px dotted red;
box-sizing: border-box;
width: 100px;
}
#miniBio, #miniQuote {
width: calc((100% - 100px) / 2);
}
.miniProfileImage {
width: 100px;
height: 100px;
display: block;
}
2. Float
jsFiddle
.profile {
background: silver;
}
.profile:after {
content: "";
display: table;
clear: both;
}
.miniBioSegment {
float: left;
border: 1px dotted red;
box-sizing: border-box;
width: 100px;
}
#miniBio, #miniQuote {
width: calc((100% - 100px) / 2);
}
.miniProfileImage {
width: 100px;
height: 100px;
display: block;
}
3. CSS table
jsFiddle
.profile {
background: silver;
display: table;
border-collapse: collapse;
width: 100%;
}
.miniBioSegment {
display: table-cell;
vertical-align: top;
border: 1px dotted red;
}
#miniBio, #miniQuote {
width: 50%;
}
.miniProfileImage {
width: 100px;
height: 100px;
display: block;
}
4. Flexbox
jsFiddle
.profile {
background: silver;
display: flex;
}
.miniBioSegment {
border: 1px dotted red;
}
#miniBio, #miniQuote {
flex: 1;
}
.miniProfileImage {
width: 100px;
height: 100px;
display: block;
}

Positioning a div at specific fixed place irrespective of zoom and scroll

I have a header with fixed position and inside header I have navigation links but when I zoom into browser links are thrown out of window to right. How can I make the navigation links fixed to 50px right no matter I zoom in or out.
jsfiddle here I don't want to change properties of header.
.header {
width: 100%;
min-width: 500px;
position: fixed;
background: red;
height: 60px;
}
.navlinks {
float: right;
margin-right: 50px;
width: 30px;
margin-top: 4px;
height: 20px;
background: black;
}
<div class="header">hello
<div class='navlinks'></div>
</div>
You've already set the fixed position header to width:100% so the min-width:500px is unnecessary.
Remove that and the issue is solved.
.header {
width: 100%;
position: fixed;
background: red;
height: 60px;
}
.navlinks {
float: right;
margin-right: 50px;
width: 30px;
margin-top: 4px;
height: 20px;
background: black;
}
<div class="header">hello
<div class='navlinks'></div>
</div>
JSfiddle Demo

On display of hidden element it shows on wrong place because of scroll, only in chrome

I don't realy know how to explain this thing in short sentence.
I don't know if it is bug or not..
In parent div with fixed height and overflow-y scroll, I have multiple children elements, which has jquery function click, what displays hidden element in these divs. When I scroll down to last div, after click, hidden element displays in wrong place.
I tried to search for this problem, cause it should be pretty common. But nothing came up.s
It's realy hard to explain with words. Just look at this jquery example with mozilla and after that with chrome.
https://jsfiddle.net/zvwcdzjz/2/#
P.S. I need my original example work and look exactly the same on chrome and mozilla, cause right now on mozilla everything looks exactly as i want it to be, but it bugs on chrome.
It can be solved with jQuery too, makes no difference for me.
HTML:
<div id="el">
<div class="content">
<div class="block">
<div class="blocktoopen"></div>
<div class="button">click to open</div>
</div>
<div class="block">
<div class="blocktoopen"></div>
<div class="button">click to open</div>
</div>
<div class="block">
<div class="blocktoopen"></div>
<div class="button">click to open</div>
</div>
</div>
</div>
CSS:
#el {
width: 300px;
height: 400px;
overflow-x: hidden;
overflow-y: scroll;
background-color: rgba(0,0,0,0.1);
}
#el .content {
width: 300px;
height: auto;
}
.block {
width: 300px;
height: 200px;
margin-top: 10px;
background-color: rgba(0,0,0,0.2);
}
.button {
background-color: blue;
color: #fff;
cursor: pointer;
text-align: center;
margin-top: 90px;
float: left;
}
.blocktoopen {
width: 50px;
height: 50px;
position: absolute;
margin-left: 300px;
background-color: red;
display: none;
}
JS:
$(function(){
$(".button").click(function(){
$(this).parent(".block").children(".blocktoopen").show();
});
$("#el").scroll(function(){
$(".blocktoopen").hide(); });
});
The set height of #el was causing the red box to appear in the incorrect location. I have removed this. See the example below:
Change:
#el {
width: 300px;
height: 400px;
overflow-x: hidden;
overflow-y: scroll;
background-color: rgba(0,0,0,0.1);
}
To:
#el {
width: 300px;
overflow-x: hidden;
overflow-y: scroll;
background-color: rgba(0,0,0,0.1);
}
And then you're good to go.
To make your life simpler make the parent .bloc relative so the blocktoopen will be computed relatively. Will help with the responsiveness.
.block {
width: 300px;
height: 200px;
margin-top: 10px;
background-color: rgba(0,0,0,0.2);
position: relative;
}
.blocktoopen {
width: 50px;
height: 50px;
position: absolute;
top: 50%;
bottom: 50%;
background-color: red;
display: none;
right: 0;
}
I can't post comment so here is another try with jsfiddle. I am not sure if you have horizontal scroll as well. remove margin-right from .blocktoopen and add right:0; Also wrap all your internal content inside a div and set the width to maybe 225px
#el {
width: 300px;
height: 400px;
overflow-x: hidden;
overflow-y: scroll;
background-color: rgba(0,0,0,0.1);
}
#el .content {
width: 300px;
height: auto;
}
.block {
width: 300px;
height: 200px;
margin-top: 10px;
background-color: rgba(0,0,0,0.2);
position: relative;
}
.button {
background-color: blue;
color: #fff;
cursor: pointer;
text-align: center;
margin-top: 90px;
float: left;
}
.blocktoopen {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
display: none;
top: 50%;
bottom: 50%;
right: 0;
}
.internal{
width: 225px;
}
Have you tried to click on 2 buttons without scrolling? Try it. Looks like you were using visibility: hidden; and not display: none;. Maybe trying to set the position: relative; ...
Just seen the jquery script. Show() and hide() appears to work as visibility css property.
If u look with Chrome DevTools the jsFiddle example you will see that you can't see the red boxes but they are still there.

JQuery drop functionality not working as expected?

I've been trying to implement drag and drop functionality using JQuery. I've got 3 'draggable' divs and 3 'droppable' divs. Div with id 'draggable1' should be accepted by div with id 'droppable1' and so on. However, it only works for one pair of the divs(draggable1 and droppable1). It doesn't work for the other two.
I think it's somehow related to the css positioning. When I don't set the margin properties for the individual divs, it works. However, if I want to position the divs elsewhere, the functionality doesn't work anymore.
Here's a jsfiddle I've created: https://jsfiddle.net/3ews8j8x/
HTML
<center><h3>Drag and Drop</h3></center>
<div class="wrap">
<div class="draggables" id="draggable1"></div><br>
<div class="draggables" id="draggable2"></div><br>
<div class="draggables" id="draggable3"></div><br>
</div>
<div id="droppable1"></div>
<div id="droppable2"></div>
<div id="droppable3"></div>
CSS
body{
margin: 0;
}
.wrap{
width: 400px;
height: 300px;
background: #e3e3e3;
position: relative;
margin-top: 80px;
}
.draggables{
width: 20px;
height: 20px;
margin: auto;
position: absolute;
margin-left: 30px;
}
#draggable1{
background: #003366;
position: relative;
}
#draggable2{
background: #ffff00;
position: relative;
margin-top: 90px;
}
#draggable3{
background: #ff0000;
margin-top: -150px;
margin-left: 220px;
}
#droppable1{
width: 50px;
height: 50px;
background: #0000FF;
margin-left: 600px;
margin-top: -200px;
}
#droppable2{
width: 50px;
height: 50px;
background: #008080;
margin-left: 700px;
margin-top: -50px;
}
#droppable3{
width: 50px;
height: 50px;
background: #00cc00;
margin-left: 800px;
margin-top: -50px;
}
Javascript code is provided in the link.
I want to know why it doesn't work when I try to change the positioning of the divs. Can it not be done or am I doing something wrong? I've been stuck with this problem for over 3 days now. Any help would be appreciated.
Thank you in advance.
So there were a few fundamental errors. Firstly the .draggables are set to position:relative; These need to be absolute. You were positioning these .draggables with margins, you should be positioning them with top & left:
JSFiddle
.draggables{
width: 20px;
height: 20px;
position: absolute;
}
#draggable1{
background: #003366;
}
#draggable2{
background: #ffff00;
top: 90px;
}
#draggable3{
background: #ff0000;
top: 150px;
left: 220px;
}

Centering CSS Boxes(Html and Css)

I am trying to center these boxes in the middle of the screen both horizontally and vertically. Another question is how can I make it where it re-sizes automatically when I scale my page?
/*-------------------------
Simple reset
--------------------------*/
*{
margin:0;
padding:0;
}
/*-------------------------
General Styles
--------------------------*/
/*----------------------------
Color Themes
-----------------------------*/
.nav-colors{
position: relative;
background: white;
height: 200px;
width: 60%;
margin: 0 auto;
padding: 20px;
overflow: auto;
}
.home-link{
background-color:#00c08b;
width: 15%;
height: 80px;
display: inline-block;
margin-left: 10%;
}
.portfolio-link{
background-color:#ea5080;
width: 15%;
height: 80px;
display: inline-block;
}
.social-link{
background-color:#53bfe2;
width: 15%;
height: 80px;
display: inline-block;
}
.contact-link{
background-color:#f8c54d;
width: 15%;
height: 80px;
display: inline-block;
}
.blog-link{
background-color:#df6dc2;
width: 15%;
height: 80px;
display: inline-block;
}
<!DOCTYPE html>
<html>
<head>
<title>Neiko Anglin | Front-End Develper </title>
<!-- Our CSS stylesheet file -->
<link rel="stylesheet" href="css/styles.css" />
<!-- Font Awesome Stylesheet -->
<link rel="stylesheet" href="font-awesome/css/font-awesome.css" />
</head>
<body>
<div class="nav-colors">
<div class="home-link">
</div>
<div class="portfolio-link">
</div>
<div class="social-link">
</div>
<div class="contact-link">
</div>
<div class="blog-link">
</div>
</div>
</body>
</html>
You can use absolute positioning on the container to center vertically and horizontally:
/*-------------------------
Simple reset
--------------------------*/
* {
margin:0;
padding:0;
}
/*-------------------------
General Styles
--------------------------*/
/*----------------------------
Color Themes
-----------------------------*/
.nav-colors {
position: absolute;
background: white;
height: 84px;
width: 60%;
margin: auto;
padding: 20px;
overflow: auto;
top:0;
right:0;
bottom:0;
left:0;
}
.home-link {
background-color:#00c08b;
width: 15%;
height: 80px;
display: inline-block;
margin-left: 10%;
}
.portfolio-link {
background-color:#ea5080;
width: 15%;
height: 80px;
display: inline-block;
}
.social-link {
background-color:#53bfe2;
width: 15%;
height: 80px;
display: inline-block;
}
.contact-link {
background-color:#f8c54d;
width: 15%;
height: 80px;
display: inline-block;
}
.blog-link {
background-color:#df6dc2;
width: 15%;
height: 80px;
display: inline-block;
}
<div class="nav-colors">
<div class="home-link"></div>
<div class="portfolio-link"></div>
<div class="social-link"></div>
<div class="contact-link"></div>
<div class="blog-link"></div>
</div>
To align vertically you need a wrapper class with position absolute in CSS. Search for vertical center which will fetch you lots of results.
To resize boxes along with screen resize - is responsive template. I could suggest you to use Twitter Bootstrap which takes care of your dimensions.
Change your .nav-color class to
.nav-colors{
position: fixed;
background: white;
height: 80px;
width:60%;
margin: -60px 0 0 0;
padding: 20px;
overflow: auto;
top:50%;
left:20%;
}
/*-------------------------
Simple reset
--------------------------*/
* {
margin: 0;
padding: 0;
}
/*-------------------------
General Styles
--------------------------*/
/*----------------------------
Color Themes
-----------------------------*/
.nav-colors {
position: fixed;
background: white;
height: 80px;
width: 60%;
margin: -60px 0 0 0;
padding: 20px;
overflow: auto;
top: 50%;
left: 20%;
}
.home-link {
background-color: #00c08b;
width: 15%;
height: 80px;
display: inline-block;
margin-left: 10%;
}
.portfolio-link {
background-color: #ea5080;
width: 15%;
height: 80px;
display: inline-block;
}
.social-link {
background-color: #53bfe2;
width: 15%;
height: 80px;
display: inline-block;
}
.contact-link {
background-color: #f8c54d;
width: 15%;
height: 80px;
display: inline-block;
}
.blog-link {
background-color: #df6dc2;
width: 15%;
height: 80px;
display: inline-block;
}
<div class="nav-colors">
<div class="home-link">
</div>
<div class="portfolio-link">
</div>
<div class="social-link">
</div>
<div class="contact-link">
</div>
<div class="blog-link">
</div>
</div>
You just have to add some properties to your .nav-colors:
.nav-colors{
position: relative;
background: white;
height: 200px;
width: 60%;
margin: 0 auto;
padding: 20px;
overflow: auto;
line-height: 200px;
text-align: center;
}
And add vertical-align: middle; to elements you want to center vertically.
First the explanation, then some code.
Vertical centering is a classic css issue. The vh unit has come in very handy for this recently. Coupled with margin (and maybe calc) its now a solvable thing.
Centering it horizontally is simple enough, and you have that figured out. Just have a width and set margin: 0 auto and you are good to go.
With Vertical Centering the key thing to remember is you are centering your element, so half is over the middle, half is under the middle. With that we can make margin: calc(50vh-40px) auto 0 for your 80px high element and presto, it's in the middle vertically.
One step further:
Like horizontal centering, you seem to already have the dynamic width down by using %.
For a dynamic vertical size we can again turn to vh. The nice thing is this saves us the css calc function. Just subtract half the height from the 50vh margin and you'll get your margin. So for height: 20vh the margin is margin: 40vh auto 0
Here is a JsFiddle
and here is some code:
CSS:
*{
margin: 0;
padding: 0;
}
html, body{
width: 100vw;
height: 100vh;
}
.nav-colors{
width: 80%;
height: 20vh;
margin: calc(40vh) auto 0;
}
.nav-colors div{
width: 18%;
margin: 0 0 0 1%;
height: 100%;
display: inline-block;
}
.home-link{background-color:#00c08b;}
.portfolio-link{background-color:#ea5080;}
.social-link{background-color:#53bfe2;}
.contact-link{background-color:#f8c54d;}
.blog-link{background-color:#df6dc2;}
HTML:
<div class="nav-colors">
<div class="home-link"></div>
<div class="portfolio-link"></div>
<div class="social-link"></div>
<div class="contact-link"></div>
<div class="blog-link"></div>
</div>
enjoy.

Categories