Как выровнять оболочку CSS из выпадающего меню - PullRequest
0 голосов
/ 22 января 2019

Я создаю выпадающее меню, и оно выглядит примерно так, как я хочу, но способ, которым я достиг макета, делает область парения слишком большой с правой стороны, что показано здесь серым прямоугольником.Я хочу, чтобы зависание над серым квадратом (элемент .dropdown) рассматривалось как белая область, а выпадающий список игнорировался.

Как получить меню, которое будет закрываться при наведении курсора на область серого .dropdown?

рабочая демо здесь: https://codepen.io/anon/pen/BMarBb?editors=1100

enter image description here

a {
  text-decoration: none;
}

nav {
  font-family: monospace;
  margin-left: 300px;
}

ul {
  list-style: none;
  margin: 0;
  padding-left: 0;
}

li {
  color: #fff;
  background: darkorange;
  display: block;
  float: left;
  padding: 1rem;
  position: relative;
  text-decoration: none;
  transition-duration: 0.5s;
}

li a {
  color: #fff;
}

li:hover {
  cursor: pointer;
}

.dropdown {
  visibility: hidden;
  opacity: 0;
  position: absolute;
  transition: all 0.5s ease;
  margin-top: 1rem;
  left: 0;
  display: none;
  margin-left: 50%;
  background: silver;
}

li:hover .dropdown,
.dropdown:hover {
  visibility: visible;
  opacity: 1;
  display: block;
}

.dropdown li {
  clear: both;
  white-space: nowrap;
  background: none;
}

.wrapper {
  /*   background: green; */
  display: inline-block;
  margin-left: -50%;
  padding-top: 30px;
}

.inner {
  background: darkorange;
  display: inline-block;
  box-shadow: 12px 15px 45px 0 rgba(12, 0, 51, 0.2);
  border-radius: 4px;
}

.inner:before,
.inner:after,
.inner li:first-child:after {
  display: block;
  content: "";
  width: 0;
  height: 0;
  position: absolute;
  left: -12px;
  border: 12px outset transparent;
  margin-top: 29px;
}

.inner:after {
  border-bottom: 12px solid darkorange;
  top: -23px;
}
<nav role="navigation">
  <ul>
    <li><a href="#">One</a>
      <ul class="dropdown dropdown1">
        <section class="wrapper">
          <section class="inner">
            <li><a href="#">Sub-A</a></li>
            <li><a href="#">Sub-B</a></li>
            <li><a href="#">Sub-C</a></li>
          </section>
        </section>
      </ul>
    </li>
    <li><a href="#">Two</a>
      <ul class="dropdown dropdown2">
        <section class="wrapper">
          <section class="inner">
            <li><a href="#">Sub-1</a></li>
            <li><a href="#">Sub-2</a></li>
            <li><a href="#">Sub-3</a></li>
          </section>
        </section>
      </ul>
    </li>
    <li><a href="#">Three</a></li>
  </ul>
</nav>

Ответы [ 3 ]

0 голосов
/ 22 января 2019

См. Встроенные комментарии к CSS, чтобы узнать, как я управляю событиями при наведении на определенные элементы. Этот подход оставляет активную серую область прямо над выпадающим списком, что, на мой взгляд, является хорошим поведением.

Примечание. Это может не работать в Safari. Смотри https://caniuse.com/#feat=pointer.

a {
  text-decoration: none;
}

nav {
  font-family: monospace;
  margin-left: 300px;
}

ul {
  list-style: none;
  margin: 0;
  padding-left: 0;
}

li {
  color: #fff;
  background: darkorange;
  display: block;
  float: left;
  padding: 1rem;
  position: relative;
  text-decoration: none;
  transition-duration: 0.5s;
}

li a {
  color: #fff;
}

li:hover {
  cursor: pointer;
}

.dropdown {
  visibility: hidden;
  opacity: 0;
  position: absolute;
  transition: all 0.5s ease;
  margin-top: 1rem;
  left: 0;
  display: none;
  margin-left: 50%;
  background: silver;
  pointer-events: none; /* <-- disable hover events */
}

li:hover .dropdown,
.dropdown:hover {
  visibility: visible;
  opacity: 1;
  display: block;
}

.dropdown li {
  clear: both;
  white-space: nowrap;
  background: none;
}

.wrapper {
  /*   background: green; */
  display: inline-block;
  margin-left: -50%;
  padding-top: 30px;
  pointer-events: all; /* <-- enable hover events */
}

