Отзывчивый выравнивание текста по позиции

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

Есть ли средство, только с помощью CSS, изменить обоснование элемента и его дочерних элементов на основе того, ориентировано ли оно больше налево или вправо экрана?

Там нет прямой собственности для этого, но я вижу, если я пропустил какой-то хакерский метод, возможно, с участием псевдоселекторов или элементов.

Демонстрация текущего затруднительного положения:

У меня есть панель навигации <ul> которая содержит смесь ссылок <a> и некоторых вложенных контейнеров <ul> для выпадающих меню при наведении указателя мыши. Довольно стандартно и отлично работает на более широких экранах:

enter image description here

Если доступ к экрану меньше, навигационная панель переносится на следующую строку, как предполагалось. Это желаемый результат. Однако иногда выпадающие меню могут быть усечены за кадром, что не очень желательно:

enter image description here

Вместо того, чтобы предлагать совершенно разные стили для мобильных устройств (мой резервный план состоит в том, чтобы представить раскрывающиеся меню в виде диалоговых вариантов через размещение postion: fixed на меньших экранах, а не на position: absolute как сейчас), я мог бы исправить мои ситуация, когда мои элементы осознают свое приключение вне экрана и необходимость как text-align: right и, возможно, корректируют их абсолютное позиционирование для привязки справа от родительского <li> а не слева, как сейчас:

enter image description here

Я могу управлять этим с помощью javascript, но у меня уже достаточно событий для прослушивания, и вы хотите предоставить более элегантный ответ, который позволяет избежать javascript. Если нет метода css-only, я могу вместо этого использовать альтернативу фиксированной позиции, как план b.

Разъяснения:

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

Например, количество навигационных элементов может расти в будущем и может представлять эту ситуацию на любом экране. Просто нужно выпадающее меню, которое будет справа.

Я также не могу гарантировать, что устройство, которое я еще не тестировал, не реплицирует проблему, размер которой я не ожидал.

Моя точка зрения заключается в том, что я не вижу способа, которым я могу полагаться на запросы на размер экрана. Я думаю, что мое решение, если оно есть, должно реагировать на положение элемента на экране - вот почему я думаю, что может оказаться неудачным для решения, отличного от javascript.

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

Образец кода:

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

Код - это упрощенная версия, но вопрос можно было задать практически с любым стандартным знакомым меню навигации <ul> которое предоставляет выпадающие списки с помощью :hover в CSS.

Имея это в виду, если вы пытаетесь решить вопрос, работая через мой код, я, возможно, плохо описал свое затруднительное положение. Я считаю, что я довольно хорошо разбираюсь в экстентах, в которые в настоящее время может быть добавлен CSS, и верю, что ответ будет "невозможен без javascript", но я просто гарантирую, что не упустил умного обходного пути/взлома для динамического изменения атрибутов элемента через CSS на основе экранной позиции (извините за повторение вопроса - я просто хочу убедиться, что он понял, следуя некоторым комментариям). Благодарю.

<ul class="nav nav__container">

    <li><a class='nav nav__item' href="#">Standard Link</a></li>
    <li><a class='nav nav__item' href="#">Standard Link</a></li>
    <li><a class='nav nav__item' href="#">Standard Link</a></li>
    <li><a class='nav nav__item' href="#">Standard Link</a></li>
    <li class='nav nav__item nav__item--dropdown'><li><a href="#">Dropdown Label</a></li>
        <ul class='nav nav__dropdown'>
            <li><a class='nav nav__item nav__item--dditem' href="#">Dropdown Link</a></li>
            <li><a class='nav nav__item nav__item--dditem' href="#">Dropdown Link</a></li>
            <li><a class='nav nav__item nav__item--dditem' href="#">Dropdown Link</a></li>
        </ul>
    </li>

</ul>

Ответы

Ответ 1

Это похоже на ответ на главный вопрос:

Есть ли средство, только с помощью CSS, изменить обоснование элемента и его дочерних элементов на основе того, ориентировано ли оно больше налево или вправо экрана?

