Técnica CSS para uma linha horizontal com palavras no meio


286

Estou tentando fazer uma regra horizontal com algum texto no meio. Por exemplo:

----------------------------------- meu título aqui ------------ -----------------

Existe uma maneira de fazer isso em CSS? Sem todos os traços "-" obviamente.


Isso é para dentro de uma formtag?
Trintadot 06/03

nesse caso, como trinta pontos assinalou em resposta à minha resposta, você pode procurar os elementos fieldsete #legend
Stephan Muller


Para uma solução ao longo de um fundo transparente , consulte Linha de antes e depois do texto centrado sobre o fundo transparente
web-tiki

Respostas:


404

É assim que eu faria: a linha é criada definindo a border-bottomno contendo e h2depois dando a h2um menor line-height. O texto é então colocado em um fundo aninhado spancom um fundo não transparente.

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>

Testei apenas no Chrome, mas não há motivo para que ele não funcione em outros navegadores.

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


3
Esta é a minha solução favorita. Também funciona no OSX e alguns outros não. Se você usar esta solução, lembre-se de definir o plano de fundo do período com a mesma cor do plano de fundo da sua página, será especialmente óbvio o que quero dizer se o plano de fundo não for branco. ;)
Drlazer

1
alguma maneira de fazer isso cerca de um quarto do caminho?
Troy Cosentino

1
Obtenha o texto recuado da esquerda usando "alinhamento de texto: esquerda; recuo de texto: 40 px;" no estilo h2.
Matt__C

14
Isso não é flexível, pois você corrige a cor do plano de fundo do texto como branco.
Chao

2
@NateBarbettini A menos que a linha que você está tentando fazer e o texto precise ter fundos transparentes para as outras coisas por trás dela.
Coburn

265

Depois de tentar soluções diferentes, eu vim com uma válida para diferentes larguras de texto, qualquer plano de fundo possível e sem adicionar marcações extras.

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>

Eu testei no IE8, IE9, Firefox e Chrome. Você pode ver aqui http://jsfiddle.net/Puigcerber/vLwDf/1/


