-1

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.

MuiButton component with left icon MuiButton component with right icon

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?

Jagadeeswar
  • 311
  • 2
  • 5
  • 14
  • Does this answer your question? [How to style SVG with external CSS?](https://stackoverflow.com/questions/18434094/how-to-style-svg-with-external-css) – Mohammed Alwedaei Feb 24 '22 at 09:49
  • No @MohammedAlwedaei – Jagadeeswar Feb 24 '22 at 09:59
  • _"I am be able to set based on :first-child psuedo but I want to set only for icon component."_ - I can't tell what you are trying to say / ask here. – CBroe Feb 24 '22 at 10:17
  • Something in your logic must _put_ that item either to the left, or the right. So why don't you add a class or something at that same time, and then apply the according formatting via that? – CBroe Feb 24 '22 at 12:14
  • I am trying to acheive customization for Mui Toggle button using CSS. Can go for custom styled component but I want to acheive it with the theming. Contents inside button is not in my control. If there is Icon as first child or last child of the button, want to add spacing. – Jagadeeswar Feb 24 '22 at 12:17

2 Answers2

0

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>
Mohammed Alwedaei
  • 601
  • 1
  • 7
  • 14
0

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 class="icon icon-inline" 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 class="icon icon-inline" 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).

herrstrietzel
  • 11,541
  • 2
  • 12
  • 34