нет.

В качестве более тщательного последующего ответа я подумал, что я бы сказал, что я не собираюсь с моим первоначальным планом B выпадающих меню стилизации фиксироваться при меньших размерах экрана. Я намекнул на это в своем вопросе, но стало более очевидным, что я не могу полагаться на размер экрана, чтобы определить, будет ли выпадающее меню усекаться в будущем. Поэтому, учитывая, что медиа-запросы теперь исключены, мне нужно другое решение, если я хочу, чтобы я не предоставлял неаккуратное решение для любого устройства.

Что оставляет меня с javascript. Я пытался избежать этого, но на данном этапе я был бы упрям, чтобы сделать это, учитывая исход.

метод

Если вы используете его для кого-то другого, я использовал jquery, чтобы предоставить слушателю зависание над раскрывающимися меню. Логика заключается в том, что у всех элементов определенного класса есть раскрывающееся меню, состоящее из <ul> другого класса. Поэтому я могу легко настроить таргетинг.

Я мог проверить, находится ли раскрывающееся меню справа или слева от экрана. Это будет нормально работать. Будучи разборчивым, я предпочел бы, чтобы меню оставалось оправданным влево, если оно не было около 200 пикселей справа от экрана - безопасный порог для моего динамического контента. Я мог бы измерить каждую ширину выпадающего списка и использовать это как порог, если у меня возникнут проблемы.

Все это вместе. Если я нахожусь над выпадающим меню, и он окажется менее чем на 200 пикселей справа от экрана, он будет как оправдывать свое меню вправо, так и абсолютное положение раскрывающегося меню в правой части его родительского ярлыка меню /trigger (как я показал в своих оригинальных иллюстрациях). Есть более гибкие и более короткие версии этого, и также не намного больше работать без jquery для тех, кто избегает библиотеки:

Код JS

$(nav).on('mouseover', '.dropdown', function() {

    var dropdownlist = $(this).children('ul');
    var screenWidth = $(window).width();
    var parentOffsetLeft = $(this).offset().left;
    var spaceRight = screenWidth - parentOffsetLeft;

    if (spaceRight < 200) {

        $(dropdownlist).css('text-align', 'right');
        $(dropdownlist).css('right', '0');
        $(dropdownlist).css('left', 'initial');

    } else {

        $(dropdownlist).css('text-align', 'left');
        $(dropdownlist).css('left', '0');
        $(dropdownlist).css('right', 'initial');

    }

});

Используя этот javascript, я могу воссоздать решение, проиллюстрированное в вопросе.

Ответ 2

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


Используя селектор nth-child CSS3 с переменной n вы можете настроить таргетинг на каждый третий или четвертый и т.д. Пункт меню верхнего уровня. Целевые элементы можно легко стилизовать, чтобы их выпадающие меню выравнивались вправо. Таким образом, для жестко закодированного решения на одном экране вы подсчитываете количество элементов меню верхнего уровня в строке и устанавливаете это как ваш множитель n. Например, если ваше меню завершено после 6 элементов, чтобы создать последний элемент каждой строки, вы должны установить что-то вроде:

.top-level-item:nth-child(6n) > .dropdown-container > .sub-item {
    float: right;
    clear: right;
}

или, тем не менее, ваша фактическая реализация требует стиля для выравнивания вправо.

Конечно, это зависит от всех элементов меню, имеющих одинаковую ширину. Если ваше меню имеет более 2 строк, а ваши пункты меню имеют разную ширину, вы можете иметь различное количество элементов в каждой строке, и в этом случае селектор nth-child не обязательно будет нацелен на конечный дочерний элемент каждой строки.

Теперь, чтобы сделать эту работу для любого размера экрана, если все элементы верхнего уровня имеют одинаковую фиксированную ширину, нам нужно выяснить, сколько элементов будет в каждой строке независимо от ширины окна. К сожалению, calc() слишком ограничен для этого приложения. Однако, если верхние элементы имеют фиксированную ширину, и мы знаем, что это за ширина, мы можем использовать ряд операторов @media для каждого случая.

