Each city has a population. Each population can "work" a tile within a 3 tile radius of the city (city, city+1, city+2, city+3). "Working a tile" means in the city view, there is a citizen residing on that tile, and the city will get the yields of that worked tile (food, production, energy).
Special resources just have to be within your borders, so that your workers can build improvements on them.
Each city has a food storage. Each turn, food income to the city (from worked tiles, from buildings, from trade routes) gets dumped into that storage. When that storage is full, the city grows by 1 population. Then the storage is cleared and overflow put back in, and then it needs to accumulate slightly more food this time to grow the city for another population. The higher the city's existing population is, the more food you need to accumulate to grow the next population.
With virtues and buildings, you can make a city retain a percentage of food in the storage when it grows. There are also virtues that increase a city's growth rate.
A city's borders need culture yields to grow. Border growth work the same way as population growth, the difference being that it uses culture yields instead of food yields. You can also buy border (go into the city screen for that) with energy, although that is not recommended at early game.