Техника CSS для горизонтальной линии со словами в середине


286

Я пытаюсь создать горизонтальное правило с текстом в середине. Например:

----------------------------------- мой заголовок здесь ------------ -----------------

Есть ли способ сделать это в CSS? Без всех черточек "-", очевидно.


Это внутри formтега?
тридцать пятого

в этом случае, как thirtydot отметил в ответ на мой ответ, вы можете посмотреть вверх fieldsetи legendэлементы
Стефан Мюллер



Ответы:


404

Это примерно так, как я бы это сделал: строка создается установкой a border-bottomна содержание, а h2затем передачей h2меньшего line-height. Затем текст помещается во вложенный spanнепрозрачный фон.

h2 {
   width: 100%; 
   text-align: center; 
   border-bottom: 1px solid #000; 
   line-height: 0.1em;
   margin: 10px 0 20px; 
} 

h2 span { 
    background:#fff; 
    padding:0 10px; 
}
<h2><span>THIS IS A TEST</span></h2>
<p>this is some content other</p>

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

JSFiddle: http://jsfiddle.net/7jGHS/


3
Это мое любимое решение. Это работает на OSX тоже, а некоторые другие нет. Если вы используете это решение, не забудьте установить цвет фона того же цвета, что и фон вашей страницы, будет особенно очевидно, что я имею в виду, если ваш фон не белый. ;)
DrLazer

1
любой способ сделать это около четверти пути через?
Трой Косентино

1
Получить текст с отступом слева, используя «text-align: left; text-indent: 40px;» в стиле h2.
Matt__C

15
Это не гибко, так как вы исправляете цвет фона текста как белый.
Чао

2
@NateBarbettini Если строка, которую вы пытаетесь сделать, и текст не должны иметь прозрачного фона для других вещей позади него.
Кобурн

266

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

h1 {
  overflow: hidden;
  text-align: center;
}

h1:before,
h1:after {
  background-color: #000;
  content: "";
  display: inline-block;
  height: 1px;
  position: relative;
  vertical-align: middle;
  width: 50%;
}

h1:before {
  right: 0.5em;
  margin-left: -50%;
}

h1:after {
  left: 0.5em;
  margin-right: -50%;
}
<h1>Heading</h1>
<h1>This is a longer heading</h1>

Я проверял это в IE8, IE9, Firefox и Chrome. Вы можете проверить это здесь http://jsfiddle.net/Puigcerber/vLwDf/1/


2
Мне тоже нравится этот. Чтобы получить стиль, в котором текст имеет отступ слева, а не по центру, используйте это изменение: h1 { overflow: hidden; `text-align: left; текстовый отступ: 40px; `}
Matt__C

9
Это действительно хорошее решение; тем более что он работает с любым фоном и не требует заданной ширины элемента заголовка.
Лука

2
Это круто. Я немного адаптировал ваш код, чтобы выровнять текст по левому краю и сделать :afterэлемент шириной блока. Мне интересно: в чем конкретно заключается роль margin-right: -50%? Когда я возился с кодом, отсутствие этого свойства делало оформление переломом на другую строку. И даже когда :afterему назначена ширина 100%, мне все равно нужно отрицательное поле справа-50%, чтобы оно подходило. Зачем?
BeetleTheNeato

Насколько я понимаю, добавление отрицательных полей в обе стороны тянет элемент в обоих направлениях, поэтому он центрируется.
Puigcerber

2
Одна из вещей, которые мне нравятся в этом решении, это то, что оно работает в ситуациях, когда вы не знаете, какого цвета фон. Легко лучшее решение для этой проблемы.
JoeMoe1984

54

Хорошо, этот более сложный, но он работает во всем, кроме IE <8

<div><span>text TEXT</span></div>

div {
    text-align: center;
    position: relative;
}
span {
    display: inline-block;    
}
span:before,
span:after {
    border-top: 1px solid black;
    display: block;
    height: 1px;
    content: " ";
    width: 40%;
    position: absolute;
    left: 0;
    top: 1.2em;
}
span:after {
   right: 0;  
   left: auto; 
}

Элементы: before и: after расположены абсолютно так, что мы можем потянуть один влево и один вправо. Кроме того, ширина (в данном случае 40%) очень зависит от ширины текста внутри .. нужно подумать над решением для этого. По крайней мереtop: 1.2em гарантирует, что строки остаются более или менее в центре текста, даже если у вас другой размер шрифта.

Это, кажется, работает хорошо, хотя: http://jsfiddle.net/tUGrf/3/


3
Они умные, но я надеюсь, что ОП не хочет этого внутри formтега. Если он делает, как я уверен, вы знаете, он мог бы просто использовать fieldsetи legend.
тридцать пятого