Например, скажем, что с полями и шириной вместе каждый элемент верхнего уровня имеет ширину 230 пикселей. Это означает, что если ширина окна меньше 230 * 3 = 690 пикселей, в каждой строке будет 2 элемента. Если ширина окна меньше 230 * 4 = 920 пикселей и более 690 пикселей, в каждой строке будет 3 элемента. И так далее, к самому большому размеру окна, который, по вашему мнению, вам понадобится. Используя приведенный выше пример nth-child, серия медиа-запросов для каждого размера строки будет выглядеть примерно так:

@media (max-width: 690px) {
    /* less than 3 items per row */
    .top-level-item:nth-child(2n) > .dropdown-container > .sub-item {
        float: right;
        clear: right;
    }
}
@media (max-width: 920px) and (min-width: 691px) {
    /* less than 4 items per row */
    .top-level-item:nth-child(3n) > .dropdown-container > .sub-item {
        float: right;
        clear: right;
    }
}
@media (max-width: 1150px) and (min-width: 921px) {
    /* less than 5 items per row */
    .top-level-item:nth-child(4n) > .dropdown-container > .sub-item {
        float: right;
        clear: right;
    }
}
...
/* and so on */

Перо, которое показывает реализацию, это https://codepen.io/jla-/pen/GYJQMq. Обратите внимание, что JavaScript доступен только для переключения выпадающих меню при нажатии.


Для элементов верхнего уровня, имеющих переменную ширину, или если они имеют одинаковую ширину, но вы не знаете, какое значение оно имеет, я не думаю, что текущий CSS достаточно мощный, чтобы делать то, что вы хотите. В идеале вы бы сделали что-то вроде .top-level-item:nth-child(calc((100vw / --itemwidth)-(100vw%--itemwidth)) чтобы получить количество элементов в строке, но я думаю, что CSS очень далеко от такого рода власти.

Ответ 3

Может быть, медиа-запрос с помощью flex может помочь вам, если вы правильно его используете. Я попытался реплицировать вашу проблему на jsfiddle.

<div id="menu-container">
  <div class="menu"></div>
  <div class="menu"></div>
  <div class="menu">
      <div id="sub-menu-container">
          <div class="sub-menu" id="sub-menu1"></div>
          <div class="sub-menu" id="sub-menu2"></div>
          <div class="sub-menu" id="sub-menu3"></div>
          <div class="sub-menu" id="sub-menu4"></div>
      </div>
  </div>
  <div class="menu"></div>
</div>

CSS

.menu{
  border-radius:15px;
  background-color: #00ab9e;
  width:120px;
  height:50px;
  border: 1px solid #01eae9;
  display:inline-block;
  margin:5px;
  position:relative;
  vertical-align:top;
}
#sub-menu-container{
  margin-top:50px;
  display: flex;
  flex-flow: column wrap;
  align-items: flex-start;
}
.sub-menu{
  border-radius:15px;
  background-color: #ffb12a;
  width:120px;
  height:50px;
  border: 1px solid #01eae9;
  margin-top:5px;
}
#sub-menu2{
  width:150px;
}

#sub-menu3{
  width:200px;
}

@media only screen and (max-width: 495px) {
    #sub-menu-container {
      align-items: flex-end;
    }
}
@media only screen and (max-width: 420px) {
    #sub-menu-container {
      align-items: flex-start;
    }
}

https://jsfiddle.net/nimittshah/7bsf1r3v/

Спасибо

Ответ 4

Напишите медиа-запрос для вашего требования, так как вы хотите настроить выравнивание текста. вы можете изменить свойство, обоснованное для проверки в медиа-запросе. используйте различные медиа-запросы для разных размеров дисплея в соответствии с вашим требованием, см. пример

@media only screen and (max-width: 600px) {
selector {
    property : value;
}
}