.inner {
  background: darkorange;
  display: inline-block;
  box-shadow: 12px 15px 45px 0 rgba(12, 0, 51, 0.2);
  border-radius: 4px;
}

.inner:before,
.inner:after,
.inner li:first-child:after {
  display: block;
  content: "";
  width: 0;
  height: 0;
  position: absolute;
  left: -12px;
  border: 12px outset transparent;
  margin-top: 29px;
}

.inner:after {
  border-bottom: 12px solid darkorange;
  top: -23px;
}
<nav role="navigation">
  <ul>
    <li><a href="#">One</a>
      <ul class="dropdown dropdown1">
        <section class="wrapper">
          <section class="inner">
            <li><a href="#">Sub-A</a></li>
            <li><a href="#">Sub-B</a></li>
            <li><a href="#">Sub-C</a></li>
          </section>
        </section>
      </ul>
    </li>
    <li><a href="#">Two</a>
      <ul class="dropdown dropdown2">
        <section class="wrapper">
          <section class="inner">
            <li><a href="#">Sub-1</a></li>
            <li><a href="#">Sub-2</a></li>
            <li><a href="#">Sub-3</a></li>
          </section>
        </section>
      </ul>
    </li>
    <li><a href="#">Three</a></li>
  </ul>
</nav>
0 голосов
/ 22 января 2019

Другой способ решить вашу проблему - удалить margin-left на .dropdown и .wrapper, а затем отцентрировать стрелку с помощью:

margin-right: auto;
margin-left: auto;
left: 0;
right: 0;

Поскольку в этом элементе также есть margin-top, вы можете написать margin: 29px auto 0; вместо margin-left и margin-right.

a {
  text-decoration: none;
}

nav {
  font-family: monospace;
  margin-left: 300px;
}

ul {
  list-style: none;
  margin: 0;
  padding-left: 0;
}

li {
  color: #fff;
  background: darkorange;
  display: block;
  float: left;
  padding: 1rem;
  position: relative;
  text-decoration: none;
  transition-duration: 0.5s;
}

li a {
  color: #fff;
}

li:hover {
  cursor: pointer;
}

.dropdown {
  visibility: hidden;
  opacity: 0;
  position: absolute;
  transition: all 0.5s ease;
  margin-top: 1rem;
  left: 0;
  display: none;
  background: silver;
}

li:hover .dropdown,
.dropdown:hover {
  visibility: visible;
  opacity: 1;
  display: block;
}

.dropdown li {
  clear: both;
  white-space: nowrap;
  background: none;
}

.wrapper {
  /*   background: green; */
  display: inline-block;
  padding-top: 30px;
}

.inner {
  background: darkorange;
  display: inline-block;
  box-shadow: 12px 15px 45px 0 rgba(12, 0, 51, 0.2);
  border-radius: 4px;
}

.inner:before,
.inner:after,
.inner li:first-child:after {
  display: block;
  content: "";
  width: 0;
  height: 0;
  position: absolute;
  border: 12px outset transparent;
  left: 0;
  right: 0;
  margin: 29px auto 0;
}

.inner:after {
  border-bottom: 12px solid darkorange;
  top: -23px;
}
<nav role="navigation">
  <ul>
    <li><a href="#">One</a>
      <ul class="dropdown dropdown1">
        <section class="wrapper">
          <section class="inner">
            <li><a href="#">Sub-A</a></li>
            <li><a href="#">Sub-B</a></li>
            <li><a href="#">Sub-C</a></li>
          </section>
        </section>
      </ul>
    </li>
    <li><a href="#">Two</a>
      <ul class="dropdown dropdown2">
        <section class="wrapper">
          <section class="inner">
            <li><a href="#">Sub-1</a></li>
            <li><a href="#">Sub-2</a></li>
            <li><a href="#">Sub-3</a></li>
          </section>
        </section>
      </ul>
    </li>
    <li><a href="#">Three</a></li>
  </ul>
</nav>

Редактировать: Как сказали Chiller и Temani Afif в разделе комментариев, структура вашего кода недействительна. Я быстро очистил ваш пример, чтобы вы могли видеть, что вы можете сделать с менее обернутыми элементами.

a { text-decoration: none; }

nav {
  font-family: monospace;
  margin-left: 300px;
}

ul {
  list-style: none;
  margin: 0;
  padding-left: 0;
}