1
Хех, ты прав насчет этого. В любом случае, можно пойти и на это, если это не сработает ... не семантически правильно, но это лучше, чем прибегать к javascript для чего-то подобного этому imo.
Стефан Мюллер

8
Лучшее решение, которое я нашел, которое хорошо работает, когда экран находится без фона цвета текста, это jsfiddle.net/vLwDf/268
Ксавье Джон,

Да @ xavier-john, это мой ответ ;)
Puigcerber

43

Самый короткий и лучший метод:

span:after,
span:before{
    content:"\00a0\00a0\00a0\00a0\00a0";
    text-decoration:line-through;
}
<span> your text </span>


4
Вы должны добавить описание того, что делает ваш код, если вы не хотите, чтобы он был удален.
inf3rno

В моем случае строка оказалась слишком толстой, поэтому я взломал ее, назначив другое семейство шрифтов: font-family: monospace;работало нормально.
Михаил Васин

38

Вот решение на основе Flex.

Заголовок с центральной горизонтальной линией в стороны

h1 {
  display: flex;
  flex-direction: row;
}
h1:before, h1:after{
  content: "";
  flex: 1 1;
  border-bottom: 1px solid #000;
  margin: auto;
}
h1:before {
  margin-right: 10px
}
h1:after {
  margin-left: 10px
}
<h1>Today</h1>

JSFiddle: https://jsfiddle.net/yoshiokatsuneo/3h1fmj29/


Как получить прокладку?
Сайлар

быстро и грязно, вы можете добавить & NBSP;
Крисмаркс

1
Я использую другой элемент: <h1><span>Today</span></h1>с полем / отступом на промежутке.
Джесси Буитенхойс

19

для более позднего (ныне) браузера, display:flexandd pseudo-elements облегчает рисование. border-style, box-shadowИ даже backgroundпомогает также для макияжа. демо ниже

h1 {margin-top:50px;
  display:flex;
  background:linear-gradient(to left,gray,lightgray,white,yellow,turquoise);;
}
h1:before, h1:after {
  color:white;
  content:'';
  flex:1;
  border-bottom:groove 2px;
  margin:auto 0.25em;
  box-shadow: 0 -1px ;/* ou 0 1px si border-style:ridge */
}
<h1>side lines via flex</h1>


Спасибо за это, очень ловко!
Джимми Обонио Абор

Идеальное, единственное решение, которое работало для меня, когда фон был изображением
cjohansson

12

.hr-sect {
	display: flex;
	flex-basis: 100%;
	align-items: center;
	color: rgba(0, 0, 0, 0.35);
	margin: 8px 0px;
}
.hr-sect::before,
.hr-sect::after {
	content: "";
	flex-grow: 1;
	background: rgba(0, 0, 0, 0.35);
	height: 1px;
	font-size: 0px;
	line-height: 0px;
	margin: 0px 8px;
}
<div class="hr-sect">Text</div>


9
<div><span>text TEXT</span></div>

div { 
  height: 1px; 
  border-top: 1px solid black; 
  text-align: center; 
  position: relative; 
}
span { 
  position: relative; 
  top: -.7em; 
  background: white; 
  display: inline-block; 
}

Дайте интервалу отступ, чтобы сделать больше пространства между текстом и строкой.

Пример: http://jsfiddle.net/tUGrf/


1
Хорошо, единственная проблема в том, что вы должны установить белый фон и не можете установить его прозрачным.
Марникс

в этом случае вам придется работать с двумя линиями, по одной на каждой стороне. Это будет трудно достичь чистым способом ..
Стефан Мюллер

Пока что мой любимый подход, но, к сожалению, по какой-то причине он не работает в почтовых клиентах (Gmail для мобильных устройств и в Интернете)
reedwolf

9

Я искал некоторые решения для этого простого украшения и нашел немало, некоторые странные, некоторые даже с JS для вычисления высоты шрифта и бла, бла, бла, потом я прочитал один на этот пост и прочитать комментарий от тридцати, говоря о fieldsetиlegend я подумал , что это было.

Я переопределяю эти 2 стиля элементов, я думаю, вы могли бы скопировать для них стандарты W3C и включить их в свой .middle-line-textкласс (или как вы хотите это называть), но я сделал это так:

<fieldset class="featured-header">
    <legend>Your text goes here</legend>
</fieldset>

<style>
.featured-header{
    border-bottom: none;
    border-left: none;
    border-right: none;
    text-align: center;
 }

