def types_of_elements(elements):

    """
    Characterises whether all the elements passed in the input list
    are 'diagonals' (i.e. if elements=['11', '22', '33']),
    'off-diagonals' (i.e. if elements=['12', '21', '42']), or 'both'
    (i.e. if elements=['11', '22', '21', '12']). String descriptions
    of 'diagonals', 'off-diagonals', or 'all' may also be passed.

    Parameters
    ----------
    elements : list of str
        A list of string represntations of the elements of a
        matrix, numbered with indexing starting at 1; i.e ['11',
        '12', '21', '22']. Alternatively, the string description
        can also be passed, in accordance with the specification
        for the elements argument to the
        figures.complex_space_time() method.

    Returns
    -------
    str
        The characterisation of the list of elements as a whole,
        returning either 'diagonals', 'off-diagonals', or 'both'.
    None
        If the value of elements is passed as None.
    """
    # If elements is passed as None
    if elements is None:
        return None

    # If elements pass as 'all', 'off_diagonals', or 'diagonals'
    if isinstance(elements, str):
        assert elements in ['all', 'off-diagonals', 'diagonals']
        if elements == 'all':
            return 'both'
        return elements

    # If elements are passed in list form i.e. ['11', '21', ...]
    if isinstance(elements, list):
        if all([int(element[0]) == int(element[1]) for element in elements]):
            return 'diagonals'
        if all([int(element[0]) != int(element[1]) for element in elements]):
            return 'off-diagonals'
        return 'both'

    raise ValueError('Incorrect format for elements')