Why is adding 'margin: 0 auto' to a slider menu breaks it?

by Nyko Gagné   Last Updated September 11, 2019 17:26 PM

I'm creating a slider menu and everything was working fine until I tried to center it with margin: 0 auto;

I strongly think the problem comes from relative positioning and the jQuery .animate function I am using. So I am looking for another way to achieve the same result!

Here's a fiddle with the problem

http://jsfiddle.net/jwsh7/ (image couldn't be include so I put a border on everything, the problem is with the green bordered div)

Remove margin: 0 auto; to see that it works as I want it to.

body {
  margin: 0;
  padding: 0;
}

#content {
  width: 625px;
  border: 1px solid red;
}

#content div.slider {
  position: relative;
  width: 50px;
  height: 100px;
  background-image: url(images/rond.png);
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
  z-index: 2;
  top: 110px;
  left: 25px;
  border: 1px solid red;
}

.menu {
  color: #00C;
  font-size: 18px;
  font-family: "OnomatoShark!";
  position: absolute;
  width: 50px;
  height: 100px;
  background-image: url(images/ligne_barre.png);
  background-position: center;
  background-repeat: no-repeat;
  cursor: pointer;
  border: 1px solid red;
}

.menu p {
  width: 150px;
  float: left;
  position: absolute;
  top: -25px;
  left: 10px;
}

.menu p:hover {
  width: 150px;
  float: left;
  position: absolute;
  top: -25px;
  color: red;
}

#barre {
  position: relative;
  width: 600px;
  height: 28px;
  background-image: url(images/ligne.png);
  background-position: center;
  list-style-type: none;
  top: 25px;
  padding: 0;
  border: 1px solid red;
}

#sousMenu1 {
  margin: 0;
  padding: 0;
  margin-top: 90px;
  background-image: url(images/sousmenu.png);
  background-position: left;
  background-repeat: no-repeat;
  overflow: hidden;
  float: left;
  height: 150px;
  display: none;
  text-align: left;
}

#sousMenu2 {
  margin: 0;
  padding: 0;
  margin-top: 90px;
  margin-left: 10px;
  background-image: url(images/sousmenu.png);
  background-position: left;
  background-repeat: no-repeat;
  overflow: hidden;
  float: left;
  height: 150px;
  display: none;
}

#sousMenu3 {
  margin: 0;
  padding: 0;
  margin-top: 90px;
  margin-left: 10px;
  background-image: url(images/sousmenu.png);
  background-position: left;
  background-repeat: no-repeat;
  height: 150px;
  width: 250px;
  overflow: hidden;
  float: left;
  display: none;
}

#sousMenu4 {
  margin: 0;
  padding: 0;
  margin-top: 90px;
  margin-left: 10px;
  background-image: url(images/sousmenu.png);
  background-position: left;
  background-repeat: no-repeat;
  height: 150px;
  overflow: hidden;
  float: left;
  display: none;
}

ol {
  text-align: left;
  padding-top: 20px;
}

ol a {
  text-decoration: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="content">

  <div class='slider'></div>

  <ul id="barre">
    <li class="menu" id="option1">
      <p>Accueil</p>
    </li>

    <li class="menu" id="option2">
      <p>Animation</p>
      <ul class="sous-menu" id="sousMenu1">
        <ol><a href="#">Histoire</a></ol>
        <ol><a href="http://google.com">Avancées technologiques</a></ol>
      </ul>
    </li>

    <li class="menu" id="option3">
      <p>Techniques</p>
      <ul class="sous-menu" id="sousMenu2">
        <ol><a href="#">Rotoscopie</a></ol>
        <ol><a href="#">Trait</a></ol>
      </ul>

    </li>

    <li class="menu" id="option4">
      <p>Fondements</p>
      <ul class="sous-menu" id="sousMenu3">
        <ol><a href="#">Processus de production</a></ol>
        <ol><a href="#">Interpolation</a></ol>
        <ol><a href="#">Guide de mouvement</a></ol>
      </ul>
    </li>

    <li class="menu" id="option5">
      <p>Principes</p>
    </li>

    <li class="menu" id="option6">
      <p>Effets Avancés</p>
      <ul class="sous-menu" id="sousMenu4">
        <ol><a href="#">Rotation</a></ol>
      </ul>
    </li>
  </ul>



</div>
<script type="text/javascript">
  $(document).ready(function() {

    function sousmenuCache() {

      $("#sousMenu1").hide("fast");
      $("#sousMenu2").hide("fast");
      $("#sousMenu3").hide("fast");
      $("#sousMenu4").hide("fast");

    }

    $("#option1").click(function() {
      sousmenuCache();
    });

    $("#option2").click(function() {
      sousmenuCache();
      $("#sousMenu1").delay(300).show("slow");
    });

    $("#option3").click(function() {
      sousmenuCache();
      $("#sousMenu2").delay(300).show("slow");
    });

    $("#option4").click(function() {
      sousmenuCache();
      $("#sousMenu3").delay(300).show("slow");
    });

    $("#option5").click(function() {
      sousmenuCache();
    });

    $("#option6").click(function() {
      sousmenuCache();
      $("#sousMenu4").delay(300).show("slow");
    });




    // Centrer la barre dans le container

    var middleOption = ($("#barre").height() - ($("#option1").height() - $("#barre").height()));

    // Création des options du menu
    var leftOption = -70;
    $("#content #barre li").each(function() {
      $(this).css('top', '' + middleOption + 'px');
      $(this).css('left', '' + (leftOption + 90) + 'px');

      leftOption += 90;
    });

    $(function() {

      $(".menu").click(function() {
        var middleSlider = (($(".slider").width() - $("#option1").width()) * 0.5);
        $(".slider").animate({
          left: ($(this).offset().left - middleSlider)
        });

      });
    });
    TweenMax.set("#content", {
      x: 300
    });
  });
</script>



Answers 2


The problem is that you are using both margin and position to position the slide and they are conflicting. To make it dead center, use a margin-left that is -0.5 * width of the slider, and then left:50%;

#content div.slider {   
    position:relative;
    width: 50px;
    height: 100px;
    background-image:url(images/rond.png);
    background-repeat:no-repeat;
    background-position:center;
    background-size:cover;
    z-index: 2; 
    top: 110px;
    left: 50%;
    border: 1px solid green;
    margin-left:-25px;
}
Jason Lydon
Jason Lydon
March 19, 2013 19:27 PM

When you center #content you have to take into account additional offset when doing animation. Hard to explain, take a look at this updated fiddle:

http://jsfiddle.net/jwsh7/1/

var fix = ($(document).width() - $('#content').width()) * .5; // <-- need to subtract this

$(".menu").click(function () {
    var middleSlider = ($(".slider").width() - $("#option1").width()) * 0.5;
    $(".slider").animate({
        left: ($(this).offset().left - middleSlider - fix)
    });
});
dfsq
dfsq
March 19, 2013 19:33 PM

Related Questions


Updated August 07, 2017 18:26 PM

Updated August 14, 2017 08:26 AM

Updated February 08, 2018 23:26 PM

Updated May 01, 2018 06:26 AM

Updated July 21, 2017 03:26 AM