li {
  color: #fff;
  background: darkorange;
  display: block;
  float: left;
  padding: 1rem;
  position: relative;
  text-decoration: none;
  transition-duration: 0.5s;
}

li a { color: #fff; }
li:hover { cursor: pointer; }

.dropdown {
  visibility: hidden;
  opacity: 0;
  position: absolute;
  transition: all 0.5s ease;
  margin-top: 1rem;
  left: 0;
  display: none;
}

li:hover .dropdown {
  visibility: visible;
  opacity: 1;
  display: block;
}

.dropdown { padding-top: 30px; }

.dropdown li {
  clear: both;
  white-space: nowrap;
  position: relative;
}

.dropdown li:first-child { border-radius: 4px 4px 0 0; }
.dropdown li:last-child { border-radius: 0 0 4px 4px; }

.dropdown li:first-child:before {
  content: "";
  bottom: 100%;
  left: 50%;
  border: solid transparent;
  height: 0;
  width: 0;
  position: absolute;
  border-bottom-color: darkorange;
  border-width: 12px;
  margin-left: -12px;
}
<nav role="navigation">
  <ul>
    <li><a href="#">One</a>
      <ul class="dropdown">
        <li><a href="#">Sub-A</a></li>
        <li><a href="#">Sub-B</a></li>
        <li><a href="#">Sub-C</a></li>
      </ul>
    </li>
    <li><a href="#">Two</a>
      <ul class="dropdown">
        <li><a href="#">Sub-1</a></li>
        <li><a href="#">Sub-2</a></li>
        <li><a href="#">Sub-3</a></li>
      </ul>
    </li>
    <li><a href="#">Three</a></li>
  </ul>
</nav>
0 голосов
/ 22 января 2019

Моя интерпретация вашего вопроса заключается в том, что вы хотите, чтобы раскрывающийся список скрывался, когда вы перестали зависать над оранжевой секцией.

То, что я сделал с приведенным ниже кодом, это position:absolute элементы с left:50%и transform:translate(-50%).Это выровняет элементы по центру по горизонтали таким образом, что оранжевые ссылки окажутся над серой областью.

a {
  text-decoration: none;
}

nav {
  font-family: monospace;
  margin-left: 300px;
}

ul {
  list-style: none;
  margin: 0;
  padding-left: 0;
}

li {
  color: #fff;
  background: darkorange;
  display: block;
  float: left;
  padding: 1rem;
  position: relative;
  text-decoration: none;
  transition-duration: 0.5s;
}

li a {
  color: #fff;
}

li:hover {
  cursor: pointer;
}

.dropdown {
  visibility: hidden;
  opacity: 0;
  position: absolute;
  transition: all 0.5s ease;
  margin-top: 1rem;
  left: 50%;
  display: none;
  transform: translate(-50%);
  background: silver;
}

li:hover .dropdown,
.dropdown:hover {
  visibility: visible;
  opacity: 1;
  display: block;
}

.dropdown li {
  clear: both;
  white-space: nowrap;
  background: none;
}

.wrapper {
  /*   background: green; */
  display: inline-block;
  padding-top: 30px;
}

.inner {
  background: darkorange;
  display: inline-block;
  box-shadow: 12px 15px 45px 0 rgba(12, 0, 51, 0.2);
  border-radius: 4px;
}

.inner:before,
.inner:after,
.inner li:first-child:after {
  display: block;
  content: "";
  width: 0;
  height: 0;
  position: absolute;
  left: 50%;
  transform: translate(-50%);
  border: 12px outset transparent;
  margin-top: 29px;
}

.inner:after {
  border-bottom: 12px solid darkorange;
  top: -23px;
}
<nav role="navigation">
  <ul>
    <li><a href="#">One</a>
      <ul class="dropdown dropdown1">
        <section class="wrapper">
          <section class="inner">
            <li><a href="#">Sub-A</a></li>
            <li><a href="#">Sub-B</a></li>
            <li><a href="#">Sub-C</a></li>
          </section>
        </section>
      </ul>
    </li>
    <li><a href="#">Two</a>
      <ul class="dropdown dropdown2">
        <section class="wrapper">
          <section class="inner">
            <li><a href="#">Sub-1</a></li>
            <li><a href="#">Sub-2</a></li>
            <li><a href="#">Sub-3</a></li>
          </section>
        </section>
      </ul>
    </li>
    <li><a href="#">Three</a></li>
  </ul>
</nav>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...