For example, consider a Python function that prints a string repeatedly:
def printmeonehundredtimes( str ):
"This prints a passed string into this function one hundred times"
for i in range(100):
This code describes a function to print something one hundred times. Note how the code goes in a pattern where some things are indented more than others.
In some languages, like Python, this has a specific meaning that must be present and correct for the program to function properly - the level of indentation of the code indicates what "level" things are on, and how things are iterated in loops etc. In other programming languages, like C, the indentations and whitespace are not required to have this specific meaning, but people tend to organize their code with indentation in a similar way because it is much easier to read and understand code that is shaped with levels like this than if the entire thing was at the same 'level'.
The "tabs vs spaces" argument is about how to make the levels that push characters to the right - if you use tabs, you can use a single tab per level, or some larger number of spaces (4 spaces are used above, but other numbers may be used occasionally).
If you use tabs, code looks different depending on tab settings on every machine - if tabs are twice as big, then the code gets moved. If you use spaces, you have to hit spaces a lot. If you mix them, then code mixing tabs and spaces looks like a garbled mess if you don't have identical settings for the width of a tab on every machine you look at the code on - and it makes interoperability and copying code really annoying. If a person using tabs has to work with other code using spaces or vice versa it's often super annoying.
I lean towards spaces, with the caveat that most modern developer tools have automatic abilities to transform tabs into the same number of spaces.