2
Eu gosto mais deste também. Para obter um estilo em que o texto é recuado da esquerda em vez de centralizado, use esta alteração: h1 { overflow: hidden; `alinhamento de texto: esquerda; `recuo do texto: 40 px; `}
Matt__C 27/03

9
Esta é realmente uma boa solução; particularmente porque funciona com qualquer plano de fundo e não requer uma largura definida no elemento de cabeçalho.
29413 Luke

2
Isso é ótimo. Adaptei um pouco o seu código para alinhar o texto à esquerda e tornar o :afterelemento a largura do bloco. Estou curioso: qual é exatamente o papel margin-right: -50%? Quando eu estava mexendo no código, perder essa propriedade faria com que a decoração fosse quebrada em outra linha. E mesmo quando :afteré atribuída uma largura de 100%, ainda preciso da margem negativa à direita de 50% para ajustá-la. Por quê?
BeetleTheNeato

Pelo que entendi, adicionar margens negativas em ambos os lados puxa o elemento nas duas direções, e é por isso que fica centrado.
precisa saber é o seguinte

2
Uma das coisas que eu amo nessa solução é que ela funciona em situações nas quais você não sabe qual é a cor do plano de fundo. Facilmente a melhor solução até agora para este problema.
JoeMoe1984

54

Ok, este é mais complicado, mas funciona em tudo, menos no 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; 
}

Os elementos: before e: after são posicionados absolutamente para que possamos puxar um para a esquerda e outro para a direita. Além disso, a largura (40% neste caso) é muito dependente da largura do texto dentro .. tem que pensar em uma solução para isso. Pelo menos otop: 1.2em garante que as linhas fiquem mais ou menos no centro do texto, mesmo se você tiver um tamanho de fonte diferente.

Parece funcionar bem: http://jsfiddle.net/tUGrf/3/


3
Isso é inteligente, mas espero que o OP não queira isso dentro de uma formtag. Se ele faz, como eu tenho certeza que você sabe, ele poderia simplesmente usar fieldsete legend.
thirtydot

1
Heh, você está certo sobre isso. É bem possível fazer isso de qualquer maneira, se isso não funcionar .. não é semanticamente correto, mas é melhor do que ter que recorrer ao javascript para algo como esta imo.
Stephan Muller

8
A melhor solução que eu encontrei que funciona bem quando a tela é residiu e sem definir a cor de fundo do texto é jsfiddle.net/vLwDf/268
Xavier John

Sim @ xavier-john, essa é a minha resposta ;)
Puigcerber

43

Método mais curto e melhor:

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


4
Você deve adicionar uma descrição do que seu código faz, a menos que queira que ele seja excluído.
Inf3rno 12/05

No meu caso, a linha parecia um pouco grossa, então eu a cortei atribuindo uma família de fontes diferente: font-family: monospace;funcionou bem.
21817 Mikhail Vasin

38

Aqui está a solução baseada em Flex.

Um cabeçalho com uma linha horizontal central aos lados

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/


Como obter preenchimento?
22417 Sylar

rápido e sujo, você pode adicionar um & nbsp;
Chrismarx #

1
Eu uso outro elemento: <h1><span>Today</span></h1>com uma margem / preenchimento no vão.
Jesse Buitenhuis

19

para o navegador mais recente (hoje em dia), display:flexandd pseudo-elements facilita o desenho. border-style, box-shadowe até backgroundajuda também para a maquiagem. demonstração abaixo

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>


Obrigado por isso, muito liso!
Jimmy Obonyo Abor

Perfeito, apenas a solução que funcionou para mim quando o fundo foi uma imagem
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; 
}

Dê um preenchimento ao espaço para deixar mais espaço entre o texto e a linha.

Exemplo: http://jsfiddle.net/tUGrf/


1
Bom, o único problema é que você precisa definir o plano de fundo para branco e não pode defini-lo como transparente.
Marnix

nesse caso, você terá que trabalhar com duas linhas, uma de cada lado. Isso vai ser difícil de alcançar em uma maneira limpa ..
Stephan Muller

A minha abordagem favorita até agora, mas infelizmente ele não funciona em clientes de e-mail por algum motivo (Gmail móvel e web)
reedwolf

9

Estive procurando algumas soluções para essa decoração simples e encontrei algumas, algumas estranhas, algumas até com JS para calcular a altura da fonte e bla, bla, bla, então li o um neste post e ler um comentário de trintadot falando sobre fieldsetelegend e eu pensei que era ele.

Estou substituindo esses estilos de 2 elementos, acho que você pode copiar os padrões W3C para eles e incluí-los em sua .middle-line-textclasse (ou como você quiser chamar), mas foi o que fiz:

<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>

Aqui está o violino: http://jsfiddle.net/legnaleama/3t7wjpa2/

Eu brinquei com os estilos de borda e também funciona no Android;) (Testado no kitkat 4.XX)

EDITAR:

Seguindo a ideia de Bekerov Artur, que também é uma boa opção, alterei a imagem .png base64 para criar o traçado com um .SVG, para que você possa renderizar em qualquer resolução e também alterar a cor do elemento sem nenhum outro software envolvido :)

/* 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

Solução para IE8 e mais recente ...

Questões que merecem destaque:

Usando background-color para mascarar uma borda pode não ser a melhor solução. Se você tiver uma cor (ou imagem) complexa (ou desconhecida) do plano de fundo, o mascaramento falhará. Além disso, se você redimensionar o texto, notará que a cor branca do plano de fundo (ou o que você definir) começará a encobrir o texto na linha acima (ou abaixo).

Também não é necessário "estimar" a largura das seções, pois isso torna os estilos muito inflexíveis e quase impossíveis de serem implementados em um site responsivo em que a largura do conteúdo está mudando.

Solução:

( Exibir JSFiddle )

Em vez de "mascarar" uma borda com a background-color, use sua displaypropriedade.

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; }

Redimensione seu texto colocando sua font-sizepropriedade no .groupelemento

Limitações:

  • Nenhum texto de várias linhas. Apenas linhas únicas.
  • A marcação HTML não é tão elegante
  • topA propriedade no .lineelemento precisa ser metade line-height. Então, se você tem um line-heightdos 1.5em, então o topdeve ser -.75em. Essa é uma limitação, pois não é automatizada e, se você aplicar esses estilos em elementos com diferentes alturas de linha, poderá ser necessário reaplicar seu line-heightestilo.

Para mim, essas limitações superam os "problemas" que observei no início da minha resposta para a maioria das implementações.


Funciona em cromo. Parece semântico e bastante simples. Funciona com inicialização.
Jeff Ancel 15/14

Eu tive que adicionar border-collapse: separado para .group, porque eu estou usando-o no capaz que tem uma configuração diferente. Funciona bem.
Brian MacKay

5

Isso fornece um comprimento fixo para as linhas, mas funciona muito bem. Os comprimentos das linhas são controlados adicionando ou usando '\ 00a0' (espaço unicode).

insira a descrição da imagem aqui

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


2

Se alguém está se perguntando como definir o cabeçalho de modo que apareça com uma distância fixa para o lado esquerdo (e não centralizado como apresentado acima), descobri isso modificando o código do @ 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%;
}

Aqui o 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;
        }

isso vai te ajudar


entre linhas

<h6 class = "background"> ​​<span> <br> NOSSOS SERVIÇOS </span> </h6> este é o código html
Dominic Amal Joe F

Joe, você pode editar sua própria resposta para adicionar o código HTML - muito melhor do que colocá-lo em comentários. Você também deve adicionar uma explicação à resposta.
Mogsdad

Desculpe, Mogsdad, eu esqueci de colocar o código html, é por isso que o coloquei aqui.
Dominic Amal Joe F

2

Eu uso um layout de tabela para preencher os lados dinamicamente e divs de posição absoluta e altura 0 para posicionamento vertical dinâmico:

insira a descrição da imagem aqui

  • sem dimensões codificadas
  • sem imagens
  • sem pseudo-elementos
  • respeita o fundo
  • aparência da barra de controle

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

Eu descobri que um pouco abaixo do verdadeiro centro fica melhor com o texto; isso pode ser ajustado onde 55%estiver (altura mais alta diminui a barra). A aparência da linha pode ser alterada onde oborder-bottom estiver.

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

Para não bater em um cavalo morto, mas eu estava procurando uma solução, acabei aqui e não estava satisfeito com as opções, até porque, por algum motivo, não consegui fazer com que as soluções fornecidas aqui funcionassem bem para mim. (Provavelmente devido a erros da minha parte ...) Mas eu tenho jogado com o flexbox e aqui está algo que eu trabalhei para mim.

Algumas das configurações são cabeadas, mas apenas para fins de demonstração. Eu acho que essa solução deve funcionar em praticamente qualquer navegador moderno. Apenas remova / ajuste as configurações fixas da classe .flex-parent, ajuste cores / texto / outras coisas e (espero) você ficará tão feliz quanto eu com essa abordagem.

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>

Também salvei minha solução aqui: https://jsfiddle.net/Wellspring/wupj1y1a/1/


1

Caso alguém queira, IMHO a melhor solução usando CSS é por um flexbox.

Aqui está um exemplo:

.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>

Isso sempre deve resultar em um conteúdo alinhado perfeitamente centralizado, com uma linha à esquerda e à direita, com uma margem fácil de controlar entre a linha e o seu conteúdo.

Ele cria um elemento de linha antes e depois do seu controle superior e define-os para pedir 1,3 no seu contêiner flex, enquanto define seu conteúdo como ordem 2 (vá no meio). dar um aumento de 1 antes / depois fará com que eles consumam o espaço mais vago da mesma forma, mantendo o conteúdo centralizado.

Espero que isto ajude!


0

Não tenho muita certeza, mas você pode tentar usar uma regra horizontal e empurrar o texto acima da margem superior. Você precisará de uma largura fixa na sua tag de parágrafo e um plano de fundo também. É um pouco hacky e não sei se funcionará em todos os navegadores, e você precisa definir a margem negativa com base no tamanho da fonte. Funciona no chrome embora.

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

<hr><p>def</p>

0

Eu tentei a maioria das maneiras sugeridas, mas termina com alguns problemas, como largura total ou Inadequado para conteúdo dinâmico. Finalmente eu modifiquei um código e funciona perfeitamente. Este código de exemplo desenhará essas linhas antes e depois e é flexível na alteração do conteúdo. Centro alinhado também.

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: ;
        }

Resultado: https://jsfiddle.net/fasilkk/vowqfnb9/


0

Para mim, esta solução funciona perfeitamente bem ...

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

As pessoas que estão usando o Bootstrap 4 podem obter esse método. As classes mencionadas no código HTML são do 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;
 }

E escreva seu HTML assim

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

0

Linha horizontal e vertical com palavras no meio

.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>

Isso também é respondido em https://stackoverflow.com/a/57279326/6569224


-1
  • Imagem pequena criada 1x18 com um único ponto de cor # e0e0e0
  • Transformada a imagem em código base64

Resultado:

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>

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.