178

I have several same HTML elements going one after another:

<span>1</span>
<span>2</span>
<span>3</span>

I'm looking for the best way of adding space between the elements using CSS only

[no space]  [1]  [space 10px]  [2]  [space 10px]  [3]  [no space]

Additionally:

  • Please write down browser compatibility of your receipts

I don't want to use any additional HTML markup like

<span></span>  <span></span>  <span class="last_span"></span>

I don't want to use tables.

I want the first and last span to be targeted automatically by CSS.

I don't want to use JavaScript.

Optional requirement: last span can be not last child of the parent tag, but it will be the last span of the parent tag. Spans do not have any other tags between them.

7
  • Maybe you should consider using a table. Depends on what data goes into the text Commented Nov 18, 2011 at 15:47
  • Is the number of spans variable? Commented Nov 18, 2011 at 15:56
  • @Truth last resort should be tables. Commented Nov 18, 2011 at 15:59
  • The span elements are generated by the web service I don't have access to. So I can't change the markup. However, I can fully use CSS Commented Nov 18, 2011 at 16:01
  • With questions like this, you should always specify the browser support you require. "I need IE7 support" will receive completely different answers to "I'm only using Chrome". Commented Nov 18, 2011 at 16:16

13 Answers 13

366

A good way to do it is this:

span + span {
    margin-left: 10px;
}

Every span preceded by a span (so, every span except the first) will have margin-left: 10px.

Here's a more detailed answer to a similar question: Separators between elements without hacks

Sign up to request clarification or add additional context in comments.

5 Comments

This is a nice solution, though if your container will span to multiple lines it fails.
It also works with classes, like this: .sidebar-img + .sidebar-text { margin-left: 40px; }
How do you handle when the items wrap to the next line?
@thdoan: It depends on your layout, etc. You can try something like this.
I prefer reddtoric's solution using grid and grid-gap.
53

Add these rules to the parent container:

display: grid
grid-auto-flow: column
grid-column-gap: 10px

A good reference: CSS Reference - A free visual guide to CSS

Browser compatibility: Browser Support for CSS Grid Layout

3 Comments

grid-auto-columns="max-content" may also be useful. It will make the grid item's size match the content. Also, browser compatibility shouldn't be an issue anymore: caniuse.com/#feat=css-grid
This should be the accepted answer. I know comments are not for thanks, i was only making use of the 'flex' display until now, and this 'grid' thing makes it all so easy from the parent container itself! To not leave it entirely useless, would add the following reference that helps a lot for anyone looking to learn more: css-tricks.com/snippets/css/complete-guide-grid
This is the best answer as of 2024 and it's easy to assume how to change it for rows instead of columns for whoever fell here from Google looking for rows like myself
49

Just use margin or padding.

In your specific case, you could use margin:0 10px only on the second <span>.

Here's a nice CSS 3 solution (JSFiddle):

span {
    margin: 0 10px;
}

span:first-of-type {
    margin-left: 0;
}

span:last-of-type {
    margin-right: 0;
}

Advanced element selection using selectors like :nth-child(), :last-child, :first-of-type, etc. is supported since Internet Explorer 9.

4 Comments

You have a great answer, Simone, but could you please solve the question without specifying the last span manually? This should be the CSS's job
this is an unneded hack, that's the "word-spacing" property for: w3schools.com/cssref/pr_text_word-spacing.asp check Ben's answer
the OP wanted space between spans, so it's ok to give a solution for inline elements, the margin/padding/first/last properties are not needed here and only adds complexity
Actually, the OP said he'll be using spans and divs (which are block elements). Your solution is valid anyway if you define divs as inline elements...
24

You can style elements with excluding the first one, just in one line of code:

span ~ span {
    padding-left: 10px;
}

There isn't a need to change any classes.

2 Comments

This one works perfekt. span + span didnt work but span ~ span works like a charm! Thanks
In my case, I have several spans, some of which may not contain the class "Showing", so what I need is span.Showing ~ span.Showing instead of span.Showing + span.Showing. ~ is the general sibling selector, where one doesn't need to directly follow another.
12

You can take advantage of the fact that span is an inline element:

span{
     word-spacing: 10px;
}

However, this solution will break if you have more than one word of text in your span.

Comments

9
span:not(:last-child) {
    margin-right: 10px;
}

1 Comment

An explanation would be in order.
5

You can write like this:

span{
    margin-left: 10px;
}

span:first-child{
    margin-left: 0;
}

Comments

5

If you want to align various items and you like to have the same margin around all sides, you can use the following. Each element within container, regardless of type, will receive the same surrounding margin.

Enter image description here

.container {
  display: flex;
}
.container > * {
  margin: 5px;
}

If you wish to align items in a row, but have the first element touch the leftmost edge of container, and have all other elements be equally spaced, you can use this:

Enter image description here

.container {
  display: flex;
}
.container > :first-child {
  margin-right: 5px;
}
.container > *:not(:first-child) {
  margin: 5px;
}

1 Comment

While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value.
3

You should wrap your elements inside a container, use new CSS 3 features like CSS grid, a free course, and then use grid-gap:value that was created for your specific problem.

span{
  border: 1px solid red;
}
.inRow{
  display: grid;
  grid-template-columns: repeat(auto-fill, auto);
  grid-gap: 10px /* This adds space between elements, only works on grid items */
}
.inColumn{
  display: grid;
  grid-template-rows: repeat(auto-fill, auto);
  grid-gap: 15px;
}
<div class="inrow">
  <span>1</span>
  <span>2</span>
  <span>3</span>
</div>
<div class="inColumn">
  <span>4</span>
  <span>5</span>
  <span>6</span>
</div>

1 Comment

I was looking to add space between elements of a div class using css style. I used your example to build my code for that. Worked like a charm. Thank you!
2

<span> is an inline element, so you can’t make spacing on them without making it block level.

Try this:

Horizontal

span{
    margin-right: 10px;
    float: left;
}

Vertical

span{
    margin-bottom: 10px;
}

It is compatible with all browsers.

Comments

2

Or, instead of setting margin and then overriding it, you can just set it properly right away with the following combination:

span:not(:first-of-type) {
    margin-left:  5px;
}

span:not(:last-of-type) {
    margin-right: 5px;
}

4 Comments

Good answer, the restriction is the browser support of :first-of-type and :last-of-type CSS selectors.
...also check for not expression browser support
@Dan it's actually great, all several last-years browsers are covered. But I must admit, that yzoja's solution is even smarter :)
This solution is superior in the specific case that you are going to also include borders between elements as separators (so like a UL in a nav, for example), as it will properly place the border in the middle of the spacing.
0
span.middle {
    margin: 0 10px 0 10px; /* top right bottom left */
}
<span>text</span> <span class="middle">text</span> <span>text</span>

Comments

0
/* Horizontal space */
.space-8-x > * + * {
    margin-left: 8px;
}
/* Vertical space */
.space-8-y > * + * {
    margin-top: 8px;
}
<div class="space-8-x">
    <span>1</span>
    <span>2</span>
    <span>3</span>
</div>

<div class="space-8-y">
    <div>1</div>
    <div>2</div>
    <div>3</div>
</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.