Центрировать псевдоэлемент

css pseudo-element

64611 просмотра

6 ответа

5650 Репутация автора

Первый раз действительно с помощью псевдо- :afterселектора. Не уверен, что проблема, с которой я сталкиваюсь, является ее ограничением, или я просто упускаю что-то очевидное.

Вот мой живой код .

li.current:after {
    border-width: 1px 1px 0 0;
    content: ' ';
    background: #256f9e;
    display: block;
    height: 13px;
    position: absolute;
    width: 10px;
    top: 6;
    margin:0px auto;
    z-index: 99;
    transform: rotate(-224deg);
    -webkit-transform: rotate(-224deg);
    -moz-transform: rotate(-224deg);
    -ms-transform: rotate(-224deg);
    -o-transform: rotate(-224deg);
    transform-origin: 50% 50%;
    -webkit-transform-origin: 50% 50%;
    -moz-transform-origin: 50% 50%;
    -ms-transform-origin: 50% 50%;
    -o-transform-origin: 50% 50%;
    text-align: center;
    float: center;
}

Я создал маленький треугольник (точнее, коробку, которая была повернута, чтобы выглядеть как треугольник). Я хочу, чтобы это было в центре, <li></li>но не могу понять, используя мои обычные методы. Вещи, которые потерпели неудачу (без определенного порядка):

text-align: center;
float: center;
margin: 0 auto;
margin-right: 0;
margin-left: 0;

Что мне не хватает? Я сомневаюсь, что это имеет значение, но я использую AngularJS. Думаю, я бы упомянул об этом в случае известного конфликта между Angular и Pseudo selectors (в чем я сомневаюсь). Благодарю.

Автор: EnigmaRM Источник Размещён: 29.05.2013 04:03

Ответы (6)


95 плюса

10273 Репутация автора

Решение

Проблема заключается в том, что вы используете absoluteпозиционирование и метод, который вы используете для его центрирования. Если вы позиционируете элемент абсолютно, старый margin: 0 auto;метод не сработает для центрирования элемента . Я укажу вам объяснение, почему это в конце вопроса, но если вы просто хотите, чтобы это сработало, давайте сначала найдем решение.

Вот некоторый рабочий код. Посмотреть это на JSFiddle

#tool-menu li {
  ...
  position: relative;
}

li.current:after {
  ...
  position: absolute;
  width: 10px;
  top: 6;
  left: 50%;
  margin-left: -5px;
}

Давайте разберемся, что здесь происходит.

Установка нового Содержащего Блока

В вашей оригинальной скрипке псевдоэлемент расположен абсолютно относительно области просмотра. Примером может быть лучший способ показать, что это значит, и почему мы этого не хотим. Рассмотрите возможность установки его top: 0. Это будет держать его привязанным к верхней части окна браузера (или, в данном случае, к рамке JSFiddle), а не к родительскому элементу (the li). Таким образом, если наше меню окажется в нижней части страницы или даже будет перемещаться, псевдоэлемент будет плавать независимо от него и прилипнет к верхней части страницы.

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

Чтобы это произошло, вам нужно установить родительский элемент, #tool-menu liчтобы он был явно позиционирован (что означает, что он должен быть установлен иначе position: static). Если вы решите использовать position: relative;, он не изменит вычисленное местоположение родителя на странице и сделает то, что мы хотим. Вот почему я использовал это.

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

Позиционирование псевдоэлемента

Теперь, когда наше абсолютное позиционирование будет определено по отношению к родителю, мы можем воспользоваться тем фактом, что мы можем использовать проценты, чтобы определить, куда поместить ребенка. В этом случае вы хотите, чтобы он был в центре, поэтому я установил его left: 50%.

Если вы сделаете именно это, вы увидите, что это выравнивает левый край псевдоэлемента на 50%. Это не то, что мы хотим - мы хотим, чтобы центр псевдоэлемента находился посередине. И именно поэтому я добавил негатив margin-left. Это немного смещает его, чтобы выровнять середину по центру родительского элемента.

И как только мы это сделаем, это будет в центре! Brilliance!

Почему не моя margin: auto;работа?

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

Автор: jamesplease Размещён: 29.05.2013 04:11

3 плюса

434 Репутация автора

Не имеет прямого отношения (уже проголосовал за jmeas), но вам также может быть проще использовать CSS-трюк с рамкой для создания треугольника. например

li.current:after {
    content: '';
    display: block;
    height: 0;
    position: absolute;
    width: 0;
    overflow:hidden;
    bottom: 0;
    left: 50%;
    margin: 0 0 -5px -5px;
    z-index: 99;
    border-top: 5px #256f9e solid;
    border-left: 5px transparent solid;
    border-right: 5px transparent solid;
}

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

Автор: MarkP Размещён: 29.05.2013 04:32

9 плюса

103 Репутация автора

Использование calcдля центрирования

Вы также можете использовать calcфункцию в css для центрирования псевдоэлемента.

Примечание: это не поддерживается в IE8 и ниже ( caniuse ), но вы можете предоставить запасной вариант для старых браузеров.

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

li.current:after {
  content: '';
  display: block;
  height: 0;
  position: absolute;
  width: 0;
  overflow: hidden;
  bottom: -5px;
  left: calc(50% - 5px);
  z-index: 2;
  border-top: 5px #256f9e solid;
  border-left: 5px transparent solid;
  border-right: 5px transparent solid;
}
Автор: Mark Reilly Размещён: 21.07.2014 05:01

1 плюс

2065 Репутация автора

Использование margin:autoдля центрирования

Пока элемент имеет объявленную ширину, вы можете использовать метод абсолютного центрирования.

Для использования этого метода rightи leftсвойства должны быть установлены в 0течение , margin: autoчтобы быть эффективными.

Этот метод может быть расширен для реализации горизонтального центрирования.

см. ссылку для полной информации:

http://www.smashingmagazine.com/2013/08/09/absolute-horizontal-vertical-centering-css/

li.current:after {
  content: "";
  position: absolute;
  display: block;
  right: 0;
  bottom: -5px;
  left: 0;
  margin: auto;
  border-width: 5px;
  border-style: solid;
  border-color: transparent;
  border-top-color: #256f9e;
  width: 200px;
  height: 200px;
}

ul {
  list-style-type: none;
  padding: 0;
  margin: 0;
}
<div>
  <ul>
    <li class="current"></li>
  </ul>
</div>

Автор: user1095118 Размещён: 12.04.2015 09:37

3 плюса

31 Репутация автора

Не лучше ли просто определить ширину в процентах, сделать ее блочным элементом и выровнять ее по центру?

"плавать: центр;" является недействительным и не будет работать. Смешивание плавающих и абсолютно позиционированных элементов - верный способ получить проблемы с вашим макетом, поскольку они не очень хорошо работают вместе.

Попробуйте что-то вроде этого:

li.current:after {
content: 'YOUR CONTENT';
display: block;
width: 100%;
text-align: center; }
Автор: Hexdom Размещён: 26.06.2017 11:52

0 плюса

36 Репутация автора

С элементом pesudo: after или: before use display: inline-block;

Попробуйте что-то вроде этого:

content: url(../images/no-result.png);
display: inline-block;
width: 100%;
text-align: center;
Автор: ocram88 Размещён: 20.09.2019 09:20
Вопросы из категории :
32x32