问题
I have a some basic button styles where on :hover
I add the letter-spacing
property:
.btn {
display: inline-block;
text-align: center;
background-color: transparent;
border: 1px solid transparent;
padding: 0.375rem 0.75rem;
font-size: 1rem;
border-radius: 0.25rem;
cursor: pointer;
transition: all 0.2s ease;
}
.btn-primary {
background-color: #8065F1;
color: #FFFFFF;
}
.btn-large {
border-radius: 32px;
box-shadow: 0 2px 80px 0 rgba(74, 74, 74, 0.23);
padding: 0.25rem 3rem;
font-size: 1.5rem;
text-transform: uppercase;
}
.btn:hover {
letter-spacing: 4px;
}
<button type="button" class="btn btn-primary btn-large">Lorem</button>
Is there a way that width
doesn't expand? Like adding min/max-width
? However the problem is that button
elements can contain different string length:
.btn {
display: inline-block;
text-align: center;
background-color: transparent;
border: 1px solid transparent;
padding: 0.375rem 0.75rem;
box-shadow: 0 2px 80px 0 rgba($grey, 0.23);
font-size: 1rem;
border-radius: 0.25rem;
cursor: pointer;
transition: all 0.2s ease;
}
.btn-primary {
background-color: #8065F1;
color: #FFFFFF;
}
.btn-large {
border-radius: 32px;
-webkit-box-shadow: 0 2px 80px 0 rgba(74, 74, 74, 0.23);
box-shadow: 0 2px 80px 0 rgba(74, 74, 74, 0.23);
padding: 0.25rem 3rem;
font-size: 1.5rem;
text-transform: uppercase;
min-width: 240px;
}
.btn:hover {
letter-spacing: 4px;
}
<p>I need this "effect" (I added some min-width):</p>
<button type="button" class="btn btn-primary btn-large">Lorem</button>
<p>However it won't work for larger strings</p>
<button type="button" class="btn btn-primary btn-large">Lorem Ipsum</button><br><br>
<button type="button" class="btn btn-primary btn-large">Lorem Ipsum Dolor</button>
I know I can use JS and append the elements fixed width to it, however I'm looking for a CSS solution - if there is one?
回答1:
On idea to approximate this is to duplicate the text considering a hidden one that has already the letter-spacing
and another one on the top that you animate to fill the space already defined by the hidden text:
Here is an idea by making the text color the same as background:
.btn {
display: inline-block;
text-align: center;
background-color: transparent;
border: 1px solid transparent;
padding: 0.375rem 0.75rem;
font-size: 1rem;
border-radius: 0.25rem;
cursor: pointer;
transition: all 0.2s ease;
margin-bottom:10px;
}
.btn-primary {
background-color: #8065F1;
color: #FFFFFF;
}
.btn-large {
border-radius: 32px;
box-shadow: 0 2px 80px 0 rgba(74, 74, 74, 0.23);
padding: 0.25rem 3rem;
font-size: 1.5rem;
text-transform: uppercase;
}
.btn::before {
content:attr(data-text);
position:absolute;
left:0;
right:0;
text-align:center;
letter-spacing: initial;
color:#fff;
transition: all 0.2s ease;
}
.btn {
letter-spacing: 4px;
color:#8065F1;
position:relative;
}
.btn:hover::before {
letter-spacing: 4px;
}
<div><button type="button" class="btn btn-primary btn-large" data-text="Lorem">Lorem</button></div>
<div><button type="button" class="btn btn-primary btn-large" data-text="Lorem Ipsum">Lorem Ipsum</button></div>
<div><button type="button" class="btn btn-primary btn-large" data-text="Lorem Ipsum Dolor">Lorem Ipsum Dolor</button></div>
Another one using opacity and both pseudo element in case the background is not a solid color:
.btn {
display: inline-block;
text-align: center;
background-color: transparent;
border: 1px solid transparent;
padding: 0.375rem 0.75rem;
font-size: 1rem;
border-radius: 0.25rem;
cursor: pointer;
transition: all 0.2s ease;
margin-bottom:10px;
}
.btn-primary {
background: linear-gradient(#8065F1,purple);
color: #FFFFFF;
}
.btn-large {
border-radius: 32px;
box-shadow: 0 2px 80px 0 rgba(74, 74, 74, 0.23);
padding: 0.25rem 3rem;
font-size: 1.5rem;
text-transform: uppercase;
}
.btn {
position:relative;
font-size:0;
}
.btn::before {
content:attr(data-text);
position:absolute;
left:0;
right:0;
text-align:center;
letter-spacing: initial;
font-size: 1.5rem;
transition: all 0.2s ease;
}
.btn::after {
content:attr(data-text);
letter-spacing: 4px;
opacity:0;
font-size: 1.5rem;
}
.btn:hover::before {
letter-spacing: 4px;
}
<div><button type="button" class="btn btn-primary btn-large" data-text="Lorem">Lorem</button></div>
<div><button type="button" class="btn btn-primary btn-large" data-text="Lorem Ipsum">Lorem Ipsum</button></div>
<div><button type="button" class="btn btn-primary btn-large" data-text="Lorem Ipsum Dolor">Lorem Ipsum Dolor</button></div>
回答2:
How about turning off box-sizing, then using a percentage for your padding? It should work well no matter what the size of your contents is, but my numbers are probably wrong so you'll need to adjust the numbers to make it accurate.
.wrapper{
display:inline-block;
}
button{
box-sizing: content-box;
padding: 0 10.4%;
border: none;
width: 100%;
font-size:13px;
}
button:hover{
letter-spacing:0.1em;
padding:0;
}
.outer-wrapper{
}
<div class="outer-wrapper">
<div class="wrapper">
<button class='button'>Small Text</button>
</div>
</div>
<div class="outer-wrapper">
<div class="wrapper">
<button class='button'>Much much bigger text</button>
</div>
</div>
<div class="outer-wrapper">
<div class="wrapper">
<button class='button'>Small TextSmall TextSmall TextSmall TextSmall Text</button>
</div>
</div>
Edit: Well, it's...more or less working, except that it turns out to be impossible. No matter how finely I tune it, I'm getting problems because of differences in browser rendering of sub-pixels. (The browser apparently rounds rem differently than it does %, which means this is going to be impossible to do with pure CSS.)
来源:https://stackoverflow.com/questions/54440571/keep-width-when-using-letter-spacing-on-hover