.featured-header legend{
    -webkit-padding-start: 8px; /* It sets the whitespace between the line and the text */
    -webkit-padding-end: 8px; 
    background: transparent; /** It's cool because you don't need to fill your bg-color as you would need to in some of the other examples that you can find (: */
    font-weight: normal; /* I preffer the text to be regular instead of bold  */
    color: YOU_CHOOSE;
}   

</style>

Вот скрипка: http://jsfiddle.net/legnaleama/3t7wjpa2/

Я играл со стилями границ, и это также работает в Android;) (Проверено на kitkat 4.XX)

РЕДАКТИРОВАТЬ:

Следуя идее Бекерова Артура, которая также является хорошим вариантом, я изменил изображение .png base64, чтобы создать обводку с помощью .SVG, чтобы вы могли рендерить в любом разрешении, а также изменять цвет элемента без участия какого-либо другого программного обеспечения :)

/* SVG solution based on Bekerov Artur */
/* Flexible solution, scalable, adaptable and also color customizable*/
.stroke {
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' width='1px' height='1px' viewBox='0 0 1 1' enable-background='new 0 0 1 1' fill='%23ff6600' xml:space='preserve'><rect width='1' height='1'/></svg>");
background-repeat: repeat-x;
background-position: left;
text-align: center;
}
.stroke h3 {
background-color: #ffffff;
margin: 0 auto;
padding:0 10px;
display: inline-block;
font-size: 66px;
}

5

Решение для IE8 и новее ...

Вопросы стоит отметить:

С помощью background-color маскировки границы может быть не лучшим решением. Если у вас сложный (или неизвестный) цвет фона (или изображение), маскировка в конечном итоге потерпит неудачу. Кроме того, если вы измените размер текста, вы заметите, что белый цвет фона (или любой другой заданный вами размер) начнет скрывать текст в строке выше (или ниже).

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

Решение:

( Посмотреть JSFiddle )

Вместо того, чтобы «маскировать» границу с помощью background-color, используйте вашу displayсобственность.

HTML

<div class="group">
    <div class="item line"></div>
    <div class="item text">This is a test</div>
    <div class="item line"></div>
</div>

CSS

