I want to set margin-left or margin-right for a Icon component inside toggle button component (svg text inside button) in ReactJS using CSS.
Here I want to add space between the icon and button placeholder. Using :first-child and :last-child seems to apply in both scenarios (when icon is on left I want to apply marginRight, when icon is on right I want to apply marginLeft).
How to achieve it in CSS?
CodePudding user response:
You can add an ID attribute to the SVG tag. And only then you will be able to target the SVG in the CSS.
Side note: Since you are using react I will suggest that you create a component for the button itself so it could be re-usable and keep your code clean.
References that might help you out:
MDN Docs: SVG and CSS
MDN Docs: SVG style
#btn-icon{
/* Indicators to prove it works */
margin: 0 1rem;
fill: red;
/* Indicators to prove it works */
/* Apply your styles here */
/* Apply your styles here */
}
<button>
Placeholder <svg id="btn-icon" focusable="false" aria-hidden="true" viewBox="0 0 24 24">
<path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM8.5 8c.83 0 1.5.67 1.5 1.5S9.33 11 8.5 11 7 10.33 7 9.5 7.67 8 8.5 8zM12 18c-2.28 0-4.22-1.66-5-4h10c-.78 2.34-2.72 4-5 4zm3.5-7c-.83 0-1.5-.67-1.5-1.5S14.67 8 15.5 8s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"></path></svg>
</button>
CodePudding user response:
If your first code example was correct, you don't have any siblings you could select in css.
Since your buttons text content is not a selectable element in css.
Therfore, the svg icon will is both :last-child
and :first-child
.
You might try to add a js to assign classes to your buttons:
let buttons = document.querySelectorAll('button');
buttons.forEach(function(button, i){
let icon = button.querySelector('svg');
let siblingLeft = icon.previousSibling.textContent;
// strip whitespace
siblingLeft = siblingLeft.replace(/\s/g, "")
let btnClass = siblingLeft ? 'icon-right' : 'icon-left';
button.classList.add(btnClass);
});
body{
font-size:3em;
}
button{
font-size:inherit;
background:#fff;
border: 1px solid #ccc;
padding:0.3em;
}
.icon{
display:inline-block;
height:1em;
margin-left:0.3em;
margin-right:0.3em;
position:relative;
bottom:-0.1em;
fill: green;
}
.icon-right svg{
margin-right:0
}
.icon-left svg{
margin-left:0;
fill:red;
}
<button>
<svg focusable="false" aria-hidden="true" viewBox="0 0 24 24">
<path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM8.5 8c.83 0 1.5.67 1.5 1.5S9.33 11 8.5 11 7 10.33 7 9.5 7.67 8 8.5 8zM12 18c-2.28 0-4.22-1.66-5-4h10c-.78 2.34-2.72 4-5 4zm3.5-7c-.83 0-1.5-.67-1.5-1.5S14.67 8 15.5 8s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z" /></svg>Placeholder left
</button>
<button>
Placeholder right<svg focusable="false" aria-hidden="true" viewBox="0 0 24 24">
<path d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM8.5 8c.83 0 1.5.67 1.5 1.5S9.33 11 8.5 11 7 10.33 7 9.5 7.67 8 8.5 8zM12 18c-2.28 0-4.22-1.66-5-4h10c-.78 2.34-2.72 4-5 4zm3.5-7c-.83 0-1.5-.67-1.5-1.5S14.67 8 15.5 8s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z" /></svg>
</button>
But I'm pretty sure your predefined UI css will have some class attributes for different icon types or positionings. (So you should add an accurate code example of your button markup to your question).