Reputation: 2470
I'm rendering a list of icon-links, using v-for and right after it adding a few other icon-list items.
Why am I getting space with the items attached at the end? Obviously, I checked my css and it has no rules for any margin, padding, etc.
As you can see, without v-for, every item in the list have this space around it.
<span style="padding-top:10px;display: block;">
<a v-for="s in social.sites" :href="s.userPageUrl" target="_blank">
<img :src="s.iconUrl" style="display: inline-block; margin-bottom: 4px;" nosend="1" :width="social.wh" :height="social.wh">
</a>
<a :href="contacts.skype"><img src="imgurl" style="display: inline-block; margin-bottom: 4px;" nosend="1" :width="social.wh" :height="social.wh"></a>
<a :href="contacts.skype"><img src="imgurl" style="display: inline-block; margin-bottom: 4px;" nosend="1" :width="social.wh" :height="social.wh"></a>
<a :href="contacts.skype"><img src="imgurl" style="display: inline-block; margin-bottom: 4px;" nosend="1" :width="social.wh" :height="social.wh"></a>
</span>
new Vue({
el: "#app",
data: {
demoL: "https://i.imgur.com/Nk3PKVZ.png",
social: {
sites: [
{
iconUrl: "https://i.imgur.com/Nk3PKVZ.png",
userPageUrl: "sdf"
},
{
iconUrl: "https://i.imgur.com/Nk3PKVZ.png",
userPageUrl: "sdf"
},
{
iconUrl: "https://i.imgur.com/Nk3PKVZ.png",
userPageUrl: "sdf"
}
]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<span style="display: block;">
<a v-for="s in social.sites" :href="s.userPageUrl">
<img :src="s.iconUrl" style="display: inline-block; margin-bottom: 4px;" nosend="1" width="20" height="20">
</a>
<a href=""><img :src="demoL" style="display: inline-block; margin-bottom: 4px;" nosend="1" width="20" height="20"></a>
<a href=""><img :src="demoL" style="display: inline-block; margin-bottom: 4px;" nosend="1" width="20" height="20"></a>
<a href=""><img :src="demoL" style="display: inline-block; margin-bottom: 4px;" nosend="1" width="20" height="20"></a>
</span>
</div>
Upvotes: 1
Views: 119
Reputation: 90013
The classic (block level) solution is to give the children:
a {
display: inline-block;
float: left;
}
and apply overflow: hidden;
to parent (extends its background to include all floating children).
The modern solution, applicable to your case, is to give the parent display:flex
(if there's any case in which you want the children to wrap, also add flex-wrap:wrap
to it).
Why?
By default, anchors have display:inline
. Which means they are displayed as letters in text, as far as you're concerned. When you write l e t t e r s
you don't expect browsers to remove the spaces between your letters.
Why do you expect it when the letters are... anchors?
As an alternative, you can simply remove any spaces or tabs between the end of an <a>
tag and the beginning of the next.
The above is a bit of a simplification, but it's enough to understand the cause.
Here's why it's a simplification: any display:inline
element can contain other elements and spaces, which will determine how the inline content will wrap, according to text-wrap
property. Or, its elements can have a display
value other than inline
which will disrupt the inline behaviour of the parent as well. So a better association would be with words in text, not with letters.
For the intents and purposes of your question, either making the children inline-block
s and floating them or giving the parent a display
value of flex
or inline-flex
will work. Alternatively, you could effectively remove any space, tab or new line character in between your >
and <
.
A handy way of removing the spaces (while keeping your code in a readable position) is to place the ending character of your closing tag on the next line:
new Vue({
el: "#app",
data: {
demoL: "https://i.imgur.com/Nk3PKVZ.png",
social: {
sites: [
{
iconUrl: "https://i.imgur.com/Nk3PKVZ.png",
userPageUrl: "sdf"
},
{
iconUrl: "https://i.imgur.com/Nk3PKVZ.png",
userPageUrl: "sdf"
},
{
iconUrl: "https://i.imgur.com/Nk3PKVZ.png",
userPageUrl: "sdf"
}
]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<span style="display: block;">
<a v-for="s in social.sites" :href="s.userPageUrl">
<img :src="s.iconUrl" style="display: inline-block; margin-bottom: 4px;" nosend="1" width="20" height="20">
</a
><a href=""><img :src="demoL" style="display: inline-block; margin-bottom: 4px;" nosend="1" width="20" height="20"></a
><a href=""><img :src="demoL" style="display: inline-block; margin-bottom: 4px;" nosend="1" width="20" height="20"></a
><a href=""><img :src="demoL" style="display: inline-block; margin-bottom: 4px;" nosend="1" width="20" height="20"></a></span></div>
However, this technique is not recommended in production environments, especially when more than one developer is working on the same codebase, as it's too fragile and errors would be hard to spot.
Controlling their display behavior via CSS is the proper way to go.
Flexbox solution:
new Vue({
el: "#app",
data: {
demoL: "https://i.imgur.com/Nk3PKVZ.png",
social: {
sites: [
{
iconUrl: "https://i.imgur.com/Nk3PKVZ.png",
userPageUrl: "sdf"
},
{
iconUrl: "https://i.imgur.com/Nk3PKVZ.png",
userPageUrl: "sdf"
},
{
iconUrl: "https://i.imgur.com/Nk3PKVZ.png",
userPageUrl: "sdf"
}
]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<span style="display:flex;">
<a v-for="s in social.sites" :href="s.userPageUrl">
<img :src="s.iconUrl" style="display: inline-block; margin-bottom: 4px;" nosend="1" width="20" height="20">
</a>
<a href=""><img :src="demoL" style="display: inline-block; margin-bottom: 4px;" nosend="1" width="20" height="20"></a>
<a href=""><img :src="demoL" style="display: inline-block; margin-bottom: 4px;" nosend="1" width="20" height="20"></a>
<a href=""><img :src="demoL" style="display: inline-block; margin-bottom: 4px;" nosend="1" width="20" height="20"></a></span></div>
Inline blocks solution:
new Vue({
el: "#app",
data: {
demoL: "https://i.imgur.com/Nk3PKVZ.png",
social: {
sites: [
{
iconUrl: "https://i.imgur.com/Nk3PKVZ.png",
userPageUrl: "sdf"
},
{
iconUrl: "https://i.imgur.com/Nk3PKVZ.png",
userPageUrl: "sdf"
},
{
iconUrl: "https://i.imgur.com/Nk3PKVZ.png",
userPageUrl: "sdf"
}
]
}
}
})
#app > span {
overflow: hidden;
}
#app > span > a {
display: inline-block;
float: left;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<span style="display:block;">
<a v-for="s in social.sites" :href="s.userPageUrl">
<img :src="s.iconUrl" style="display: inline-block; margin-bottom: 4px;" nosend="1" width="20" height="20">
</a>
<a href=""><img :src="demoL" style="display: inline-block; margin-bottom: 4px;" nosend="1" width="20" height="20"></a>
<a href=""><img :src="demoL" style="display: inline-block; margin-bottom: 4px;" nosend="1" width="20" height="20"></a>
<a href=""><img :src="demoL" style="display: inline-block; margin-bottom: 4px;" nosend="1" width="20" height="20"></a></span></div>
Upvotes: 3