Yogesh Bhatt
Yogesh Bhatt

Reputation: 127

Why are margins not consistent?

I have set the margin of my child divs to 40px, yet the distance between the parent container and first div is less that the distance between first and second div. Furthermore, there is difference of 1-2 between the rest of gaps. You can crosscheck by inserting two adjacent element's index in place of existing indexes at rows 9 and 10 of my JavaScript code. For instance: The gap between first and second element is 105px, between 2nd and 3rd it's 104px, between 3rd and 4th it is 106px, and between 4th and 5th it is back to 104px. These all should've been 40px (80px i guess as i just checked margin don't collapse horizontally). Am i missing something very basic? I'm trying to make an image slider. Files

let projectContainer = document.querySelector(".project-container")
let projects = document.querySelectorAll(".project")

let initialPosition = 0;
let mouseIsDown = false
let distanceTravelled = 0;

elementAOffset = projects[3].offsetLeft;
elementBOffset = projects[4].offsetLeft;
elementAWidth = parseInt(getComputedStyle(projects[0]).width)
margin = (elementBOffset - (elementAOffset + elementAWidth))

var LeftSideBoundary = -1 * ((elementAWidth * 2) + (margin))
var RightSideBoundary = (elementAWidth * 6) + (margin * 5) + elementAOffset
var RightSidePosition = RightSideBoundary - elementAWidth;

projectContainer.addEventListener("mousedown", e => {
    mouseIsDown = true
    initialPosition = e.clientX;
    console.log("Mouse key pressed")
})

projectContainer.addEventListener("mouseup", e => {
    mouseExit(e)
})

projectContainer.addEventListener("mouseleave", e => {
    mouseExit(e);
})


projectContainer.addEventListener("mousemove", e => {
    if (!mouseIsDown) { return };
    projects.forEach(project => {
        project.style.transform = 'translateX(' + ((e.clientX - initialPosition) + project.currentTranslationX ?? 0) + 'px)'
        shiftPosition(e, project)
    })
})




function mouseExit(e) {
    mouseIsDown = false

    distanceTravelled = e.clientX - initialPosition

    var example_project = projects[0]
    var style = window.getComputedStyle(example_project)
    currentTranslationX = (new WebKitCSSMatrix(style.webkitTransform)).m41


    projects.forEach(project => {
        var style = window.getComputedStyle(project)
        project.currentTranslationX = (new WebKitCSSMatrix(style.webkitTransform)).m41

        project.style.transform = 'translateX(' + (project.currentTranslationX ?? 0) + 'px)'

    })
}


function shiftPosition(e, project) {
    animationShift = window.getComputedStyle(project)
    animationShift = (new WebKitCSSMatrix(animationShift.webkitTransform)).m41
    animationShift = animationShift + project.offsetLeft

    if (animationShift <= LeftSideBoundary) {
        project.style.transform = "translateX(" + (RightSidePosition - project.offsetLeft) + "px)"
    }
}
*, *::before, *::after{
    margin:0px;
    padding:0px;
    box-sizing: border-box;
    font-size:100px;
    user-select: none;
}

.project-container{
    width:1500px;
    height:400px;
    background-color: rgb(15, 207, 224);
    margin:auto;
    margin-top:60px;
    white-space: nowrap;
    overflow: hidden;
}

.project{
    margin:40px 40px 40px 40px;
    display: inline-block;
    height:300px;
    width:350px;
    background-color:white;
    border: black 3px solid;
    user-select: none;
}
<body>
    <div class="project-container">
        <div class="project">1</div>
        <div class="project">2</div>
        <div class="project">3</div>
        <div class="project">4</div>
        <div class="project">5</div>
        <div class="project">6</div>
        <div class="project">7</div>
        <div class="project">8</div>
    </div>
</body>

Upvotes: 0

Views: 224

Answers (1)

FluffyKitten
FluffyKitten

Reputation: 14312

The main problem is that you are using inline-block, which uses inline display and this means all the content is displayed inline - even white space. What you are seeing is the white space that is in your HTML between the </div> of one block and the <div> of the next.

There have been various workarounds, for example, removing the space between the elements, e.g.

<div class="project">1</div><div class="project">2</div><div class="project">3</div>...etc

However, these days the best way is to use the flexbox layout.

  • Use display:flex in the container
  • This is the important part for your example: flex: none; for the boxes inside that container (otherwise they will get resized to fit into the display area, regardless of what width you have given them in the CSS)

The CSS you need to add is:

.project-container{
    display: flex;
    /* rest of your CSS */
}

.project{
    flex: none;
    /* rest of your CSS */
}

Working Snippet (note: I've removed the margins so you can see it more clearly):

*, *::before, *::after{
    margin:0px;
    padding:0px;
    box-sizing: border-box;
    font-size:100px;
    user-select: none;
}

.project-container{
    display: flex;
    width:1500px;
    height:400px;
    background-color: rgb(15, 207, 224);
    margin:auto;
    margin-top:60px;
    white-space: nowrap;
    overflow: hidden;
}

.project{
    flex: none;
    margin:40px 0;
    display: inline-block;
    height:300px;
    width:350px;
    background-color:white;
    border: black 3px solid;
    user-select: none;
}
<div class="project-container">
        <div class="project">1</div>
        <div class="project">2</div>
        <div class="project">3</div>
        <div class="project">4</div>
        <div class="project">5</div>
        <div class="project">6</div>
        <div class="project">7</div>
        <div class="project">8</div>
    </div>

Upvotes: 2

Related Questions