.group { display: table; width: 100%; }
.item { display: table-cell; }
.text { white-space: nowrap; width: 1%; padding: 0 10px; }
.line { border-bottom: 1px solid #000; position: relative; top: -.5em; }

Измените размер текста, разместив вашу font-sizeсобственность на.group элемент.

Ограничения:

  • Нет многострочного текста. Только отдельные строки.
  • HTML-разметка не так элегантна
  • topсвойство на .lineэлементе должно быть половиной line-height. Итак, если у вас есть line-heightо 1.5em, то topдолжно быть -.75em. Это ограничение, потому что оно не автоматизировано, и если вы применяете эти стили к элементам с разной высотой строки, вам может потребоваться повторно применить ваш line-heightстиль.

Для меня эти ограничения перевешивают «проблемы», которые я отметил в начале моего ответа для большинства реализаций.


Работает на хроме. Кажется семантическим и довольно простым. Работает с начальной загрузкой.
Джефф Ансель

Мне пришлось добавить border-collapse: отделить от .group, потому что я использую его в состоянии, которое имеет другую настройку. Прекрасно работает.
Брайан МакКей,

5

Это дает вам фиксированную длину линий, но прекрасно работает. Длина строк контролируется путем добавления или взятия '\ 00a0' (пробел в юникоде).

введите описание изображения здесь

h1:before, h1:after {
  content:'\00a0\00a0\00a0\00a0';
  text-decoration: line-through;
  margin: auto 0.5em;
}
<h1>side lines</h1>


2

Если кому-то интересно, как установить заголовок таким образом, чтобы он отображался с фиксированным расстоянием до левой стороны (а не по центру, как показано выше), я понял это, изменив код @ Puigcerber.

h1 {
  white-space: nowrap;
  overflow: hidden;
}

h1:before, 
h1:after {
  background-color: #000;
  content: "";
  display: inline-block;
  height: 1px;
  position: relative;
  vertical-align: middle;
}

h1:before {
  right: 0.3em;
  width: 50px;
}

h1:after {
  left: 0.3em;
  width: 100%;
}

Здесь JSFiddle .


2
h6 {
    font: 14px sans-serif;
    margin-top: 20px;
    text-align: center;
    text-transform: uppercase;
    font-weight: 900;
}

    h6.background {
        position: relative;
        z-index: 1;
        margin-top: 0%;
        width:85%;
        margin-left:6%;
    }

        h6.background span {
            background: #fff;
            padding: 0 15px;
        }

        h6.background:before {
            border-top: 2px solid #dfdfdf;
            content: "";
            margin: 0 auto; /* this centers the line to the full width specified */
            position: absolute; /* positioning must be absolute here, and relative positioning must be applied to the parent */
            top: 50%;
            left: 0;
            right: 0;
            bottom: 0;
            width: 95%;
            z-index: -1;
        }

это поможет тебе


между линией

<h6 class = "background"> ​​<span> <br> НАШИ УСЛУГИ </ span> </ h6> это HTML-код
Доминик Амаль Джо, F

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

Извините, Mogsdad Я забыл поместить HTML-код, поэтому я поместил его здесь.
Доминик Амаль Джо Ф

2

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

введите описание изображения здесь

  • нет жестко заданных размеров
  • нет изображений
  • нет псевдоэлементов
  • уважает фон
  • внешний вид панели управления

https://jsfiddle.net/eq5gz5xL/18/

Я обнаружил, что немного ниже истинного центра лучше всего выглядит текст; это можно отрегулировать там, где 55%есть (чем выше высота, тем ниже планка). Внешний вид линии можно изменить там, где она border-bottomесть.

HTML:

<div class="title">
  <div class="title-row">
    <div class="bar-container">
      <div class="bar"></div>
    </div>
    <div class="text">
      Title
    </div>
    <div class="bar-container">
      <div class="bar"></div>
    </div>
  </div>
</div>

CSS:

.title{
  display: table;
  width: 100%
  background: linear-gradient(to right, white, lightgray);
}
.title-row{
  display: table-row;
}
.bar-container {
  display: table-cell;
  position: relative;
  width: 50%;
}
.bar {
  position: absolute;
  width: 100%;
  top: 55%;
  border-bottom: 1px solid black;
}
.text {
  display: table-cell;
  padding-left: 5px;
  padding-right: 5px;
  font-size: 36px;
}

2

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

Некоторые настройки являются жесткими, но только для демонстрации. Я думаю, что это решение должно работать практически в любом современном браузере. Просто удалите / настройте фиксированные настройки для класса .flex-parent, настройте цвета / текст / материал и (я надеюсь) вы будете так же счастливы, как и я, с этим подходом.

HTML:

.flex-parent {
  display: flex;
  width: 300px;
  height: 20px;
  align-items: center;
}

.flex-child-edge {
  flex-grow: 2;
  height: 1px;
  background-color: #000;
  border: 1px #000 solid;
}
.flex-child-text {
  flex-basis: auto;
  flex-grow: 0;
  margin: 0px 5px 0px 5px;
  text-align: center;
}
<div class="flex-parent">
  <div class="flex-child-edge"></div>
  <div class="flex-child-text">I found this simpler!</div>
  <div class="flex-child-edge"></div>
</div>

Я также сохранил свое решение здесь: https://jsfiddle.net/Wellspring/wupj1y1a/1/


1

На всякий случай, если кто-то захочет, IMHO, лучшее решение с использованием CSS - это flexbox.

Вот пример:

.kw-dvp-HorizonalButton {
    color: #0078d7;
    display:flex;
    flex-wrap:nowrap;
    align-items:center;
}
.kw-dvp-HorizonalButton:before, .kw-dvp-HorizonalButton:after {
    background-color: #0078d7;
    content: "";
    display: inline-block;
    float:left;
    height:1px;
}
.kw-dvp-HorizonalButton:before {
    order:1;
    flex-grow:1;
    margin-right:8px;
}
.kw-dvp-HorizonalButton:after {
    order: 3;
    flex-grow: 1;
    margin-left: 8px;
}
.kw-dvp-HorizonalButton * {
    order: 2;
}
    <div class="kw-dvp-HorizonalButton">
        <span>hello</span>
    </div>

Это всегда должно приводить к идеально центрированному выровненному контенту с линией слева и справа, с легким контролем поля между строкой и вашим контентом.

Он создает линейный элемент до и после вашего верхнего элемента управления и устанавливает их в порядке 1,3 в вашем флекс-контейнере, в то время как ваш контент устанавливается в порядке 2 (переходите в середину). если задать значение «до» или «после» 1, они будут в равной степени использовать самое свободное место, сохраняя при этом центрирование вашего контента.

Надеюсь это поможет!


0

Я не слишком уверен, но вы можете попробовать использовать горизонтальное правило и поместить текст выше его верхнего поля. Вам понадобится фиксированная ширина тега абзаца и фон. Это немного странно, и я не знаю, сработает ли это во всех браузерах, и вам нужно установить отрицательное поле в зависимости от размера шрифта. Работает на Chrome, хотя.

<style>   
 p{ margin-top:-20px; background:#fff; width:20px;}
</style>

<hr><p>def</p>

0

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

HTML

        <div style="text-align:center"> 
            <h1>
                <span >S</span>
            </h1> 
        </div> 

        <div style="text-align:center"> 
            <h1>
                <span >Long text</span>
            </h1> 
        </div> 

CSS

      h1 {
            display: inline-block;
            position: relative;
            text-align: center;
        }

        h1 span {
            background: #fff;
            padding: 0 10px;
            position: relative;
            z-index: 1;
        }

        h1:before {
            background: #ddd;
            content: "";
            height: 1px;
            position: absolute;
            top: 50%;
            width: calc(100% + 50px);//Support in modern browsers
            left: -25px;
        }

        h1:before {
            left: ;
        }

Результат: https://jsfiddle.net/fasilkk/vowqfnb9/


0

Для меня это решение прекрасно работает ...

HTML

<h2 class="strikethough"><span>Testing Text</span></h2>

CSS

.strikethough {
 width:100%; 
 text-align:left; 
 border-bottom: 1px solid #bcbcbc; 
 overflow: inherit;
 margin:0px 0 30px;
 font-size: 16px;
 color:#757575;
 }
.strikethough span {
 background:#fff; 
 padding:0 20px 0px 0px;
 position: relative;
 top: 10px;
}

0

Люди, которые используют Bootstrap 4, могут достичь с помощью этого метода. классы, упомянутые в коде HTML, взяты из Bootstrap 4.

h1 {
    position: relative;
    flex-grow: 1;
    margin: 0;
}

h1:before {
   content: "";
   display: block;
   border-top: solid 2px blue;
   width: 100%;
   height: 1px;
   position: absolute;
   top: 50%;
   z-index: 1;
 }
 h1 span {
   background: #fff;
   left: 12%;
   padding: 0 15px;
   position: relative;
   z-index: 5;
 }

И напишите свой HTML, как это

<div class="d-flex flex-row align-items-center">
  <h1><span> Title </span> </h1>
</div>

0

Горизонтальная и вертикальная линия со словами в середине

.box{
    background-image: url("https://i.stack.imgur.com/N39wV.jpg");
    width: 350px;
    padding: 10px;
}

/*begin first box*/
.first{
    width: 300px;
    height: 100px;
    margin: 10px;
    border-width: 0 2px 0 2px;
    border-color: red;
    border-style: solid;
    position: relative;
}

.first span {
    position: absolute;
    display: flex;
    right: 0;
    left: 0;
    align-items: center;
}
.first .foo{
    top: -8px;
}
.first .bar{
    bottom: -8.5px;
}
.first span:before{
    margin-right: 15px;
}
.first span:after {
    margin-left: 15px;
}
.first span:before , .first span:after {
    content: ' ';
    height: 2px;
    background: red;
    display: block;
    width: 50%;
}


/*begin second box*/
.second{
    width: 300px;
    height: 100px;
    margin: 10px;
    border-width: 2px 0 2px 0;
    border-color: red;
    border-style: solid;
    position: relative;
}

.second span {
    position: absolute;
    top: 0;
    bottom: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
}
.second .foo{
    left: -15px;
}
.second .bar{
    right: -15.5px;
}
.second span:before{
    margin-bottom: 15px;
}
.second span:after {
    margin-top: 15px;
}
.second span:before , .second span:after {
    content: ' ';
    width: 2px;
    background: red;
    display: block;
    height: 50%;
}
<div class="box">
    <div class="first">
        <span class="foo">FOO</span>
        <span class="bar">BAR</span>
    </div>

   <br>

    <div class="second">
        <span class="foo">FOO</span>
        <span class="bar">BAR</span>
    </div>
</div>

Ответ также дан в https://stackoverflow.com/a/57279326/6569224


-1
  • Создано маленькое изображение 1x18 с одной цветной точкой # e0e0e0
  • Преобразовал изображение в код base64

Результат:

body
{
  background: #c0c0c0;
}

#block_with_line
{
  width: 100%;
  position: relative;
  height: 18px;
  background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAASAQMAAACgmSb/AAAAAXNSR0IB2cksfwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAZQTFRFAAAA4ODg8vF4+wAAAAJ0Uk5TAP9bkSK1AAAAEElEQVR4nGNgQAMN6AIMDAAJpACBAQttyAAAAABJRU5ErkJggg==');
}

#block_with_line span
{
  background: #e4e4e4;
  width: 150px;
  display: block;
  margin: 0 auto;
  position: absolute;
  left: 50%;
  margin-left: -75px;
  text-align: center
}
<body>
  <div id="block_with_line">
    <span>text</span>
  </div>
</body>

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.